]> git.pld-linux.org Git - packages/XFree86.git/blob - XFree86-4.2.1-mit-shm-security.patch
- base R: XFree86-xft
[packages/XFree86.git] / XFree86-4.2.1-mit-shm-security.patch
1 Index: xc/config/cf/FreeBSD.cf
2 ===================================================================
3 RCS file: /home/x-cvs/xc/config/cf/FreeBSD.cf,v
4 retrieving revision 3.112.2.1
5 diff -u -r3.112.2.1 FreeBSD.cf
6 --- xc/config/cf/FreeBSD.cf     2002/09/04 02:38:08     3.112.2.1
7 +++ xc/config/cf/FreeBSD.cf     2002/09/12 20:51:03
8 @@ -191,6 +191,10 @@
9  #define HasSetUserContext      YES
10  #endif
11  
12 +#if OSMajorVersion >= 5 || (OSMajorVersion == 4 && OSMinorVersion >= 6) 
13 +#define HasGetpeereid          YES
14 +#endif
15 +
16  /* 3.3(?) and later has support for setting MTRRs */
17  #ifndef HasMTRRSupport
18  #if OSMajorVersion > 3 || (OSMajorVersion == 3 && OSMinorVersion >= 3)
19 Index: xc/config/cf/Imake.tmpl
20 ===================================================================
21 RCS file: /home/x-cvs/xc/config/cf/Imake.tmpl,v
22 retrieving revision 3.116.2.1
23 diff -u -r3.116.2.1 Imake.tmpl
24 --- xc/config/cf/Imake.tmpl     2002/09/04 02:38:08     3.116.2.1
25 +++ xc/config/cf/Imake.tmpl     2002/09/12 20:51:06
26 @@ -395,6 +395,9 @@
27  #ifndef HasPamMisc
28  #define HasPamMisc             NO
29  #endif
30 +#ifndef HasGetpeereid
31 +#define HasGetpeereid          NO
32 +#endif
33  /* byte-order defaults */
34  #ifndef ByteOrder
35  #if defined(VaxArchitecture)
36 Index: xc/config/cf/OpenBSD.cf
37 ===================================================================
38 RCS file: /home/x-cvs/xc/config/cf/OpenBSD.cf,v
39 retrieving revision 3.66.2.1
40 diff -u -r3.66.2.1 OpenBSD.cf
41 --- xc/config/cf/OpenBSD.cf     2002/09/04 02:38:08     3.66.2.1
42 +++ xc/config/cf/OpenBSD.cf     2002/09/12 20:51:06
43 @@ -97,6 +97,11 @@
44  # define HasBSDAuth            YES
45  #endif
46  
47 +/* OpenBSD 3.0 and later has getpeereid() */
48 +#if OSMajorVersion >= 3
49 +# define HasGetpeereid         YES
50 +#endif
51 +
52  /* OpenBSD 3.0 has APM with kqueue interface */
53  #if OSMajorVersion >= 3
54  # define HasApmKqueue          YES
55 Index: xc/programs/Xserver/Xext/shm.c
56 ===================================================================
57 RCS file: /home/x-cvs/xc/programs/Xserver/Xext/shm.c,v
58 retrieving revision 3.33.2.2
59 diff -u -r3.33.2.2 shm.c
60 --- xc/programs/Xserver/Xext/shm.c      2002/05/29 23:03:19     3.33.2.2
61 +++ xc/programs/Xserver/Xext/shm.c      2002/09/12 20:51:36
62 @@ -38,6 +38,7 @@
63  #include <shm.h>
64  #endif
65  #include <unistd.h>
66 +#include <sys/stat.h>
67  #define NEED_REPLIES
68  #define NEED_EVENTS
69  #include "X.h"
70 @@ -64,12 +65,6 @@
71  #include "panoramiXsrv.h"
72  #endif
73  
74 -#if defined(SVR4) || defined(__linux__) || defined(CSRG_BASED)
75 -#define HAS_SAVED_IDS_AND_SETEUID
76 -#else
77 -#include <sys/stat.h>
78 -#endif
79 -
80  typedef struct _ShmDesc {
81      struct _ShmDesc *next;
82      int shmid;
83 @@ -361,35 +356,38 @@
84      return (client->noClientException);
85  }
86  
87 -#ifndef HAS_SAVED_IDS_AND_SETEUID
88  /*
89   * Simulate the access() system call for a shared memory segement,
90 - * using the real user and group id of the process
91 + * using the credentials from the client if available
92   */
93  static int
94 -shm_access(uid_t uid, gid_t gid, struct ipc_perm *perm, int readonly)
95 +shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
96  {
97 +    int uid, gid;
98      mode_t mask;
99  
100 -    /* User id 0 always gets access */
101 -    if (uid == 0) {
102 -       return 0;
103 -    }
104 -    /* Check the owner */
105 -    if (perm->uid == uid || perm->cuid == uid) {
106 -       mask = S_IRUSR;
107 -       if (!readonly) {
108 -           mask |= S_IWUSR;
109 +    if (LocalClientCred(client, &uid, &gid) != -1) {
110 +       
111 +       /* User id 0 always gets access */
112 +       if (uid == 0) {
113 +           return 0;
114         }
115 -       return (perm->mode & mask) == mask ? 0 : -1;
116 -    }
117 -    /* Check the group */
118 -    if (perm->gid == gid || perm->cgid == gid) {
119 -       mask = S_IRGRP;
120 -       if (!readonly) {
121 -           mask |= S_IWGRP;
122 +       /* Check the owner */
123 +       if (perm->uid == uid || perm->cuid == uid) {
124 +           mask = S_IRUSR;
125 +           if (!readonly) {
126 +               mask |= S_IWUSR;
127 +           }
128 +           return (perm->mode & mask) == mask ? 0 : -1;
129 +       }
130 +       /* Check the group */
131 +       if (perm->gid == gid || perm->cgid == gid) {
132 +           mask = S_IRGRP;
133 +           if (!readonly) {
134 +               mask |= S_IWGRP;
135 +           }
136 +           return (perm->mode & mask) == mask ? 0 : -1;
137         }
138 -       return (perm->mode & mask) == mask ? 0 : -1;
139      }
140      /* Otherwise, check everyone else */
141      mask = S_IROTH;
142 @@ -398,7 +396,6 @@
143      }
144      return (perm->mode & mask) == mask ? 0 : -1;
145  }
146 -#endif
147  
148  static int
149  ProcShmAttach(client)
150 @@ -407,12 +404,6 @@
151      struct shmid_ds buf;
152      ShmDescPtr shmdesc;
153      REQUEST(xShmAttachReq);
154 -    uid_t ruid;
155 -    gid_t rgid;
156 -#ifdef HAS_SAVED_IDS_AND_SETEUID
157 -    uid_t euid;
158 -    gid_t egid;
159 -#endif
160  
161      REQUEST_SIZE_MATCH(xShmAttachReq);
162      LEGAL_NEW_RESOURCE(stuff->shmseg, client);
163 @@ -436,44 +427,25 @@
164         shmdesc = (ShmDescPtr) xalloc(sizeof(ShmDescRec));
165         if (!shmdesc)
166             return BadAlloc;
167 -       ruid = getuid();
168 -       rgid = getgid();
169 -#ifdef HAS_SAVED_IDS_AND_SETEUID
170 -       euid = geteuid();
171 -       egid = getegid();
172 -
173 -       if (euid != ruid || egid != rgid) {
174 -           /* Temporarly switch back to real ids */
175 -           if (seteuid(ruid) == -1 || setegid(rgid) == -1) {
176 -               return BadAccess;
177 -           }
178 -       }
179 -#endif
180         shmdesc->addr = shmat(stuff->shmid, 0,
181                               stuff->readOnly ? SHM_RDONLY : 0);
182 -#ifdef HAS_SAVED_IDS_AND_SETEUID
183 -       if (euid != ruid || egid != rgid) {
184 -           /* Switch back to root privs */
185 -           if (seteuid(euid) == -1 || setegid(egid) == -1) {
186 -               return BadAccess;
187 -           }
188 -       } 
189 -#endif
190         if ((shmdesc->addr == ((char *)-1)) ||
191             shmctl(stuff->shmid, IPC_STAT, &buf))
192         {
193             xfree(shmdesc);
194             return BadAccess;
195         }
196 -#ifndef HAS_SAVED_IDS_AND_SETEUID
197 +
198         /* The attach was performed with root privs. We must
199 -        * do manual checking of access rights for the real uid/gid */
200 -       if (shm_access(ruid, rgid, &(buf.shm_perm), stuff->readOnly) == -1) {
201 +        * do manual checking of access rights for the credentials 
202 +        * of the client */
203 +
204 +       if (shm_access(client, &(buf.shm_perm), stuff->readOnly) == -1) {
205             shmdt(shmdesc->addr);
206             xfree(shmdesc);
207             return BadAccess;
208         }
209 -#endif 
210 +
211         shmdesc->shmid = stuff->shmid;
212         shmdesc->refcnt = 1;
213         shmdesc->writable = !stuff->readOnly;
214 Index: xc/programs/Xserver/include/os.h
215 ===================================================================
216 RCS file: /home/x-cvs/xc/programs/Xserver/include/os.h,v
217 retrieving revision 3.40
218 diff -u -r3.40 os.h
219 --- xc/programs/Xserver/include/os.h    2001/12/14 19:59:55     3.40
220 +++ xc/programs/Xserver/include/os.h    2002/09/12 20:51:42
221 @@ -639,6 +639,8 @@
222  #endif
223  );
224  
225 +extern int LocalClientCred(ClientPtr, int *, int *);
226 +
227  extern int ChangeAccessControl(
228  #if NeedFunctionPrototypes
229      ClientPtr /*client*/,
230 Index: xc/programs/Xserver/os/Imakefile
231 ===================================================================
232 RCS file: /home/x-cvs/xc/programs/Xserver/os/Imakefile,v
233 retrieving revision 3.34
234 diff -u -r3.34 Imakefile
235 --- xc/programs/Xserver/os/Imakefile    2001/10/28 03:34:16     3.34
236 +++ xc/programs/Xserver/os/Imakefile    2002/09/12 20:51:42
237 @@ -78,6 +78,10 @@
238  MALLOC_OBJS=xalloc.o
239  #endif
240  
241 +#if HasGetpeereid
242 +GETPEEREID_DEFINES = -DHAS_GETPEEREID
243 +#endif
244 +
245  BOOTSTRAPCFLAGS = 
246             SRCS = WaitFor.c access.c connection.c io.c $(COLOR_SRCS) \
247                    osinit.c utils.c auth.c mitauth.c secauth.c $(XDMAUTHSRCS) \
248 @@ -111,7 +115,7 @@
249  #endif
250          DEFINES = -DXSERV_t -DTRANS_SERVER $(CONNECTION_FLAGS) $(MEM_DEFINES) \
251                   $(XDMAUTHDEFS) $(RPCDEFS) $(SIGNAL_DEFINES) $(OS_DEFINES) \
252 -                 $(KRB5_DEFINES) $(RGB_DEFINES)
253 +                 $(KRB5_DEFINES) $(RGB_DEFINES) $(GETPEEREID_DEFINES)
254         INCLUDES = -I. -I../include -I$(XINCLUDESRC) -I$(EXTINCSRC) \
255                   -I$(SERVERSRC)/Xext -I$(FONTINCSRC) \
256                   -I$(TOP)/lib/Xau -I../lbx Krb5Includes
257 Index: xc/programs/Xserver/os/access.c
258 ===================================================================
259 RCS file: /home/x-cvs/xc/programs/Xserver/os/access.c,v
260 retrieving revision 3.39
261 diff -u -r3.39 access.c
262 --- xc/programs/Xserver/os/access.c     2002/01/07 20:38:29     3.39
263 +++ xc/programs/Xserver/os/access.c     2002/09/12 20:51:44
264 @@ -1007,6 +1007,55 @@
265      return FALSE;
266  }
267  
268 +/*
269 + * Return the uid and gid of a connected local client
270 + * or the uid/gid for nobody those ids cannot be determinded
271 + * 
272 + * Used by XShm to test access rights to shared memory segments
273 + */
274 +int
275 +LocalClientCred(ClientPtr client, int *pUid, int *pGid)
276 +{
277 +    int fd;
278 +    XtransConnInfo ci;
279 +#ifdef HAS_GETPEEREID
280 +    uid_t uid;
281 +    gid_t gid;
282 +#elif defined(SO_PEERCRED)
283 +    struct ucred peercred;
284 +    socklen_t so_len = sizeof(peercred);
285 +#endif
286 +
287 +    if (client == NULL)
288 +       return -1;
289 +    ci = ((OsCommPtr)client->osPrivate)->trans_conn;
290 +    /* We can only determine peer credentials for Unix domain sockets */
291 +    if (!_XSERVTransIsLocal(ci)) {
292 +       return -1;
293 +    }
294 +    fd = _XSERVTransGetConnectionNumber(ci);
295 +#ifdef HAS_GETPEEREID
296 +    if (getpeereid(fd, &uid, &gid) == -1) 
297 +           return -1;
298 +    if (pUid != NULL)
299 +           *pUid = uid;
300 +    if (pGid != NULL)
301 +           *pGid = gid;
302 +    return 0;
303 +#elif defined(SO_PEERCRED)
304 +    if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1) 
305 +           return -1;
306 +    if (pUid != NULL)
307 +           *pUid = peercred.uid;
308 +    if (pGid != NULL)
309 +           *pGid = peercred.gid;
310 +    return 0;
311 +#else
312 +    /* No system call available to get the credentials of the peer */
313 +    return -1;
314 +#endif
315 +}
316 +
317  static Bool
318  AuthorizedClient(ClientPtr client)
319  {
This page took 0.046489 seconds and 3 git commands to generate.