diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux/i386/setegid.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/setegid.c | 28 |
1 files changed, 24 insertions, 4 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) |