summaryrefslogtreecommitdiff
path: root/security/sudo/patches/patch-pwutil.c
blob: 5628882a3b47bc80728bfe5ddf326fe2df662aa1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
$NetBSD: patch-pwutil.c,v 1.2 2012/05/10 09:44:58 martin Exp $

# Tracked upstream at;
#   http://www.gratisoft.us/bugzilla/show_bug.cgi?id=555

# NetBSD uses 64bit time_t, even on 32bit architectures.
# This makes struct passwd require 8 byte-alginement on, for example,
# 32bit sparc. Curiously it all worked out naturally for sparc64 ;-)
# To not add to the magic, let the compiler design proper alignement
# by declaring a helper struct which holds the cache entry header as
# well as struct passwd.

--- pwutil.c.orig	2011-10-21 15:18:38.000000000 +0200
+++ pwutil.c	2012-05-03 10:05:28.000000000 +0200
@@ -84,6 +84,16 @@
 };
 
 /*
+ * To give the compiler a chance to properly align things, we declare this
+ * dummy structure to ease our size/offset calculations.
+ */
+struct cache_and_passwd {
+	struct cache_item cache;
+	struct passwd pw;
+};
+
+
+/*
  * Compare by uid.
  */
 static int
@@ -144,6 +154,7 @@
     size_t nsize, psize, csize, gsize, dsize, ssize, total;
     struct cache_item *item;
     struct passwd *newpw;
+    struct cache_and_passwd *cnp;
 
     /* If shell field is empty, expand to _PATH_BSHELL. */
     pw_shell = (pw->pw_shell == NULL || pw->pw_shell[0] == '\0')
@@ -151,7 +162,7 @@
 
     /* Allocate in one big chunk for easy freeing. */
     nsize = psize = csize = gsize = dsize = ssize = 0;
-    total = sizeof(struct cache_item) + sizeof(struct passwd);
+    total = sizeof(struct cache_and_passwd);
     FIELD_SIZE(pw, pw_name, nsize);
     FIELD_SIZE(pw, pw_passwd, psize);
 #ifdef HAVE_LOGIN_CAP_H
@@ -168,15 +179,15 @@
     /* Allocate space for struct item, struct passwd and the strings. */
     if ((item = malloc(total)) == NULL)
 	    return NULL;
-    cp = (char *) item + sizeof(struct cache_item);
+    cnp = (struct cache_and_passwd*)item;
 
     /*
      * Copy in passwd contents and make strings relative to space
      * at the end of the buffer.
      */
-    newpw = (struct passwd *) cp;
+    newpw = &cnp->pw;
     memcpy(newpw, pw, sizeof(struct passwd));
-    cp += sizeof(struct passwd);
+    cp = (char*)&cnp[1];
     FIELD_COPY(pw, newpw, pw_name, nsize);
     FIELD_COPY(pw, newpw, pw_passwd, psize);
 #ifdef HAVE_LOGIN_CAP_H