Messages in this thread | | | Date | Thu, 29 Jul 1999 11:28:17 +0200 | From | Jakub Jelinek <> | Subject | Re: [RFC] RT signals |
| |
On Wed, Jul 28, 1999 at 10:48:31AM -0700, Richard Henderson wrote: > On Wed, Jul 28, 1999 at 05:35:15PM +0200, Jakub Jelinek wrote: > > The implementation of POSIX timers which made it into 2.3.12pre adds a > > siginfo_t nrt_info[SIGRTMIN] array to task structure. That's 4K if I count > > well, which seems a little bit dangerous to me. > > More than a little in my book. > > A correct solution in my view is to attempt to dynamicly allocate > the siginfo structures from signal_queue_cachep. If we fail, then > we just send the signal without the info. No terrible loss there.
That's what I thought about if the pad trick was not possible.
Now I thing we have severe security holes all around and I wonder whether it would not be easier to plug them at a few places. The issue is that the usual way of sending a siginfo is (example from signal.c):
struct siginfo info; ...
info.si_signo = sig; info.si_errno = 0; info.si_pid = tsk->pid; info.si_utime = tsk->times.tms_utime; info.si_stime = tsk->times.tms_stime; info.si_code = why; ... send_sig_info(sig, &info, tsk);
but no trace of memset(&info, 0, sizeof(siginfo_t)); and from that time on, the siginfo_t is always taken as whole unit and finally copied to userland either in rt_sigtimedwait or in arch's setup_rt_frame, so userland will get kernel stack content, which is in my eyes a big NO NO. I see two ways of solving this: either add memsets everywhere (now there are not many places where kernel sends signal with info, but once info can be carried with a non-rt signal, every arch's trap.c or fault.c will contain a bunch of them), or limit what is copied into userland. The latter would avoid the memsets and copy_to_user (X, X, 128) for SI_FROMKERNEL and si_code 0 codes but would allow some branches in the path. I'd think about siginfo.h defining (of course, each architecture is free to optimize this)
extern inline int __copy_siginfo_to_user (siginfo_t *kinfo, siginfo_t *info) { int err; if (kinfo->si_code < 0) err = __copy_to_user (info, kinfo, sizeof (siginfo_t)); else { err = __put_user (kinfo->si_signo, &info->si_signo); err |= __put_user (kinfo->si_errno, &info->si_errno); err |= __put_user (kinfo->si_code, &info->si_code); if (kinfo->si_code == SI_USER) { err |= __put_user (kinfo->si_pid, &info->si_pid); err |= __put_user (kinfo->si_uid, &info->si_uid); } else switch (kinfo->si_signo) { case SIGPOLL: err |= __put_user (kinfo->si_band, &info->si_band); err |= __put_user (kinfo->si_fd, &info->si_fd); break; case SIGCHLD: err |= __put_user (kinfo->si_pid, &info->si_pid); err |= __put_user (kinfo->si_uid, &info->si_uid); err |= __put_user (kinfo->si_status, &info->si_status); err |= __put_user (kinfo->si_utime, &info->si_utime); err |= __put_user (kinfo->si_stime, &info->si_stime); break; case SIGSEGV: case SIGILL: case SIGFPE: case SIGBUS: #ifdef SIGEMT case SIGEMT: #endif err |= __put_user (kinfo->si_addr, &info->si_addr); err |= __put_user (kinfo->si_trapno, &info->si_trapno); break; default: err |= __put_user (kinfo->si_pid, &info->si_pid); err |= __put_user (kinfo->si_uid, &info->si_uid); break; } } return err; }
which could be used by sys_rt_sigtimedwait and arch's setup_rt_frame. Code like POSIX timers would still have to memset the whole siginfo_t before sending it. And at least si_errno should be initialized everywhere.
Cheers, Jakub ___________________________________________________________________ Jakub Jelinek | jj@sunsite.mff.cuni.cz | http://sunsite.mff.cuni.cz Administrator of SunSITE Czech Republic, MFF, Charles University ___________________________________________________________________ UltraLinux | http://ultra.linux.cz/ | http://ultra.penguin.cz/ Linux version 2.2.10 on a sparc64 machine (1343.49 BogoMips) ___________________________________________________________________
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |