File: tg-faccessat.diff

package info (click to toggle)
glibc 2.24-11%2Bdeb9u3
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 225,316 kB
  • sloc: ansic: 996,116; asm: 261,826; sh: 10,483; makefile: 9,849; cpp: 4,169; python: 3,971; perl: 2,254; awk: 1,753; pascal: 1,521; yacc: 291; sed: 80
file content (465 lines) | stat: -rw-r--r-- 13,986 bytes parent folder | download | duplicates (4)
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
Subject: [PATCH] Implement faccessat without AT_EACCESS flag

* hurd/hurd/fd.h: Include <fcntl.h>
(__hurd_at_flags): New function.
* hurd/lookup-at.c (__file_name_lookup_at): Replace flag computation
with call to __hurd_at_flags.
* include/unistd.h (__faccessat): Add declaration.
* sysdeps/mach/hurd/access.c (__access): Move implementation to
__faccessat, and replace it with a call to __faccessat.
* sysdeps/mach/hurd/euidaccess.c (__euidaccess): Replace implementation
with a call to __faccessat.
* sysdeps/mach/hurd/faccessat.c (faccessat): Rename into...
(__faccessat): ... this. Move implementation of __access into it when
AT_FLAGS does not contain AT_EACCESS. Make it call __hurd_at_flags, add
reauthenticate_cwdir_at helper to implement AT mechanism.
(faccessat): Define weak alias.

---
 hurd/hurd/fd.h                 |  21 ++++++
 hurd/lookup-at.c               |  13 +---
 include/unistd.h               |   1 +
 sysdeps/mach/hurd/access.c     | 120 +-------------------------------
 sysdeps/mach/hurd/euidaccess.c |  31 +--------
 sysdeps/mach/hurd/faccessat.c  | 152 +++++++++++++++++++++++++++++++++++++----
 6 files changed, 165 insertions(+), 173 deletions(-)

diff --git a/hurd/hurd/fd.h b/hurd/hurd/fd.h
index adb865a..1f22153 100644
--- a/hurd/hurd/fd.h
+++ b/hurd/hurd/fd.h
@@ -26,6 +26,7 @@
 #include <hurd/hurd_types.h>
 #include <hurd/port.h>
 #include <sys/socket.h>
+#include <fcntl.h>
 
 
 /* Structure representing a file descriptor.  */
@@ -254,6 +255,26 @@ extern int _hurd_select (int nfds, struct pollfd *pollfds,
 			 const struct timespec *timeout,
 			 const sigset_t *sigmask);
 
+/* Apply AT_FLAGS on FLAGS, in preparation for calling
+   __hurd_file_name_lookup.  */
+
+_HURD_FD_H_EXTERN_INLINE error_t
+__hurd_at_flags (int *at_flags, int *flags)
+{
+  if ((*at_flags & AT_SYMLINK_FOLLOW) && (*at_flags & AT_SYMLINK_NOFOLLOW))
+    return EINVAL;
+
+  *flags |= (*at_flags & AT_SYMLINK_NOFOLLOW) ? O_NOLINK : 0;
+  *at_flags &= ~AT_SYMLINK_NOFOLLOW;
+  if (*at_flags & AT_SYMLINK_FOLLOW)
+    *flags &= ~O_NOLINK;
+  *at_flags &= ~AT_SYMLINK_FOLLOW;
+  if (*at_flags != 0)
+    return EINVAL;
+
+  return 0;
+}
+
 /* Variant of file_name_lookup used in *at function implementations.
    AT_FLAGS may only contain AT_SYMLINK_FOLLOW or AT_SYMLINK_NOFOLLOW,
    which will remove and add O_NOLINK from FLAGS respectively.
diff --git a/hurd/lookup-at.c b/hurd/lookup-at.c
index 0288bcf..d729f67 100644
--- a/hurd/lookup-at.c
+++ b/hurd/lookup-at.c
@@ -29,16 +29,9 @@ __file_name_lookup_at (int fd, int at_flags,
   error_t err;
   file_t result;
 
-  if ((at_flags & AT_SYMLINK_FOLLOW) && (at_flags & AT_SYMLINK_NOFOLLOW))
-    return (__hurd_fail (EINVAL), MACH_PORT_NULL);
-
-  flags |= (at_flags & AT_SYMLINK_NOFOLLOW) ? O_NOLINK : 0;
-  at_flags &= ~AT_SYMLINK_NOFOLLOW;
-  if (at_flags & AT_SYMLINK_FOLLOW)
-    flags &= ~O_NOLINK;
-  at_flags &= ~AT_SYMLINK_FOLLOW;
-  if (at_flags != 0)
-    return (__hurd_fail (EINVAL), MACH_PORT_NULL);
+  err = __hurd_at_flags (&at_flags, &flags);
+  if (err)
+    return (__hurd_fail (err), MACH_PORT_NULL);
 
   if (fd == AT_FDCWD || file_name[0] == '/')
     return __file_name_lookup (file_name, flags, mode);
diff --git a/include/unistd.h b/include/unistd.h
index a5cbc5d..09f9342 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -23,6 +23,7 @@ libc_hidden_proto (readlinkat)
 /* Now define the internal interfaces.  */
 extern int __access (const char *__name, int __type);
 extern int __euidaccess (const char *__name, int __type);
+extern int __faccessat (int __fd, const char *__file, int __type, int __flag);
 extern __off64_t __lseek64 (int __fd, __off64_t __offset, int __whence);
 extern __off_t __lseek (int __fd, __off_t __offset, int __whence);
 libc_hidden_proto (__lseek)
diff --git a/sysdeps/mach/hurd/access.c b/sysdeps/mach/hurd/access.c
index 3a54df7..9379689 100644
--- a/sysdeps/mach/hurd/access.c
+++ b/sysdeps/mach/hurd/access.c
@@ -16,10 +16,6 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <unistd.h>
-#include <hurd.h>
-#include <hurd/port.h>
-#include <hurd/id.h>
-#include <hurd/lookup.h>
 #include <fcntl.h>
 
 /* Test for access to FILE by our real user and group IDs.  */
@@ -28,121 +24,7 @@ __access (file, type)
 int
 __access (const char *file, int type)
 {
-  error_t err;
-  file_t rcrdir, rcwdir, io;
-  int flags, allowed;
-
-  error_t reauthenticate (int which, file_t *result)
-    {
-      /* Get a port to our root directory, authenticated with the real IDs.  */
-      error_t err;
-      mach_port_t ref;
-      ref = __mach_reply_port ();
-      err = HURD_PORT_USE
-	(&_hurd_ports[which],
-	 ({
-	   err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
-	   if (!err)
-	     err = __auth_user_authenticate (_hurd_id.rid_auth,
-					     ref, MACH_MSG_TYPE_MAKE_SEND,
-					     result);
-	   err;
-	 }));
-      __mach_port_destroy (__mach_task_self (), ref);
-      return err;
-    }
-
-  error_t init_port (int which, error_t (*operate) (mach_port_t))
-    {
-      switch (which)
-	{
-	case INIT_PORT_AUTH:
-	  return (*operate) (_hurd_id.rid_auth);
-	case INIT_PORT_CRDIR:
-	  return (reauthenticate (INIT_PORT_CRDIR, &rcrdir) ?:
-		  (*operate) (rcrdir));
-	case INIT_PORT_CWDIR:
-	  return (reauthenticate (INIT_PORT_CWDIR, &rcwdir) ?:
-		  (*operate) (rcwdir));
-	default:
-	  return _hurd_ports_use (which, operate);
-	}
-    }
-
-  rcrdir = rcwdir = MACH_PORT_NULL;
-
-  HURD_CRITICAL_BEGIN;
-
-  __mutex_lock (&_hurd_id.lock);
-  /* Get _hurd_id up to date.  */
-  if (err = _hurd_check_ids ())
-    goto lose;
-
-  if (_hurd_id.rid_auth == MACH_PORT_NULL)
-    {
-      /* Set up _hurd_id.rid_auth.  This is a special auth server port
-	 which uses the real uid and gid (the first aux uid and gid) as
-	 the only effective uid and gid.  */
-
-      if (_hurd_id.aux.nuids < 1 || _hurd_id.aux.ngids < 1)
-	{
-	  /* We do not have a real UID and GID.  Lose, lose, lose!  */
-	  err = EGRATUITOUS;
-	  goto lose;
-	}
-
-      /* Create a new auth port using our real UID and GID (the first
-	 auxiliary UID and GID) as the only effective IDs.  */
-      if (err = __USEPORT (AUTH,
-			   __auth_makeauth (port,
-					    NULL, MACH_MSG_TYPE_COPY_SEND, 0,
-					    _hurd_id.aux.uids, 1,
-					    _hurd_id.aux.uids,
-					    _hurd_id.aux.nuids,
-					    _hurd_id.aux.gids, 1,
-					    _hurd_id.aux.gids,
-					    _hurd_id.aux.ngids,
-					    &_hurd_id.rid_auth)))
-	goto lose;
-    }
-
-  if (!err)
-    /* Look up the file name using the modified init ports.  */
-    err = __hurd_file_name_lookup (&init_port, &__getdport, 0,
-				   file, 0, 0, &io);
-
-  /* We are done with _hurd_id.rid_auth now.  */
- lose:
-  __mutex_unlock (&_hurd_id.lock);
-
-  HURD_CRITICAL_END;
-
-  if (rcrdir != MACH_PORT_NULL)
-    __mach_port_deallocate (__mach_task_self (), rcrdir);
-  if (rcwdir != MACH_PORT_NULL)
-    __mach_port_deallocate (__mach_task_self (), rcwdir);
-  if (err)
-    return __hurd_fail (err);
-
-  /* Find out what types of access we are allowed to this file.  */
-  err = __file_check_access (io, &allowed);
-  __mach_port_deallocate (__mach_task_self (), io);
-  if (err)
-    return __hurd_fail (err);
-
-  flags = 0;
-  if (type & R_OK)
-    flags |= O_READ;
-  if (type & W_OK)
-    flags |= O_WRITE;
-  if (type & X_OK)
-    flags |= O_EXEC;
-
-  if (flags & ~allowed)
-    /* We are not allowed all the requested types of access.  */
-    return __hurd_fail (EACCES);
-
-  return 0;
+  return __faccessat (AT_FDCWD, file, type, 0);
 }
 
 weak_alias (__access, access)
diff --git a/sysdeps/mach/hurd/euidaccess.c b/sysdeps/mach/hurd/euidaccess.c
index 5b96a3c..a4da9da 100644
--- a/sysdeps/mach/hurd/euidaccess.c
+++ b/sysdeps/mach/hurd/euidaccess.c
@@ -16,42 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#include <stddef.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <hurd.h>
 
 int
 __euidaccess (const char *file, int type)
 {
-  error_t err;
-  file_t port;
-  int allowed, flags;
-
-  port = __file_name_lookup (file, 0, 0);
-  if (port == MACH_PORT_NULL)
-    return -1;
-
-  /* Find out what types of access we are allowed to this file.  */
-  err = __file_check_access (port, &allowed);
-  __mach_port_deallocate (__mach_task_self (), port);
-  if (err)
-    return __hurd_fail (err);
-
-  flags = 0;
-  if (type & R_OK)
-    flags |= O_READ;
-  if (type & W_OK)
-    flags |= O_WRITE;
-  if (type & X_OK)
-    flags |= O_EXEC;
-
-  if (flags & ~allowed)
-    /* We are not allowed all the requested types of access.  */
-    return __hurd_fail (EACCES);
-
-  return 0;
+  return __faccessat (AT_FDCWD, file, type, AT_EACCESS);
 }
 weak_alias (__euidaccess, euidaccess)
 weak_alias (__euidaccess, eaccess)
diff --git a/sysdeps/mach/hurd/faccessat.c b/sysdeps/mach/hurd/faccessat.c
index 91bec43..5ca7ff7 100644
--- a/sysdeps/mach/hurd/faccessat.c
+++ b/sysdeps/mach/hurd/faccessat.c
@@ -23,29 +23,152 @@
 #include <sys/types.h>
 #include <hurd.h>
 #include <hurd/fd.h>
+#include <hurd/port.h>
+#include <hurd/id.h>
+#include <hurd/lookup.h>
 
 int
-faccessat (int fd, const char *file, int type, int flag)
+__faccessat (int fd, const char *file, int type, int at_flags)
 {
   error_t err;
-  file_t port;
-  int allowed, flags;
+  file_t rcrdir, rcwdir, io;
+  int flags, allowed;
 
-  if ((flag & AT_EACCESS) == 0)
+  if ((at_flags & AT_EACCESS) == AT_EACCESS)
     {
-      if (fd == AT_FDCWD || file[0] == '/')
-	return __access (file, type);
-      __set_errno (ENOTSUP);	/* XXX later */
-      return -1;
+      /* Use effective permissions.  */
+      io = __file_name_lookup_at (fd, at_flags &~ AT_EACCESS, file, 0, 0);
+      if (io == MACH_PORT_NULL)
+	return -1;
     }
+  else
+    {
+      /* We have to use real permissions instead of the
+         usual effective permissions.  */
+
+      int hurd_flags = 0;
+      __hurd_at_flags (&at_flags, &hurd_flags);
+
+      error_t reauthenticate_cwdir_at (file_t *result)
+	{
+	  /* Get a port to the FD directory, authenticated with the real IDs.  */
+	  error_t err;
+	  mach_port_t ref;
+	  ref = __mach_reply_port ();
+	  err = HURD_DPORT_USE
+	    (fd,
+	     ({
+	       err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
+	       if (!err)
+		 err = __auth_user_authenticate (_hurd_id.rid_auth,
+						 ref, MACH_MSG_TYPE_MAKE_SEND,
+						 result);
+	       err;
+	     }));
+	  __mach_port_destroy (__mach_task_self (), ref);
+	  return err;
+	}
+
+      error_t reauthenticate (int which, file_t *result)
+	{
+	  /* Get a port to our root directory, authenticated with the real IDs.  */
+	  error_t err;
+	  mach_port_t ref;
+	  ref = __mach_reply_port ();
+	  err = HURD_PORT_USE
+	    (&_hurd_ports[which],
+	     ({
+	       err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
+	       if (!err)
+		 err = __auth_user_authenticate (_hurd_id.rid_auth,
+						 ref, MACH_MSG_TYPE_MAKE_SEND,
+						 result);
+	       err;
+	     }));
+	  __mach_port_destroy (__mach_task_self (), ref);
+	  return err;
+	}
+
+      error_t init_port (int which, error_t (*operate) (mach_port_t))
+	{
+	  switch (which)
+	    {
+	    case INIT_PORT_AUTH:
+	      return (*operate) (_hurd_id.rid_auth);
+	    case INIT_PORT_CRDIR:
+	      return (reauthenticate (INIT_PORT_CRDIR, &rcrdir) ?:
+		      (*operate) (rcrdir));
+	    case INIT_PORT_CWDIR:
+	      if (fd == AT_FDCWD || file[0] == '/')
+		return (reauthenticate (INIT_PORT_CWDIR, &rcwdir) ?:
+			(*operate) (rcwdir));
+	      else
+		return (reauthenticate_cwdir_at (&rcwdir) ?:
+			(*operate) (rcwdir));
+	    default:
+	      return _hurd_ports_use (which, operate);
+	    }
+	}
+
+      rcrdir = rcwdir = MACH_PORT_NULL;
+
+      HURD_CRITICAL_BEGIN;
+
+      __mutex_lock (&_hurd_id.lock);
+      /* Get _hurd_id up to date.  */
+      if (err = _hurd_check_ids ())
+	goto lose;
 
-  port = __file_name_lookup_at (fd, flag &~ AT_EACCESS, file, 0, 0);
-  if (port == MACH_PORT_NULL)
-    return -1;
+      if (_hurd_id.rid_auth == MACH_PORT_NULL)
+	{
+	  /* Set up _hurd_id.rid_auth.  This is a special auth server port
+	     which uses the real uid and gid (the first aux uid and gid) as
+	     the only effective uid and gid.  */
+
+	  if (_hurd_id.aux.nuids < 1 || _hurd_id.aux.ngids < 1)
+	    {
+	      /* We do not have a real UID and GID.  Lose, lose, lose!  */
+	      err = EGRATUITOUS;
+	      goto lose;
+	    }
+
+	  /* Create a new auth port using our real UID and GID (the first
+	     auxiliary UID and GID) as the only effective IDs.  */
+	  if (err = __USEPORT (AUTH,
+			       __auth_makeauth (port,
+						NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+						_hurd_id.aux.uids, 1,
+						_hurd_id.aux.uids,
+						_hurd_id.aux.nuids,
+						_hurd_id.aux.gids, 1,
+						_hurd_id.aux.gids,
+						_hurd_id.aux.ngids,
+						&_hurd_id.rid_auth)))
+	    goto lose;
+	}
+
+      if (!err)
+	/* Look up the file name using the modified init ports.  */
+	err = __hurd_file_name_lookup (&init_port, &__getdport, 0,
+				       file, hurd_flags, 0, &io);
+
+      /* We are done with _hurd_id.rid_auth now.  */
+     lose:
+      __mutex_unlock (&_hurd_id.lock);
+
+      HURD_CRITICAL_END;
+
+      if (rcrdir != MACH_PORT_NULL)
+	__mach_port_deallocate (__mach_task_self (), rcrdir);
+      if (rcwdir != MACH_PORT_NULL)
+	__mach_port_deallocate (__mach_task_self (), rcwdir);
+      if (err)
+	return __hurd_fail (err);
+    }
 
   /* Find out what types of access we are allowed to this file.  */
-  err = __file_check_access (port, &allowed);
-  __mach_port_deallocate (__mach_task_self (), port);
+  err = __file_check_access (io, &allowed);
+  __mach_port_deallocate (__mach_task_self (), io);
   if (err)
     return __hurd_fail (err);
 
@@ -67,3 +190,4 @@ faccessat (fd, file, type, flag)
 
   return 0;
 }
+weak_alias (__faccessat, faccessat)
-- 
tg: (58695b8..) t/faccessat (depends on: baseline)