]>
Commit | Line | Data |
---|---|---|
fa803e10 PG |
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 | { |