diff options
author | Ulrich Drepper <drepper@redhat.com> | 2004-09-20 00:16:11 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2004-09-20 00:16:11 +0000 |
commit | 2edb61e3f955bfcc9dd3cb6b3b1acfe4806234a6 (patch) | |
tree | eb3ba83120d92a0ea9955520f2df4e00a22bc884 /sysdeps/unix | |
parent | 29e11320c90722aec6335a5f8d8af84d12ba3c6b (diff) | |
download | glibc-2edb61e3f955bfcc9dd3cb6b3b1acfe4806234a6.tar glibc-2edb61e3f955bfcc9dd3cb6b3b1acfe4806234a6.tar.gz glibc-2edb61e3f955bfcc9dd3cb6b3b1acfe4806234a6.tar.bz2 glibc-2edb61e3f955bfcc9dd3cb6b3b1acfe4806234a6.zip |
Update.
* sysdeps/unix/sysv/linux/setegid.c [HAVE_PTR__NPTL_SETXID]: Call
callback to set IDs in all other threads as well.
* sysdeps/unix/sysv/linux/seteuid.c: Likewise.
* sysdeps/unix/sysv/linux/i386/setegid.c: Likewise.
* sysdeps/unix/sysv/linux/i386/seteuid.c: Likewise.
* sysdeps/unix/sysv/linux/i386/setgid.c: Likewise.
* sysdeps/unix/sysv/linux/i386/setuid.c: Likewise.
* sysdeps/unix/sysv/linux/i386/setreuid.c: Likewise.
* sysdeps/unix/sysv/linux/i386/setreuid.c: Likewise.
* sysdeps/unix/sysv/linux/i386/setresuid.c: Likewise.
* sysdeps/unix/sysv/linux/i386/setresuid.c: Likewise.
* sysdeps/unix/sysv/linux/setuid.c: New file.
* sysdeps/unix/sysv/linux/setgid.c: New file.
* sysdeps/unix/sysv/linux/setreuid.c: New file.
* sysdeps/unix/sysv/linux/setregid.c: New file.
* sysdeps/unix/sysv/linux/setresuid.c: New file.
* sysdeps/unix/sysv/linux/setresgid.c: New file.
* sysdeps/unix/sysv/linux/i386/sysdep.h: Define INTERNAL_SYSCALL_NCS.
* sysdeps/unix/sysv/linux/ia64/sysdep.h: Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h: Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h: Likewise.
* sysdeps/unix/sysv/linux/x86_64/sysdep.h: Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc32/setegid.c: Use x86 version.
* sysdeps/unix/sysv/linux/sparc/sparc32/seteuid.c: Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc32/setresgid.c: New file.
* sysdeps/unix/sysv/linux/sparc/sparc32/setresuid.c: New file.
* sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list: Remove setresgid
and setresuid.
* nscd/aicache.c: Use pthread_seteuid_np instead of seteuid.
* nscd/grpcache.c: Likewise.
* nscd/hstcache.c: Likewise.
* nscd/pwdcache.c: Likewise.
Diffstat (limited to 'sysdeps/unix')
26 files changed, 689 insertions, 215 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/setegid.c b/sysdeps/unix/sysv/linux/i386/setegid.c index fcd6cf1827..b8682e3681 100644 --- a/sysdeps/unix/sysv/linux/i386/setegid.c +++ b/sysdeps/unix/sysv/linux/i386/setegid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995-1998, 2000, 2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1995-1998,2000,2002,2003,2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -22,6 +22,7 @@ #include <sysdep.h> #include "kernel-features.h" +#include <pthread-functions.h> #ifdef __NR_setresgid @@ -32,10 +33,17 @@ int setegid (gid) gid_t gid; { + int result; + + if (gid == (gid_t) ~0) + { + __set_errno (EINVAL); + return -1; + } + #if __ASSUME_32BITUIDS > 0 - return INLINE_SYSCALL (setresgid32, 3, -1, gid, -1); + result = INLINE_SYSCALL (setresgid32, 3, -1, gid, -1); #else - int result; /* First try the syscall. */ # ifdef __NR_setresgid result = __setresgid (-1, gid, -1); @@ -49,8 +57,20 @@ setegid (gid) equal to the real user ID, making it impossible to switch back. */ # endif result = __setregid (-1, gid); +#endif - return result; +#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD + if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL) + { + struct xid_command cmd; + cmd.syscall_no = __NR_setresgid32; + cmd.id[0] = -1; + cmd.id[1] = gid; + cmd.id[2] = -1; + __libc_pthread_functions.ptr__nptl_setxid (&cmd); + } #endif + + return result; } libc_hidden_def (setegid) diff --git a/sysdeps/unix/sysv/linux/i386/seteuid.c b/sysdeps/unix/sysv/linux/i386/seteuid.c index 87e348a646..0abdac832f 100644 --- a/sysdeps/unix/sysv/linux/i386/seteuid.c +++ b/sysdeps/unix/sysv/linux/i386/seteuid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1998, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -22,6 +22,7 @@ #include <sysdep.h> #include "kernel-features.h" +#include <pthread-functions.h> #ifdef __NR_setresuid @@ -31,10 +32,17 @@ extern int __setresuid (uid_t ruid, uid_t euid, uid_t suid); int seteuid (uid_t uid) { + int result; + + if (uid == (uid_t) ~0) + { + __set_errno (EINVAL); + return -1; + } + #if __ASSUME_32BITUIDS > 0 - return INLINE_SYSCALL (setresuid32, 3, -1, uid, -1); + result = INLINE_SYSCALL (setresuid32, 3, -1, uid, -1); #else - int result; /* First try the syscall. */ # ifdef __NR_setresuid result = __setresuid (-1, uid, -1); @@ -48,8 +56,20 @@ seteuid (uid_t uid) equal to the real user ID, making it impossible to switch back. */ # endif result = __setreuid (-1, uid); +#endif - return result; +#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD + if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL) + { + struct xid_command cmd; + cmd.syscall_no = __NR_setresuid32; + cmd.id[0] = -1; + cmd.id[1] = uid; + cmd.id[2] = -1; + __libc_pthread_functions.ptr__nptl_setxid (&cmd); + } #endif + + return result; } libc_hidden_def (seteuid) diff --git a/sysdeps/unix/sysv/linux/i386/setgid.c b/sysdeps/unix/sysv/linux/i386/setgid.c index 1fdca94064..17bfc3e58a 100644 --- a/sysdeps/unix/sysv/linux/i386/setgid.c +++ b/sysdeps/unix/sysv/linux/i386/setgid.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1998, 2000, 2003, 2004 + Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -26,6 +27,8 @@ #include <linux/posix_types.h> #include "kernel-features.h" +#include <pthread-functions.h> + #ifdef __NR_setgid32 # if __ASSUME_32BITUIDS == 0 @@ -38,18 +41,21 @@ extern int __libc_missing_32bit_uids; int __setgid (gid_t gid) { + int result; + #if __ASSUME_32BITUIDS > 0 - return INLINE_SYSCALL (setgid32, 1, gid); + result = INLINE_SYSCALL (setgid32, 1, gid); #else # ifdef __NR_setgid32 if (__libc_missing_32bit_uids <= 0) { - int result; int saved_errno = errno; result = INLINE_SYSCALL (setgid32, 1, gid); - if (result == 0 || errno != ENOSYS) + if (result == 0) + goto out; + if (errno != ENOSYS) return result; __set_errno (saved_errno); @@ -64,7 +70,24 @@ __setgid (gid_t gid) return -1; } - return INLINE_SYSCALL (setgid, 1, gid); + result = INLINE_SYSCALL (setgid, 1, gid); +# ifdef __NR_setgid32 + out: +# endif +#endif + +#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD + if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL) + { + struct xid_command cmd; + cmd.syscall_no = __NR_setgid32; + cmd.id[0] = gid; + __libc_pthread_functions.ptr__nptl_setxid (&cmd); + } #endif + + return result; } +#ifndef __setgid weak_alias (__setgid, setgid) +#endif diff --git a/sysdeps/unix/sysv/linux/i386/setregid.c b/sysdeps/unix/sysv/linux/i386/setregid.c index be1d73cb99..f883497fae 100644 --- a/sysdeps/unix/sysv/linux/i386/setregid.c +++ b/sysdeps/unix/sysv/linux/i386/setregid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -25,6 +25,7 @@ #include <linux/posix_types.h> #include "kernel-features.h" +#include <pthread-functions.h> #ifdef __NR_setregid32 @@ -38,18 +39,21 @@ extern int __libc_missing_32bit_uids; int __setregid (gid_t rgid, gid_t egid) { + int result; + #if __ASSUME_32BITUIDS > 0 - return INLINE_SYSCALL (setregid32, 2, rgid, egid); + result = INLINE_SYSCALL (setregid32, 2, rgid, egid); #else # ifdef __NR_setregid32 if (__libc_missing_32bit_uids <= 0) { - int result; int saved_errno = errno; result = INLINE_SYSCALL (setregid32, 2, rgid, egid); - if (result == 0 || errno != ENOSYS) + if (result == 0) + goto out; + if (errno != ENOSYS) return result; __set_errno (saved_errno); @@ -63,7 +67,25 @@ __setregid (gid_t rgid, gid_t egid) return -1; } - return INLINE_SYSCALL (setregid, 2, rgid, egid); + result = INLINE_SYSCALL (setregid, 2, rgid, egid); +# ifdef __NR_setregid32 + out: +# endif #endif + +#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD + if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL) + { + struct xid_command cmd; + cmd.syscall_no = __NR_setregid32; + cmd.id[0] = rgid; + cmd.id[1] = egid; + __libc_pthread_functions.ptr__nptl_setxid (&cmd); + } +#endif + + return result; } +#ifndef __setregid weak_alias (__setregid, setregid) +#endif diff --git a/sysdeps/unix/sysv/linux/i386/setresgid.c b/sysdeps/unix/sysv/linux/i386/setresgid.c index 414a58b07e..ee782e49f3 100644 --- a/sysdeps/unix/sysv/linux/i386/setresgid.c +++ b/sysdeps/unix/sysv/linux/i386/setresgid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1998, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -25,6 +25,8 @@ #include <sysdep.h> #include <sys/syscall.h> #include "kernel-features.h" +#include <pthread-functions.h> + #ifdef __NR_setresgid @@ -39,17 +41,20 @@ extern int __libc_missing_32bit_uids; int __setresgid (gid_t rgid, gid_t egid, gid_t sgid) { + int result; + # if __ASSUME_32BITUIDS > 0 - return INLINE_SYSCALL (setresgid32, 3, rgid, egid, sgid); + result = INLINE_SYSCALL (setresgid32, 3, rgid, egid, sgid); # else # ifdef __NR_setresgid32 if (__libc_missing_32bit_uids <= 0) { - int result; int saved_errno = errno; result = INLINE_SYSCALL (setresgid32, 3, rgid, egid, sgid); - if (result == 0 || errno != ENOSYS) + if (result == 0) + goto out; + if (errno != ENOSYS) return result; __set_errno (saved_errno); @@ -65,11 +70,30 @@ __setresgid (gid_t rgid, gid_t egid, gid_t sgid) return -1; } - return INLINE_SYSCALL (setresgid, 3, rgid, egid, sgid); + result = INLINE_SYSCALL (setresgid, 3, rgid, egid, sgid); +# ifdef __NR_setresgid32 + out: +# endif # endif + +#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD + if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL) + { + struct xid_command cmd; + cmd.syscall_no = __NR_setresgid32; + cmd.id[0] = rgid; + cmd.id[1] = egid; + cmd.id[2] = sgid; + __libc_pthread_functions.ptr__nptl_setxid (&cmd); + } +#endif + + return result; } libc_hidden_def (__setresgid) +#ifndef __setresgid weak_alias (__setresgid, setresgid) +#endif #else diff --git a/sysdeps/unix/sysv/linux/i386/setresuid.c b/sysdeps/unix/sysv/linux/i386/setresuid.c index 537fb7995b..66e5a1c0c1 100644 --- a/sysdeps/unix/sysv/linux/i386/setresuid.c +++ b/sysdeps/unix/sysv/linux/i386/setresuid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1998, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -25,6 +25,8 @@ #include <sysdep.h> #include <sys/syscall.h> #include "kernel-features.h" +#include <pthread-functions.h> + #ifdef __NR_setresuid @@ -39,17 +41,20 @@ extern int __libc_missing_32bit_uids; int __setresuid (uid_t ruid, uid_t euid, uid_t suid) { + int result; + # if __ASSUME_32BITUIDS > 0 - return INLINE_SYSCALL (setresuid32, 3, ruid, euid, suid); + result = INLINE_SYSCALL (setresuid32, 3, ruid, euid, suid); # else # ifdef __NR_setresuid32 if (__libc_missing_32bit_uids <= 0) { - int result; int saved_errno = errno; result = INLINE_SYSCALL (setresuid32, 3, ruid, euid, suid); - if (result == 0 || errno != ENOSYS) + if (result == 0) + goto out; + if (errno != ENOSYS) return result; __set_errno (saved_errno); @@ -65,11 +70,30 @@ __setresuid (uid_t ruid, uid_t euid, uid_t suid) return -1; } - return INLINE_SYSCALL (setresuid, 3, ruid, euid, suid); + result = INLINE_SYSCALL (setresuid, 3, ruid, euid, suid); +# ifdef __NR_setresuid32 + out: +# endif # endif + +#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD + if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL) + { + struct xid_command cmd; + cmd.syscall_no = __NR_setresuid32; + cmd.id[0] = ruid; + cmd.id[1] = euid; + cmd.id[2] = suid; + __libc_pthread_functions.ptr__nptl_setxid (&cmd); + } +#endif + + return result; } libc_hidden_def (__setresuid) +#ifndef __setresuid weak_alias (__setresuid, setresuid) +#endif #else diff --git a/sysdeps/unix/sysv/linux/i386/setreuid.c b/sysdeps/unix/sysv/linux/i386/setreuid.c index 2aadf7437f..1e1bfcf0d4 100644 --- a/sysdeps/unix/sysv/linux/i386/setreuid.c +++ b/sysdeps/unix/sysv/linux/i386/setreuid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -25,6 +25,7 @@ #include <linux/posix_types.h> #include "kernel-features.h" +#include <pthread-functions.h> #ifdef __NR_setreuid32 @@ -38,18 +39,21 @@ extern int __libc_missing_32bit_uids; int __setreuid (uid_t ruid, uid_t euid) { + int result; + #if __ASSUME_32BITUIDS > 0 - return INLINE_SYSCALL (setreuid32, 2, ruid, euid); + result = INLINE_SYSCALL (setreuid32, 2, ruid, euid); #else # ifdef __NR_setreuid32 if (__libc_missing_32bit_uids <= 0) { - int result; int saved_errno = errno; result = INLINE_SYSCALL (setreuid32, 2, ruid, euid); - if (result == 0 || errno != ENOSYS) + if (result == 0) + goto out; + if (errno != ENOSYS) return result; __set_errno (saved_errno); @@ -63,7 +67,25 @@ __setreuid (uid_t ruid, uid_t euid) return -1; } - return INLINE_SYSCALL (setreuid, 2, ruid, euid); + result = INLINE_SYSCALL (setreuid, 2, ruid, euid); +# ifdef __NR_setreuid32 + out: +# endif #endif + +#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD + if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL) + { + struct xid_command cmd; + cmd.syscall_no = __NR_setreuid32; + cmd.id[0] = ruid; + cmd.id[1] = euid; + __libc_pthread_functions.ptr__nptl_setxid (&cmd); + } +#endif + + return result; } +#ifndef __setreuid weak_alias (__setreuid, setreuid) +#endif diff --git a/sysdeps/unix/sysv/linux/i386/setuid.c b/sysdeps/unix/sysv/linux/i386/setuid.c index 69bf42596f..a11fb7f60c 100644 --- a/sysdeps/unix/sysv/linux/i386/setuid.c +++ b/sysdeps/unix/sysv/linux/i386/setuid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -25,6 +25,8 @@ #include <linux/posix_types.h> #include "kernel-features.h" +#include <pthread-functions.h> + #ifdef __NR_setuid32 # if __ASSUME_32BITUIDS == 0 @@ -37,8 +39,10 @@ extern int __libc_missing_32bit_uids; int __setuid (uid_t uid) { -#if __ASSUME_32BITUIDS > 0 - return INLINE_SYSCALL (setuid32, 1, uid); + int result; + +#if __ASSUME_32BITUIDS > 0 && defined __NR_setuid32 + result = INLINE_SYSCALL (setuid32, 1, uid); #else # ifdef __NR_setuid32 if (__libc_missing_32bit_uids <= 0) @@ -47,7 +51,9 @@ __setuid (uid_t uid) int saved_errno = errno; result = INLINE_SYSCALL (setuid32, 1, uid); - if (result == 0 || errno != ENOSYS) + if (result == 0) + goto out; + if (errno != ENOSYS) return result; __set_errno (saved_errno); @@ -62,7 +68,24 @@ __setuid (uid_t uid) return -1; } - return INLINE_SYSCALL (setuid, 1, uid); + result = INLINE_SYSCALL (setuid, 1, uid); +# ifdef __NR_setuid32 + out: +# endif +#endif + +#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD + if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL) + { + struct xid_command cmd; + cmd.syscall_no = __NR_setuid32; + cmd.id[0] = uid; + __libc_pthread_functions.ptr__nptl_setxid (&cmd); + } #endif + + return result; } +#ifndef __setuid weak_alias (__setuid, setuid) +#endif diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h index 79ad72abff..8845e46157 100644 --- a/sysdeps/unix/sysv/linux/i386/sysdep.h +++ b/sysdeps/unix/sysv/linux/i386/sysdep.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1992,1993,1995-2000,2002,2003 Free Software Foundation, Inc. +/* Copyright (C) 1992,1993,1995-2000,2002,2003,2004 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper, <drepper@gnu.org>, August 1995. @@ -343,7 +344,10 @@ asm (".L__X'%ebx = 1\n\t" /* Define a macro which expands inline into the wrapper code for a system call. This use is for internal calls that do not need to handle errors normally. It will never touch errno. This returns just what the kernel - gave back. */ + gave back. + + The _NCS variant allows non-constant syscall numbers but it is not + possible to use more than four parameters. */ #undef INTERNAL_SYSCALL #ifdef I386_USE_SYSENTER # ifdef SHARED @@ -360,6 +364,18 @@ asm (".L__X'%ebx = 1\n\t" : "i" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo)) \ ASMFMT_##nr(args) : "memory", "cc"); \ (int) resultvar; }) +# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ + ({ \ + register unsigned int resultvar; \ + EXTRAVAR_##nr \ + asm volatile ( \ + LOADARGS_##nr \ + "call *%%gs:%P2\n\t" \ + RESTOREARGS_##nr \ + : "=a" (resultvar) \ + : "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \ + ASMFMT_##nr(args) : "memory", "cc"); \ + (int) resultvar; }) # else # define INTERNAL_SYSCALL(name, err, nr, args...) \ ({ \ @@ -373,6 +389,17 @@ asm (".L__X'%ebx = 1\n\t" : "=a" (resultvar) \ : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \ (int) resultvar; }) +# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ + ({ \ + register unsigned int resultvar; \ + EXTRAVAR_##nr \ + asm volatile ( \ + LOADARGS_##nr \ + "call *_dl_sysinfo\n\t" \ + RESTOREARGS_##nr \ + : "=a" (resultvar) \ + : "0" (name) ASMFMT_##nr(args) : "memory", "cc"); \ + (int) resultvar; }) # endif #else # define INTERNAL_SYSCALL(name, err, nr, args...) \ @@ -387,6 +414,17 @@ asm (".L__X'%ebx = 1\n\t" : "=a" (resultvar) \ : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \ (int) resultvar; }) +# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ + ({ \ + register unsigned int resultvar; \ + EXTRAVAR_##nr \ + asm volatile ( \ + LOADARGS_##nr \ + "int $0x80\n\t" \ + RESTOREARGS_##nr \ + : "=a" (resultvar) \ + : "0" (name) ASMFMT_##nr(args) : "memory", "cc"); \ + (int) resultvar; }) #endif #undef INTERNAL_SYSCALL_DECL diff --git a/sysdeps/unix/sysv/linux/ia64/sysdep.h b/sysdeps/unix/sysv/linux/ia64/sysdep.h index 0868ad50ef..0ebfc56fdd 100644 --- a/sysdeps/unix/sysv/linux/ia64/sysdep.h +++ b/sysdeps/unix/sysv/linux/ia64/sysdep.h @@ -199,33 +199,33 @@ #ifdef IA64_USE_NEW_STUB -#define DO_INLINE_SYSCALL(name, nr, args...) \ - LOAD_ARGS_##nr (args) \ - register long _r8 __asm ("r8"); \ - register long _r10 __asm ("r10"); \ - register long _r15 __asm ("r15") = __NR_##name; \ - register void *_b7 __asm ("b7") = ((tcbhead_t *) __thread_self)->private; \ - long _retval; \ - LOAD_REGS_##nr \ - /* \ - * Don't specify any unwind info here. We mark ar.pfs as \ - * clobbered. This will force the compiler to save ar.pfs \ - * somewhere and emit appropriate unwind info for that save. \ - */ \ - __asm __volatile ("br.call.sptk.many b6=%0;;\n" \ - : "=b"(_b7), "=r" (_r8), "=r" (_r10), "=r" (_r15) \ - ASM_OUTARGS_##nr \ - : "0" (_b7), "3" (_r15) ASM_ARGS_##nr \ - : "memory", "ar.pfs" ASM_CLOBBERS_##nr); \ +# define DO_INLINE_SYSCALL(name, nr, args...) \ + LOAD_ARGS_##nr (args) \ + register long _r8 __asm ("r8"); \ + register long _r10 __asm ("r10"); \ + register long _r15 __asm ("r15") = name; \ + register void *_b7 __asm ("b7") = ((tcbhead_t *) __thread_self)->private; \ + long _retval; \ + LOAD_REGS_##nr \ + /* \ + * Don't specify any unwind info here. We mark ar.pfs as \ + * clobbered. This will force the compiler to save ar.pfs \ + * somewhere and emit appropriate unwind info for that save. \ + */ \ + __asm __volatile ("br.call.sptk.many b6=%0;;\n" \ + : "=b"(_b7), "=r" (_r8), "=r" (_r10), "=r" (_r15) \ + ASM_OUTARGS_##nr \ + : "0" (_b7), "3" (_r15) ASM_ARGS_##nr \ + : "memory", "ar.pfs" ASM_CLOBBERS_##nr); \ _retval = _r8; #else /* !IA64_USE_NEW_STUB */ -#define DO_INLINE_SYSCALL(name, nr, args...) \ +# define DO_INLINE_SYSCALL(name, nr, args...) \ LOAD_ARGS_##nr (args) \ register long _r8 asm ("r8"); \ register long _r10 asm ("r10"); \ - register long _r15 asm ("r15") = __NR_##name; \ + register long _r15 asm ("r15") = name; \ long _retval; \ LOAD_REGS_##nr \ __asm __volatile (BREAK_INSN (__BREAK_SYSCALL) \ @@ -240,7 +240,7 @@ #undef INLINE_SYSCALL #define INLINE_SYSCALL(name, nr, args...) \ ({ \ - DO_INLINE_SYSCALL(name, nr, args) \ + DO_INLINE_SYSCALL(__NR_##name, nr, args) \ if (_r10 == -1) \ { \ __set_errno (_retval); \ @@ -252,11 +252,13 @@ #define INTERNAL_SYSCALL_DECL(err) long int err #undef INTERNAL_SYSCALL -#define INTERNAL_SYSCALL(name, err, nr, args...) \ +#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ ({ \ DO_INLINE_SYSCALL(name, nr, args) \ err = _r10; \ _retval; }) +#define INTERNAL_SYSCALL(name, err, nr, args...) \ + INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args) #undef INTERNAL_SYSCALL_ERROR_P #define INTERNAL_SYSCALL_ERROR_P(val, err) (err == -1) diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h index 269b4dd531..2ee3e60229 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h @@ -79,7 +79,7 @@ # define INTERNAL_SYSCALL_DECL(err) long int err # undef INTERNAL_SYSCALL -# define INTERNAL_SYSCALL(name, err, nr, args...) \ +# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ ({ \ register long int r0 __asm__ ("r0"); \ register long int r3 __asm__ ("r3"); \ @@ -104,6 +104,8 @@ err = r0; \ (int) r3; \ }) +# define INTERNAL_SYSCALL(name, err, nr, args...) \ + INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args) # undef INTERNAL_SYSCALL_ERROR_P # define INTERNAL_SYSCALL_ERROR_P(val, err) \ @@ -113,48 +115,48 @@ # define INTERNAL_SYSCALL_ERRNO(val, err) (val) # define LOADARGS_0(name, dummy) \ - r0 = __NR_##name + r0 = name # define LOADARGS_1(name, __arg1) \ long int arg1 = (long int) (__arg1); \ LOADARGS_0(name, 0); \ - extern void __illegally_sized_syscall_##name##_arg1 (void); \ + extern void __illegally_sized_syscall_arg1 (void); \ if (__builtin_classify_type (__arg1) != 5 && sizeof (__arg1) > 4) \ - __illegally_sized_syscall_##name##_arg1 (); \ + __illegally_sized_syscall_arg1 (); \ r3 = arg1 # define LOADARGS_2(name, __arg1, __arg2) \ long int arg2 = (long int) (__arg2); \ LOADARGS_1(name, __arg1); \ - extern void __illegally_sized_syscall_##name##_arg2 (void); \ + extern void __illegally_sized_syscall_arg2 (void); \ if (__builtin_classify_type (__arg2) != 5 && sizeof (__arg2) > 4) \ - __illegally_sized_syscall_##name##_arg2 (); \ + __illegally_sized_syscall_arg2 (); \ r4 = arg2 # define LOADARGS_3(name, __arg1, __arg2, __arg3) \ long int arg3 = (long int) (__arg3); \ LOADARGS_2(name, __arg1, __arg2); \ - extern void __illegally_sized_syscall_##name##_arg3 (void); \ + extern void __illegally_sized_syscall_arg3 (void); \ if (__builtin_classify_type (__arg3) != 5 && sizeof (__arg3) > 4) \ - __illegally_sized_syscall_##name##_arg3 (); \ + __illegally_sized_syscall_arg3 (); \ r5 = arg3 # define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \ long int arg4 = (long int) (__arg4); \ LOADARGS_3(name, __arg1, __arg2, __arg3); \ - extern void __illegally_sized_syscall_##name##_arg4 (void); \ + extern void __illegally_sized_syscall_arg4 (void); \ if (__builtin_classify_type (__arg4) != 5 && sizeof (__arg4) > 4) \ - __illegally_sized_syscall_##name##_arg4 (); \ + __illegally_sized_syscall_arg4 (); \ r6 = arg4 # define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \ long int arg5 = (long int) (__arg5); \ LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \ - extern void __illegally_sized_syscall_##name##_arg5 (void); \ + extern void __illegally_sized_syscall_arg5 (void); \ if (__builtin_classify_type (__arg5) != 5 && sizeof (__arg5) > 4) \ - __illegally_sized_syscall_##name##_arg5 (); \ + __illegally_sized_syscall_arg5 (); \ r7 = arg5 # define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \ long int arg6 = (long int) (__arg6); \ LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \ - extern void __illegally_sized_syscall_##name##_arg6 (void); \ + extern void __illegally_sized_syscall_arg6 (void); \ if (__builtin_classify_type (__arg6) != 5 && sizeof (__arg6) > 4) \ - __illegally_sized_syscall_##name##_arg6 (); \ + __illegally_sized_syscall_arg6 (); \ r8 = arg6 # define ASM_INPUT_0 "0" (r0) diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h index 2e1adccd5d..38a376fa90 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h @@ -91,7 +91,7 @@ the negation of the return value in the kernel gets reverted. */ #undef INTERNAL_SYSCALL -#define INTERNAL_SYSCALL(name, err, nr, args...) \ +#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ ({ \ register long int r0 __asm__ ("r0"); \ register long int r3 __asm__ ("r3"); \ @@ -114,6 +114,8 @@ err = r0; \ (int) r3; \ }) +#define INTERNAL_SYSCALL(name, err, nr, args...) \ + INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args) #undef INTERNAL_SYSCALL_DECL #define INTERNAL_SYSCALL_DECL(err) long int err @@ -126,48 +128,48 @@ #define INTERNAL_SYSCALL_ERRNO(val, err) (val) #define LOADARGS_0(name, dummy) \ - r0 = __NR_##name + r0 = name #define LOADARGS_1(name, __arg1) \ long int arg1 = (long int) (__arg1); \ LOADARGS_0(name, 0); \ - extern void __illegally_sized_syscall_##name##_arg1 (void); \ + extern void __illegally_sized_syscall_arg1 (void); \ if (__builtin_classify_type (__arg1) != 5 && sizeof (__arg1) > 8) \ - __illegally_sized_syscall_##name##_arg1 (); \ + __illegally_sized_syscall_arg1 (); \ r3 = arg1 #define LOADARGS_2(name, __arg1, __arg2) \ long int arg2 = (long int) (__arg2); \ LOADARGS_1(name, __arg1); \ - extern void __illegally_sized_syscall_##name##_arg2 (void); \ + extern void __illegally_sized_syscall_arg2 (void); \ if (__builtin_classify_type (__arg2) != 5 && sizeof (__arg2) > 8) \ - __illegally_sized_syscall_##name##_arg2 (); \ + __illegally_sized_syscall_arg2 (); \ r4 = arg2 #define LOADARGS_3(name, __arg1, __arg2, __arg3) \ long int arg3 = (long int) (__arg3); \ LOADARGS_2(name, __arg1, __arg2); \ - extern void __illegally_sized_syscall_##name##_arg3 (void); \ + extern void __illegally_sized_syscall_arg3 (void); \ if (__builtin_classify_type (__arg3) != 5 && sizeof (__arg3) > 8) \ - __illegally_sized_syscall_##name##_arg3 (); \ + __illegally_sized_syscall_arg3 (); \ r5 = arg3 #define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \ long int arg4 = (long int) (__arg4); \ LOADARGS_3(name, __arg1, __arg2, __arg3); \ - extern void __illegally_sized_syscall_##name##_arg4 (void); \ + extern void __illegally_sized_syscall_arg4 (void); \ if (__builtin_classify_type (__arg4) != 5 && sizeof (__arg4) > 8) \ - __illegally_sized_syscall_##name##_arg4 (); \ + __illegally_sized_syscall_arg4 (); \ r6 = arg4 #define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \ long int arg5 = (long int) (__arg5); \ LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \ - extern void __illegally_sized_syscall_##name##_arg5 (void); \ + extern void __illegally_sized_syscall_arg5 (void); \ if (__builtin_classify_type (__arg5) != 5 && sizeof (__arg5) > 8) \ - __illegally_sized_syscall_##name##_arg5 (); \ + __illegally_sized_syscall_arg5 (); \ r7 = arg5 #define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \ long int arg6 = (long int) (__arg6); \ LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \ - extern void __illegally_sized_syscall_##name##_arg6 (void); \ + extern void __illegally_sized_syscall_arg6 (void); \ if (__builtin_classify_type (__arg6) != 5 && sizeof (__arg6) > 8) \ - __illegally_sized_syscall_##name##_arg6 (); \ + __illegally_sized_syscall_arg6 (); \ r8 = arg6 #define ASM_INPUT_0 "0" (r0) diff --git a/sysdeps/unix/sysv/linux/setegid.c b/sysdeps/unix/sysv/linux/setegid.c index 34e64a3dee..33e91c773a 100644 --- a/sysdeps/unix/sysv/linux/setegid.c +++ b/sysdeps/unix/sysv/linux/setegid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1998, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -23,6 +23,8 @@ #include <sysdep.h> #include "kernel-features.h" +#include <pthread-functions.h> + #if defined __NR_setresgid || __ASSUME_SETRESGID_SYSCALL > 0 @@ -40,10 +42,10 @@ setegid (gid_t gid) } # if __ASSUME_32BITUIDS > 0 && defined __NR_setresgid32 - return INLINE_SYSCALL (setresgid32, 3, -1, gid, -1); + result = INLINE_SYSCALL (setresgid32, 3, -1, gid, -1); # else /* First try the syscall. */ - result = __setresgid (-1, gid, -1); + result = INLINE_SYSCALL (setresgid, 3, -1, gid, -1); # if __ASSUME_SETRESGID_SYSCALL == 0 if (result == -1 && errno == ENOSYS) /* No system call available. Use emulation. This may not work @@ -51,11 +53,29 @@ setegid (gid_t gid) equal to the real group ID, making it impossible to switch back. */ result = __setregid (-1, gid); # endif +# endif - return result; +#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD + if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL) + { + struct xid_command cmd; +# ifdef __NR_setresgid32 + cmd.syscall_no = __NR_setresgid32; +# else + cmd.syscall_no = __NR_setresgid; # endif + cmd.id[0] = -1; + cmd.id[1] = gid; + cmd.id[2] = -1; + __libc_pthread_functions.ptr__nptl_setxid (&cmd); + } +#endif + + return result; } +#ifndef setegid libc_hidden_def (setegid) +#endif #else # include <sysdeps/unix/bsd/setegid.c> #endif diff --git a/sysdeps/unix/sysv/linux/seteuid.c b/sysdeps/unix/sysv/linux/seteuid.c index a1832d64bc..da03a1e6ef 100644 --- a/sysdeps/unix/sysv/linux/seteuid.c +++ b/sysdeps/unix/sysv/linux/seteuid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1998, 1999, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -23,6 +23,8 @@ #include <sysdep.h> #include "kernel-features.h" +#include <pthread-functions.h> + #if defined __NR_setresuid || __ASSUME_SETRESUID_SYSCALL > 0 @@ -40,22 +42,40 @@ seteuid (uid_t uid) } # if __ASSUME_32BITUIDS > 0 && defined __NR_setresuid32 - return INLINE_SYSCALL (setresuid32, 3, -1, uid, -1); + result = INLINE_SYSCALL (setresuid32, 3, -1, uid, -1); # else /* First try the syscall. */ - result = __setresuid (-1, uid, -1); -# if __ASSUME_SETRESUID_SYSCALL == 0 + result = INLINE_SYSCALL (setresuid, 3, -1, uid, -1); +# if __ASSUME_SETRESUID_SYSCALL == 0 if (result == -1 && errno == ENOSYS) /* No system call available. Use emulation. This may not work since `setreuid' also sets the saved user ID when UID is not equal to the real user ID, making it impossible to switch back. */ result = __setreuid (-1, uid); +# endif # endif - return result; +#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD + if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL) + { + struct xid_command cmd; +# ifdef __NR_setresuid32 + cmd.syscall_no = __NR_setresuid32; +# else + cmd.syscall_no = __NR_setresuid; # endif + cmd.id[0] = -1; + cmd.id[1] = uid; + cmd.id[2] = -1; + __libc_pthread_functions.ptr__nptl_setxid (&cmd); + } +#endif + + return result; } +#ifndef seteuid libc_hidden_def (seteuid) +#endif #else # include <sysdeps/unix/bsd/seteuid.c> #endif diff --git a/sysdeps/unix/sysv/linux/setgid.c b/sysdeps/unix/sysv/linux/setgid.c new file mode 100644 index 0000000000..dae642abb5 --- /dev/null +++ b/sysdeps/unix/sysv/linux/setgid.c @@ -0,0 +1,53 @@ +/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +#include <sysdep.h> +#include <sys/syscall.h> + +#include <linux/posix_types.h> +#include "kernel-features.h" +#include <pthread-functions.h> + + + +int +__setgid (gid_t gid) +{ + int result; + + result = INLINE_SYSCALL (setgid, 1, gid); + +#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD + if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL) + { + struct xid_command cmd; + cmd.syscall_no = __NR_setgid; + cmd.id[0] = gid; + __libc_pthread_functions.ptr__nptl_setxid (&cmd); + } +#endif + + return result; +} +#ifndef __setgid +weak_alias (__setgid, setgid) +#endif diff --git a/sysdeps/unix/sysv/linux/setregid.c b/sysdeps/unix/sysv/linux/setregid.c new file mode 100644 index 0000000000..1d539260ed --- /dev/null +++ b/sysdeps/unix/sysv/linux/setregid.c @@ -0,0 +1,53 @@ +/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +#include <sysdep.h> +#include <sys/syscall.h> + +#include <linux/posix_types.h> +#include "kernel-features.h" +#include <pthread-functions.h> + + +int +__setregid (gid_t rgid, gid_t egid) +{ + int result; + + result = INLINE_SYSCALL (setregid, 2, rgid, egid); + +#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD + if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL) + { + struct xid_command cmd; + cmd.syscall_no = __NR_setregid; + cmd.id[0] = rgid; + cmd.id[1] = egid; + __libc_pthread_functions.ptr__nptl_setxid (&cmd); + } +#endif + + return result; +} +#ifndef __setregid +weak_alias (__setregid, setregid) +#endif diff --git a/sysdeps/unix/sysv/linux/setresgid.c b/sysdeps/unix/sysv/linux/setresgid.c new file mode 100644 index 0000000000..ae61d42e6b --- /dev/null +++ b/sysdeps/unix/sysv/linux/setresgid.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +#include <sysdep.h> +#include <sys/syscall.h> + +#include <linux/posix_types.h> +#include "kernel-features.h" +#include <pthread-functions.h> + + +int +__setresgid (gid_t rgid, gid_t egid, gid_t sgid) +{ + int result; + + result = INLINE_SYSCALL (setresgid, 3, rgid, egid, sgid); + +#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD + if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL) + { + struct xid_command cmd; + cmd.syscall_no = __NR_setresgid; + cmd.id[0] = rgid; + cmd.id[1] = egid; + cmd.id[2] = sgid; + __libc_pthread_functions.ptr__nptl_setxid (&cmd); + } +#endif + + return result; +} +#ifndef __setresgid +weak_alias (__setresgid, setresgid) +#endif diff --git a/sysdeps/unix/sysv/linux/setresuid.c b/sysdeps/unix/sysv/linux/setresuid.c new file mode 100644 index 0000000000..962d944aa4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/setresuid.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +#include <sysdep.h> +#include <sys/syscall.h> + +#include <linux/posix_types.h> +#include "kernel-features.h" +#include <pthread-functions.h> + + +int +__setresuid (uid_t ruid, uid_t euid, uid_t suid) +{ + int result; + + result = INLINE_SYSCALL (setresuid, 3, ruid, euid, suid); + +#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD + if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL) + { + struct xid_command cmd; + cmd.syscall_no = __NR_setresuid; + cmd.id[0] = ruid; + cmd.id[1] = euid; + cmd.id[2] = suid; + __libc_pthread_functions.ptr__nptl_setxid (&cmd); + } +#endif + + return result; +} +#ifndef __setresuid +weak_alias (__setresuid, setresuid) +#endif diff --git a/sysdeps/unix/sysv/linux/setreuid.c b/sysdeps/unix/sysv/linux/setreuid.c new file mode 100644 index 0000000000..c9d841eca0 --- /dev/null +++ b/sysdeps/unix/sysv/linux/setreuid.c @@ -0,0 +1,53 @@ +/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +#include <sysdep.h> +#include <sys/syscall.h> + +#include <linux/posix_types.h> +#include "kernel-features.h" +#include <pthread-functions.h> + + +int +__setreuid (uid_t ruid, uid_t euid) +{ + int result; + + result = INLINE_SYSCALL (setreuid, 2, ruid, euid); + +#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD + if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL) + { + struct xid_command cmd; + cmd.syscall_no = __NR_setreuid; + cmd.id[0] = ruid; + cmd.id[1] = euid; + __libc_pthread_functions.ptr__nptl_setxid (&cmd); + } +#endif + + return result; +} +#ifndef __setreuid +weak_alias (__setreuid, setreuid) +#endif diff --git a/sysdeps/unix/sysv/linux/setuid.c b/sysdeps/unix/sysv/linux/setuid.c new file mode 100644 index 0000000000..84f35176a1 --- /dev/null +++ b/sysdeps/unix/sysv/linux/setuid.c @@ -0,0 +1,52 @@ +/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +#include <sysdep.h> +#include <sys/syscall.h> + +#include <linux/posix_types.h> +#include "kernel-features.h" +#include <pthread-functions.h> + + +int +__setuid (uid_t uid) +{ + int result; + + result = INLINE_SYSCALL (setuid, 1, uid); + +#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD + if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL) + { + struct xid_command cmd; + cmd.syscall_no = __NR_setuid; + cmd.id[0] = uid; + __libc_pthread_functions.ptr__nptl_setxid (&cmd); + } +#endif + + return result; +} +#ifndef __setuid +weak_alias (__setuid, setuid) +#endif diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/setegid.c b/sysdeps/unix/sysv/linux/sparc/sparc32/setegid.c index 96f807484d..2e3a54c893 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/setegid.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/setegid.c @@ -1,54 +1 @@ -/* Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <errno.h> -#include <sys/syscall.h> -#include <sys/types.h> -#include <unistd.h> - -#ifdef __NR_setresgid32 - -extern int __setresgid (gid_t rgid, gid_t egid, gid_t sgid); - -int -setegid (gid_t gid) -{ - int result; - - if (gid == (gid_t) ~0) - { - __set_errno (EINVAL); - return -1; - } - - /* First try the syscall. */ - result = __setresgid (-1, gid, -1); -# if __ASSUME_SETRESGID_SYSCALL == 0 - if (result == -1 && errno == ENOSYS) - /* No system call available. Use emulation. This may not work - since `setregid' also sets the saved group ID when GID is not - equal to the real group ID, making it impossible to switch back. */ - result = __setregid (-1, gid); -# endif - - return result; -} -libc_hidden_def (setegid) -#else -# include <sysdeps/unix/bsd/setegid.c> -#endif +#include <sysdeps/unix/sysv/linux/i386/setegid.c> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/seteuid.c b/sysdeps/unix/sysv/linux/sparc/sparc32/seteuid.c index 34638ce4be..18e41d08c1 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/seteuid.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/seteuid.c @@ -1,56 +1 @@ -/* Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <errno.h> -#include <sys/syscall.h> -#include <sys/types.h> -#include <unistd.h> - -#include "kernel-features.h" - -#if defined __NR_setresuid32 || __ASSUME_SETRESUID_SYSCALL > 0 - -extern int __setresuid (uid_t ruid, uid_t euid, uid_t suid); - -int -seteuid (uid_t uid) -{ - int result; - - if (uid == (uid_t) ~0) - { - __set_errno (EINVAL); - return -1; - } - - /* First try the syscall. */ - result = __setresuid (-1, uid, -1); -# if __ASSUME_SETRESUID_SYSCALL == 0 - if (result == -1 && errno == ENOSYS) - /* No system call available. Use emulation. This may not work - since `setreuid' also sets the saved user ID when UID is not - equal to the real user ID, making it impossible to switch back. */ - result = __setreuid (-1, uid); -# endif - - return result; -} -libc_hidden_def (seteuid) -#else -# include <sysdeps/unix/bsd/seteuid.c> -#endif +#include <sysdeps/unix/sysv/linux/i386/seteuid.c> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/setresgid.c b/sysdeps/unix/sysv/linux/sparc/sparc32/setresgid.c new file mode 100644 index 0000000000..daca1a4833 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/setresgid.c @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/linux/i386/setresgid.c> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/setresuid.c b/sysdeps/unix/sysv/linux/sparc/sparc32/setresuid.c new file mode 100644 index 0000000000..3aeabe9ad7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/setresuid.c @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/linux/i386/setresuid.c> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list b/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list index 6d8e32f9f7..2bfe376a3b 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list @@ -2,7 +2,5 @@ setrlimit - setrlimit 2 __setrlimit setrlimit getrlimit - getrlimit 2 __getrlimit getrlimit -setresuid - setresuid32 3 __setresuid setresuid -setresgid - setresgid32 3 __setresgid setresgid getresuid - getresuid32 3 getresuid getresgid - getresgid32 3 getresgid diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h index 09f8492cc6..56e4422a73 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h @@ -236,18 +236,19 @@ #undef INTERNAL_SYSCALL_DECL #define INTERNAL_SYSCALL_DECL(err) do { } while (0) -#undef INTERNAL_SYSCALL -#define INTERNAL_SYSCALL(name, err, nr, args...) \ +#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ ({ \ unsigned long resultvar; \ LOAD_ARGS_##nr (args) \ LOAD_REGS_##nr \ asm volatile ( \ - "movq %1, %%rax\n\t" \ "syscall\n\t" \ : "=a" (resultvar) \ - : "i" (__NR_##name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx"); \ + : "0" (name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx"); \ (long) resultvar; }) +#undef INTERNAL_SYSCALL +#define INTERNAL_SYSCALL(name, err, nr, args...) \ + INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args) #undef INTERNAL_SYSCALL_ERROR_P #define INTERNAL_SYSCALL_ERROR_P(val, err) \ |