--- linux-2.2.17/include/linux/sched.h.orig Thu Sep 21 08:05:01 2000 +++ linux/include/linux/sched.h Fri Sep 22 14:39:40 2000 @@ -504,6 +504,8 @@ extern void flush_signal_handlers(struct task_struct *); extern int dequeue_signal(sigset_t *block, siginfo_t *); extern int send_sig_info(int, struct siginfo *info, struct task_struct *); +extern int send_sig_info_nocheck(int, struct siginfo *info, + struct task_struct *); extern int force_sig_info(int, struct siginfo *info, struct task_struct *); extern int kill_pg_info(int, struct siginfo *info, pid_t); extern int kill_sl_info(int, struct siginfo *info, pid_t); --- linux-2.2.17/fs/fcntl.c.orig Thu Sep 21 08:02:32 2000 +++ linux/fs/fcntl.c Fri Sep 22 14:40:04 2000 @@ -256,7 +256,7 @@ si.si_pid = pid; si.si_uid = uid; si.si_fd = fa->fa_fd; - if (!send_sig_info(fown->signum, &si, p)) + if (!send_sig_info_nocheck(fown->signum, &si, p)) break; /* fall-through: fall back on the old plain SIGIO signal */ case 0: --- linux-2.2.17/kernel/signal.c.orig Thu Sep 21 08:04:07 2000 +++ linux/kernel/signal.c Fri Sep 22 14:38:45 2000 @@ -250,7 +250,7 @@ } int -send_sig_info(int sig, struct siginfo *info, struct task_struct *t) +send_sig_info_nocheck(int sig, struct siginfo *info, struct task_struct *t) { unsigned long flags; int ret; @@ -259,18 +259,6 @@ printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig); #endif - ret = -EINVAL; - if (sig < 0 || sig > _NSIG) - goto out_nolock; - /* The somewhat baroque permissions check... */ - ret = -EPERM; - if ((!info || ((unsigned long)info != 1 && SI_FROMUSER(info))) - && ((sig != SIGCONT) || (current->session != t->session)) - && (current->euid ^ t->suid) && (current->euid ^ t->uid) - && (current->uid ^ t->suid) && (current->uid ^ t->uid) - && !capable(CAP_KILL)) - goto out_nolock; - /* The null signal is a permissions and process existance probe. No signal is actually delivered. Same goes for zombies. We have to grab the spinlock now so that we do not race @@ -405,6 +393,30 @@ return ret; } +int +send_sig_info(int sig, struct siginfo *info, struct task_struct *t) +{ + int ret; + + ret = -EINVAL; + if (sig < 0 || sig > _NSIG) + goto out; + /* The somewhat baroque permissions check... */ + ret = -EPERM; + if ((!info || ((unsigned long)info != 1 && SI_FROMUSER(info))) + && ((sig != SIGCONT) || (current->session != t->session)) + && (current->euid ^ t->suid) && (current->euid ^ t->uid) + && (current->uid ^ t->suid) && (current->uid ^ t->uid) + && !capable(CAP_KILL)) + goto out; + + return send_sig_info_nocheck(sig, info, t); + +out: + + return ret; +} + /* * Force a signal that the process can't ignore: if necessary * we unblock the signal and change any SIG_IGN to SIG_DFL. @@ -634,6 +646,7 @@ EXPORT_SYMBOL(recalc_sigpending); EXPORT_SYMBOL(send_sig); EXPORT_SYMBOL(send_sig_info); +EXPORT_SYMBOL(send_sig_info_nocheck); /*