From: Christopher Faylor Date: Wed, 17 Sep 2003 01:15:56 +0000 (+0000) Subject: * pinfo.h (winpids::pid_access): New element. X-Git-Tag: pre-cgf-merge~19 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=deb648cc8b95ec4b7a5b604d958abd338347811f;p=newlib-cygwin.git * pinfo.h (winpids::pid_access): New element. (winpids::winpids): Rejigger to set pinfo_access. * pinfo.cc (winpids::add): Try to open shared memory region with supplied pinfo_access first, then default to readonly. * fhandler_termios.cc (tty_min::kill_pgrp): When getting list of pids to work with, suggest opening with PID_MAP_RW. * signal.cc (kill_pgrp): Ditto. * sigproc.cc (sig_send): Perform a write check on todo prior to attempting to increment it. Return EACCES if we can't write to it. --- diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index c4d79237f..a7ef9a7d8 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,15 @@ +2003-09-16 Christopher Faylor + + * pinfo.h (winpids::pid_access): New element. + (winpids::winpids): Rejigger to set pinfo_access. + * pinfo.cc (winpids::add): Try to open shared memory region with + supplied pinfo_access first, then default to readonly. + * fhandler_termios.cc (tty_min::kill_pgrp): When getting list of pids + to work with, suggest opening with PID_MAP_RW. + * signal.cc (kill_pgrp): Ditto. + * sigproc.cc (sig_send): Perform a write check on todo prior to + attempting to increment it. Return EACCES if we can't write to it. + 2003-09-16 Corinna Vinschen * cygheap.cc (cygheap_user::set_saved_sid): Rename from set_orig_sid. diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc index 49dbb3378..1a2dd251c 100644 --- a/winsup/cygwin/fhandler_termios.cc +++ b/winsup/cygwin/fhandler_termios.cc @@ -19,6 +19,7 @@ details. */ #include "sigproc.h" #include "pinfo.h" #include "tty.h" +#include "sys/cygwin.h" /* Common functions shared by tty/console */ @@ -84,7 +85,7 @@ void tty_min::kill_pgrp (int sig) { int killself = 0; - winpids pids; + winpids pids ((DWORD) PID_MAP_RW); for (unsigned i = 0; i < pids.npids; i++) { _pinfo *p = pids[i]; diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h index 36c3f53b1..d1083264b 100644 --- a/winsup/cygwin/include/sys/cygwin.h +++ b/winsup/cygwin/include/sys/cygwin.h @@ -49,7 +49,7 @@ struct __cygwin_perfile /* External interface stuff */ -typedef enum +typedef { CW_LOCK_PINFO, CW_UNLOCK_PINFO, diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index eabf6a92c..6c59860c6 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -541,22 +541,31 @@ winpids::add (DWORD& nelem, bool winpid, DWORD pid) pinfolist = (pinfo *) realloc (pinfolist, size_pinfolist (npidlist + 1)); } - pinfolist[nelem].init (cygpid, PID_NOREDIR | (winpid ? PID_ALLPIDS : 0)); + pinfolist[nelem].init (cygpid, PID_NOREDIR | (winpid ? PID_ALLPIDS : 0) + | pinfo_access); if (winpid) - /* nothing to do */; - else if (!pinfolist[nelem]) - return; - else - /* Scan list of previously recorded pids to make sure that this pid hasn't - shown up before. This can happen when a process execs. */ - for (unsigned i = 0; i < nelem; i++) - if (pinfolist[i]->pid == pinfolist[nelem]->pid) - { - if ((_pinfo *) pinfolist[nelem] != (_pinfo *) myself) - pinfolist[nelem].release (); - return; - } + goto out; + if (!pinfolist[nelem]) + { + if (!pinfo_access) + return; + pinfolist[nelem].init (cygpid, PID_NOREDIR | (winpid ? PID_ALLPIDS : 0)); + if (!pinfolist[nelem]) + return; + } + + /* Scan list of previously recorded pids to make sure that this pid hasn't + shown up before. This can happen when a process execs. */ + for (unsigned i = 0; i < nelem; i++) + if (pinfolist[i]->pid == pinfolist[nelem]->pid) + { + if ((_pinfo *) pinfolist[nelem] != (_pinfo *) myself) + pinfolist[nelem].release (); + return; + } + +out: pidlist[nelem++] = pid; } diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index e437328b6..518252c27 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -197,6 +197,7 @@ class winpids DWORD *pidlist; DWORD npidlist; pinfo *pinfolist; + DWORD pinfo_access; // access type for pinfo open DWORD (winpids::* enum_processes) (bool winpid); DWORD enum_init (bool winpid); DWORD enumNT (bool winpid); @@ -207,9 +208,14 @@ public: DWORD npids; inline void reset () { npids = 0; release (); } void set (bool winpid); - winpids (int): enum_processes (&winpids::enum_init) { reset (); } - winpids (): pidlist (NULL), npidlist (0), pinfolist (NULL), - enum_processes (&winpids::enum_init), npids (0) { set (0); } + winpids (int): pinfo_access (0), enum_processes (&winpids::enum_init) + { reset (); } + winpids (DWORD acc = 0): pidlist (NULL), npidlist (0), pinfolist (NULL), + enum_processes (&winpids::enum_init), npids (0) + { + pinfo_access = acc; + set (0); + } inline DWORD& winpid (int i) const {return pidlist[i];} inline _pinfo *operator [] (int i) const {return (_pinfo *) pinfolist[i];} ~winpids (); diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 5ee4cc71a..07c8a2c0b 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -247,7 +247,7 @@ kill_pgrp (pid_t pid, int sig) sigproc_printf ("pid %d, signal %d", pid, sig); - winpids pids; + winpids pids ((DWORD) PID_MAP_RW); for (unsigned i = 0; i < pids.npids; i++) { _pinfo *p = pids[i]; diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 795c7f3ef..dff073049 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -725,6 +725,11 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception) else if ((thiscatch = getevent (p, "sigcatch"))) { todo = p->getsigtodo (sig); + if (IsBadWritePtr (todo, sizeof (*todo))) + { + set_errno (EACCES); + goto out; + } issem = false; } else