mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-09 19:00:08 +00:00
New internal function __access_noerrno
Implement an internal version of __access called __access_noerrno that avoids setting errno. This is useful to check accessibility of files very early on in process startup i.e. before TLS setup. This allows tunables to replace MALLOC_CHECK_ safely (i.e. check existence of /etc/suid-debug to enable/disable MALLOC_CHECK) and at the same time initialize very early so that it can override IFUNCs. Checked on x86_64. * hurd/hurd.h (__hurd_fail_noerrno): New function. * include/unistd.h [IS_IN (rtld) || !defined SHARED]: Declare __access_noerrno. * io/access.c (__access_noerrno): New function. * sysdeps/mach/hurd/access.c (hurd_fail_seterrno): New function. (hurd_fail_seterrno): Likewise. (access_common): Likewise. (__access_noerrno): Likewise. * sysdeps/nacl/access.c (__access_noerrno): Likewise. * sysdeps/unix/sysv/linux/access.c (__access_noerrno): Likewise. * sysdeps/nacl/nacl-interfaces.h (NACL_CALL_NOERRNO): New macro.
This commit is contained in:
parent
530862a63e
commit
afcf3cd8eb
15
ChangeLog
15
ChangeLog
@ -1,3 +1,18 @@
|
|||||||
|
2016-11-16 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
* hurd/hurd.h (__hurd_fail_noerrno): New function.
|
||||||
|
* include/unistd.h [IS_IN (rtld) || !defined SHARED]: Declare
|
||||||
|
__access_noerrno.
|
||||||
|
* io/access.c (__access_noerrno): New function.
|
||||||
|
* sysdeps/mach/hurd/access.c (hurd_fail_seterrno): New function.
|
||||||
|
(hurd_fail_seterrno): Likewise.
|
||||||
|
(access_common): Likewise.
|
||||||
|
(__access_noerrno): Likewise.
|
||||||
|
* sysdeps/nacl/access.c (__access_noerrno): Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/access.c (__access_noerrno): Likewise.
|
||||||
|
* sysdeps/nacl/nacl-interfaces.h (NACL_CALL_NOERRNO): New
|
||||||
|
macro.
|
||||||
|
|
||||||
2016-11-16 Joseph Myers <joseph@codesourcery.com>
|
2016-11-16 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
* sysdeps/unix/sysv/linux/sh/sh4/register-dump.h (register_dump):
|
* sysdeps/unix/sysv/linux/sh/sh4/register-dump.h (register_dump):
|
||||||
|
29
hurd/hurd.h
29
hurd/hurd.h
@ -75,6 +75,35 @@ __hurd_fail (error_t err)
|
|||||||
errno = err;
|
errno = err;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_HURD_H_EXTERN_INLINE int
|
||||||
|
__hurd_fail_noerrno (error_t err)
|
||||||
|
{
|
||||||
|
switch (err)
|
||||||
|
{
|
||||||
|
case EMACH_SEND_INVALID_DEST:
|
||||||
|
case EMIG_SERVER_DIED:
|
||||||
|
/* The server has disappeared! */
|
||||||
|
err = EIEIO;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KERN_NO_SPACE:
|
||||||
|
err = ENOMEM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KERN_INVALID_ARGUMENT:
|
||||||
|
err = EINVAL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Basic ports and info, initialized by startup. */
|
/* Basic ports and info, initialized by startup. */
|
||||||
|
|
||||||
|
@ -181,6 +181,12 @@ extern int __getlogin_r_loginuid (char *name, size_t namesize)
|
|||||||
# include <dl-unistd.h>
|
# include <dl-unistd.h>
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# if IS_IN (rtld) || !defined SHARED
|
||||||
|
/* __access variant that does not set errno. Used in very early initialization
|
||||||
|
code in libc.a and ld.so. */
|
||||||
|
extern __typeof (__access) __access_noerrno attribute_hidden;
|
||||||
|
# endif
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
@ -19,6 +19,13 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/* Test for access to FILE without setting errno. */
|
||||||
|
int
|
||||||
|
__access_noerrno (const char *file, int type)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Test for access to FILE. */
|
/* Test for access to FILE. */
|
||||||
int
|
int
|
||||||
__access (const char *file, int type)
|
__access (const char *file, int type)
|
||||||
|
@ -22,9 +22,20 @@
|
|||||||
#include <hurd/lookup.h>
|
#include <hurd/lookup.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
/* Test for access to FILE by our real user and group IDs. */
|
static int
|
||||||
int
|
hurd_fail_seterrno (error_t err)
|
||||||
__access (const char *file, int type)
|
{
|
||||||
|
return __hurd_fail (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
hurd_fail_noerrno (error_t err)
|
||||||
|
{
|
||||||
|
return __hurd_fail_noerrno (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
access_common (const char *file, int type, int (*errfunc) (error_t))
|
||||||
{
|
{
|
||||||
error_t err;
|
error_t err;
|
||||||
file_t rcrdir, rcwdir, io;
|
file_t rcrdir, rcwdir, io;
|
||||||
@ -120,13 +131,13 @@ __access (const char *file, int type)
|
|||||||
if (rcwdir != MACH_PORT_NULL)
|
if (rcwdir != MACH_PORT_NULL)
|
||||||
__mach_port_deallocate (__mach_task_self (), rcwdir);
|
__mach_port_deallocate (__mach_task_self (), rcwdir);
|
||||||
if (err)
|
if (err)
|
||||||
return __hurd_fail (err);
|
return errfunc (err);
|
||||||
|
|
||||||
/* Find out what types of access we are allowed to this file. */
|
/* Find out what types of access we are allowed to this file. */
|
||||||
err = __file_check_access (io, &allowed);
|
err = __file_check_access (io, &allowed);
|
||||||
__mach_port_deallocate (__mach_task_self (), io);
|
__mach_port_deallocate (__mach_task_self (), io);
|
||||||
if (err)
|
if (err)
|
||||||
return __hurd_fail (err);
|
return errfunc (err);
|
||||||
|
|
||||||
flags = 0;
|
flags = 0;
|
||||||
if (type & R_OK)
|
if (type & R_OK)
|
||||||
@ -138,9 +149,23 @@ __access (const char *file, int type)
|
|||||||
|
|
||||||
if (flags & ~allowed)
|
if (flags & ~allowed)
|
||||||
/* We are not allowed all the requested types of access. */
|
/* We are not allowed all the requested types of access. */
|
||||||
return __hurd_fail (EACCES);
|
return errfunc (EACESS);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test for access to FILE by our real user and group IDs without setting
|
||||||
|
errno. */
|
||||||
|
int
|
||||||
|
__access_noerrno (const char *file, int type)
|
||||||
|
{
|
||||||
|
return access_common (file, type, hurd_fail_noerrno);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test for access to FILE by our real user and group IDs. */
|
||||||
|
int
|
||||||
|
__access (const char *file, int type)
|
||||||
|
{
|
||||||
|
return access_common (file, type, hurd_fail_seterrno);
|
||||||
|
}
|
||||||
weak_alias (__access, access)
|
weak_alias (__access, access)
|
||||||
|
@ -19,6 +19,13 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <nacl-interfaces.h>
|
#include <nacl-interfaces.h>
|
||||||
|
|
||||||
|
/* Test for access to FILE without setting errno. */
|
||||||
|
int
|
||||||
|
__access_noerrno (const char *file, int type)
|
||||||
|
{
|
||||||
|
return NACL_CALL_NOERRNO (__nacl_irt_dev_filename.access (file, type), 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Test for access to FILE. */
|
/* Test for access to FILE. */
|
||||||
int
|
int
|
||||||
__access (const char *file, int type)
|
__access (const char *file, int type)
|
||||||
|
@ -113,4 +113,8 @@ __nacl_fail (int err)
|
|||||||
#define NACL_CALL(err, val) \
|
#define NACL_CALL(err, val) \
|
||||||
({ int _err = (err); _err ? __nacl_fail (_err) : (val); })
|
({ int _err = (err); _err ? __nacl_fail (_err) : (val); })
|
||||||
|
|
||||||
|
/* Same as NACL_CALL but without setting errno. */
|
||||||
|
#define NACL_CALL_NOERRNO(err, val) \
|
||||||
|
({ int _err = (err); _err ? _err : (val); })
|
||||||
|
|
||||||
#endif /* nacl-interfaces.h */
|
#endif /* nacl-interfaces.h */
|
||||||
|
@ -20,6 +20,21 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sysdep-cancel.h>
|
#include <sysdep-cancel.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
__access_noerrno (const char *file, int type)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
INTERNAL_SYSCALL_DECL (err);
|
||||||
|
#ifdef __NR_access
|
||||||
|
res = INTERNAL_SYSCALL_CALL (access, err, file, type);
|
||||||
|
#else
|
||||||
|
res = INTERNAL_SYSCALL_CALL (faccessat, err, AT_FDCWD, file, type);
|
||||||
|
#endif
|
||||||
|
if (INTERNAL_SYSCALL_ERROR_P (res, err))
|
||||||
|
return INTERNAL_SYSCALL_ERRNO (res, err);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
__access (const char *file, int type)
|
__access (const char *file, int type)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user