OSDN Git Service

Add extra checks for sigprocmask and rt_sigprocmask syscalls.
authorEric Andersen <andersen@codepoet.org>
Wed, 31 Dec 2003 11:50:08 +0000 (11:50 -0000)
committerEric Andersen <andersen@codepoet.org>
Wed, 31 Dec 2003 11:50:08 +0000 (11:50 -0000)
The rt_sigprocmask syscall has broken error handling in 2.4.x
kernels, while the sigprocmask syscall appears to get things
right.  Regardless we should be extra careful, and add these
checks.

libc/sysdeps/linux/common/syscalls.c

index 3c08a85..1ef7c38 100644 (file)
@@ -1427,11 +1427,29 @@ _syscall3(int, mprotect, void *, addr, size_t, len, int, prot);
 
 //#define __NR_sigprocmask      126
 #ifndef __NR_rt_sigprocmask
-#ifdef L_sigprocmask
+#ifdef L___syscall_sigprocmask
 #include <signal.h>
-#undef sigprocmask
-_syscall3(int, sigprocmask, int, how, const sigset_t *, set, 
+#define __NR___syscall_sigprocmask __NR_sigprocmask
+static inline
+_syscall3(int, __syscall_sigprocmask, int, how, const sigset_t *, set,
                sigset_t *, oldset);
+#undef sigprocmask
+int sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
+{
+       if (set &&
+#if (SIG_BLOCK == 0) && (SIG_UNBLOCK == 1) && (SIG_SETMASK == 2)
+       (((unsigned int) how) > 2)
+#else
+#warning "compile time assumption violated.. slow path..."
+       ((how != SIG_BLOCK) && (how != SIG_UNBLOCK) && (how != SIG_SETMASK))
+#endif
+          )
+       {
+               __set_errno (EINVAL);
+               return -1;
+       }
+       return(__syscall_sigprocmask(how, set, oldset));
+}
 #endif
 #endif
 
@@ -1942,7 +1960,19 @@ _syscall4(int, __rt_sigprocmask, int, how, const sigset_t *, set,
 
 int sigprocmask(int how, const sigset_t *set, sigset_t *oldset) 
 {
-         return __rt_sigprocmask(how, set, oldset, _NSIG/8);
+       if (set &&
+#if (SIG_BLOCK == 0) && (SIG_UNBLOCK == 1) && (SIG_SETMASK == 2)
+                       (((unsigned int) how) > 2)
+#else
+#warning "compile time assumption violated.. slow path..."
+                       ((how != SIG_BLOCK) && (how != SIG_UNBLOCK) && (how != SIG_SETMASK))
+#endif
+          )
+       {
+               __set_errno (EINVAL);
+               return -1;
+       }
+       return __rt_sigprocmask(how, set, oldset, _NSIG/8);
 }
 #endif
 #endif