From 893ac8e03c21d246bbfc8d575a227d8c65cfae76 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sun, 3 Jul 2005 02:40:30 +0000 Subject: Replace valid memory checks with new myfault class "exception handling", almost everywhere. Leave some thread.cc stuff alone for now. * cygtls.h: Kludge some definitions to avoid including a problematic windows header. (_cygtls::_myfault): New entry. (_cygtls::_myfault_errno): Ditto. (_cygtls::fault_guarded): New function. (_cygtls::setup_fault): Ditto. (_cygtls::return_from_fault): Ditto. (_cygtls::clear_fault): Ditto. (myfault): New class. * exceptions.cc (handle_exceptions): Handle case of guarded fault in system routine. * gendef: Add another entry point for setjmp that the compiler doesn't know about and won't complain about. * gentls_offsets: Just include windows.h rather than kludging a HANDLE def. * miscfuncs.cc (check_null_str): Delete. (check_null_empty_str): Ditto. (check_null_empty_str_errno): Ditto. (check_null_str_errno): Ditto. (__check_null_invalid_struct): Ditto. (__check_null_invalid_struct_errno): Ditto. (__check_invalid_read_ptr): Ditto. (__check_invalid_read_ptr_errno): Ditto. (dummytest): New function. (check_iovec_for_read): Delete. (chec_iovec): Rename from check_iovec_for_write. Take a read/write parameter. * tlsoffsets.h: Regenerate. * winsup.h: Remove check_* declarations. (check_iovec_for_read): Delete declaration. Turn into a define instead. (check_iovec_for_write): Ditto. (check_iovec): New declaration. * thread.h: Use ifdef guard name consistent with other header files. --- winsup/cygwin/ChangeLog | 41 +++++++++++++ winsup/cygwin/cygtls.cc | 3 + winsup/cygwin/cygtls.h | 76 ++++++++++++++++++++++- winsup/cygwin/dir.cc | 19 ++++-- winsup/cygwin/environ.cc | 40 +++++-------- winsup/cygwin/exceptions.cc | 19 +++--- winsup/cygwin/external.cc | 3 +- winsup/cygwin/fhandler_socket.cc | 10 +++- winsup/cygwin/fhandler_tape.cc | 21 +++---- winsup/cygwin/gendef | 3 +- winsup/cygwin/gentls_offsets | 2 +- winsup/cygwin/libc/bsdlib.cc | 3 +- winsup/cygwin/miscfuncs.cc | 126 +++++---------------------------------- winsup/cygwin/msg.cc | 25 +++----- winsup/cygwin/net.cc | 119 ++++++++++++++++++------------------ winsup/cygwin/path.cc | 69 +++++++++++++++++---- winsup/cygwin/pthread.cc | 9 ++- winsup/cygwin/resource.cc | 7 ++- winsup/cygwin/sec_helper.cc | 1 - winsup/cygwin/select.cc | 11 ++-- winsup/cygwin/sem.cc | 22 ++----- winsup/cygwin/shm.cc | 26 ++------ winsup/cygwin/signal.cc | 12 ++-- winsup/cygwin/syscalls.cc | 95 ++++++++++++++++++----------- winsup/cygwin/thread.cc | 8 +-- winsup/cygwin/thread.h | 6 +- winsup/cygwin/timer.cc | 28 +++++---- winsup/cygwin/times.cc | 3 +- winsup/cygwin/tlsoffsets.h | 122 +++++++++++++++++++------------------ winsup/cygwin/uinfo.cc | 6 +- winsup/cygwin/uname.cc | 4 +- winsup/cygwin/winsup.h | 21 +------ 32 files changed, 514 insertions(+), 446 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 2525c9e6b..0dfa37987 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,44 @@ +2005-07-02 Christopher Faylor + + Replace valid memory checks with new myfault class "exception + handling", almost everywhere. Leave some thread.cc stuff alone for + now. + * cygtls.h: Kludge some definitions to avoid including a problematic + windows header. + (_cygtls::_myfault): New entry. + (_cygtls::_myfault_errno): Ditto. + (_cygtls::fault_guarded): New function. + (_cygtls::setup_fault): Ditto. + (_cygtls::return_from_fault): Ditto. + (_cygtls::clear_fault): Ditto. + (myfault): New class. + * exceptions.cc (handle_exceptions): Handle case of guarded fault in + system routine. + * gendef: Add another entry point for setjmp that the compiler doesn't + know about and won't complain about. + * gentls_offsets: Just include windows.h rather than kludging a HANDLE + def. + * miscfuncs.cc (check_null_str): Delete. + (check_null_empty_str): Ditto. + (check_null_empty_str_errno): Ditto. + (check_null_str_errno): Ditto. + (__check_null_invalid_struct): Ditto. + (__check_null_invalid_struct_errno): Ditto. + (__check_invalid_read_ptr): Ditto. + (__check_invalid_read_ptr_errno): Ditto. + (dummytest): New function. + (check_iovec_for_read): Delete. + (chec_iovec): Rename from check_iovec_for_write. Take a read/write + parameter. + * tlsoffsets.h: Regenerate. + * winsup.h: Remove check_* declarations. + (check_iovec_for_read): Delete declaration. Turn into a define + instead. + (check_iovec_for_write): Ditto. + (check_iovec): New declaration. + + * thread.h: Use ifdef guard name consistent with other header files. + 2005-07-02 Christopher Faylor * include/cygwin/version.h: Bump DLL minor number to 19. diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc index 58e82d2ec..0e29d8901 100644 --- a/winsup/cygwin/cygtls.cc +++ b/winsup/cygwin/cygtls.cc @@ -7,6 +7,9 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" +#include +#define USE_SYS_TYPES_FD_SET +#include #include "thread.h" #include "cygtls.h" #include "assert.h" diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index 7ee1ddcc1..2ac6d04b3 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -16,8 +16,34 @@ details. */ #define _NOMNTENT_FUNCS #include #undef _NOMNTENT_FUNCS -#define USE_SYS_TYPES_FD_SET -#include +#include + +#ifndef _WINSOCK_H +/* Stupid hack: Including winsock.h explicitly causes too many problems. */ +struct sockaddr_in +{ + short sin_family; + u_short sin_port; + struct in_addr + { + union + { + struct + { + u_char s_b1, s_b2, s_b3, s_b4; + } S_un_b; + struct + { + u_short s_w1, s_w2; + } S_un_w; + u_long S_addr; + } S_un; + }; + struct in_addr sin_addr; + char sin_zero[8]; +}; +typedef unsigned int SOCKET; +#endif #define CYGTLS_INITIALIZED 0x43227 #define CYGTLS_EXCEPTION (0x43227 + true) @@ -118,6 +144,12 @@ typedef struct struct_waitq of the compiler used to generate tlsoffsets.h and the cygwin cross compiler. */ +/*gentls_offsets*/ +#include "cygerrno.h" + +extern "C" int __sjfault (jmp_buf); +/*gentls_offsets*/ + typedef __uint32_t __stack_t; struct _cygtls { @@ -142,6 +174,8 @@ struct _cygtls }; struct _local_storage locals; class cygthread *_ctinfo; + void *_myfault; + int _myfault_errno; waitq wq; struct _cygtls *prev, *next; __stack_t *stackptr; @@ -172,7 +206,9 @@ struct _cygtls struct sigaction& siga) __attribute__((regparm(3))); void init_threadlist_exceptions (struct _exception_list *); +#ifdef _THREAD_H operator HANDLE () const {return tid->win32_obj_id;} +#endif void set_siginfo (struct sigpacket *) __attribute__ ((regparm (3))); void set_threadkill () {threadkill = true;} void reset_threadkill () {threadkill = false;} @@ -182,6 +218,26 @@ struct _cygtls void lock () __attribute__ ((regparm (1))); void unlock () __attribute__ ((regparm (1))); bool locked () __attribute__ ((regparm (1))); + void*& fault_guarded () {return _myfault;} + void return_from_fault () + { + if (_myfault_errno) + set_errno (_myfault_errno); + longjmp ((int *) _myfault, 1); + } + int setup_fault (jmp_buf j, int myerrno) __attribute__ ((always_inline)) + { + if (_myfault) + return 0; + _myfault = (void *) j; + _myfault_errno = myerrno; + return __sjfault (j); + } + void clear_fault (jmp_buf j) __attribute__ ((always_inline)) + { + if (j == _myfault) + _myfault = NULL; + } /*gentls_offsets*/ }; #pragma pack(pop) @@ -191,6 +247,22 @@ extern char *_tlstop __asm__ ("%fs:8"); #define _my_tls (((_cygtls *) _tlsbase)[-1]) extern _cygtls *_main_tls; +/*gentls_offsets*/ +class myfault +{ + jmp_buf buf; +public: + ~myfault () __attribute__ ((always_inline)) + { + _my_tls.clear_fault (buf); + } + inline int faulted (int myerrno = 0) __attribute__ ((always_inline)) + { + return _my_tls.setup_fault (buf, myerrno); + } +}; +/*gentls_offsets*/ + #define __getreent() (&_my_tls.local_clib) const int CYGTLS_PADSIZE = (((char *) _main_tls->padding) - ((char *) _main_tls)); diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index c6a6bc6e6..254906a6e 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -23,11 +23,13 @@ details. */ #include "fhandler.h" #include "dtable.h" #include "cygheap.h" +#include "cygtls.h" extern "C" int dirfd (DIR *dir) { - if (check_null_invalid_struct_errno (dir)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; if (dir->__d_cookie != __DIRENT_COOKIE) { @@ -67,7 +69,8 @@ opendir (const char *name) extern "C" struct dirent * readdir (DIR *dir) { - if (check_null_invalid_struct_errno (dir)) + myfault efault; + if (efault.faulted (EFAULT)) return NULL; if (dir->__d_cookie != __DIRENT_COOKIE) @@ -141,7 +144,8 @@ readdir (DIR *dir) extern "C" _off64_t telldir64 (DIR *dir) { - if (check_null_invalid_struct_errno (dir)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; if (dir->__d_cookie != __DIRENT_COOKIE) @@ -159,7 +163,8 @@ telldir (DIR *dir) extern "C" void seekdir64 (DIR *dir, _off64_t loc) { - if (check_null_invalid_struct_errno (dir)) + myfault efault; + if (efault.faulted (EFAULT)) return; if (dir->__d_cookie != __DIRENT_COOKIE) @@ -179,7 +184,8 @@ seekdir (DIR *dir, _off_t loc) extern "C" void rewinddir (DIR *dir) { - if (check_null_invalid_struct_errno (dir)) + myfault efault; + if (efault.faulted (EFAULT)) return; if (dir->__d_cookie != __DIRENT_COOKIE) @@ -192,7 +198,8 @@ rewinddir (DIR *dir) extern "C" int closedir (DIR *dir) { - if (check_null_invalid_struct_errno (dir)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; if (dir->__d_cookie != __DIRENT_COOKIE) diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index ddd038285..099dcaee5 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -331,20 +331,18 @@ _addenv (const char *name, const char *value, int overwrite) extern "C" int putenv (char *str) { - int res; - if ((res = check_null_empty_str (str))) + myfault efault; + if (efault.faulted (EFAULT)) + return -1; + if (*str) { - if (res == ENOENT) - return 0; - set_errno (res); - return -1; - } - char *eq = strchr (str, '='); - if (eq) - return _addenv (str, eq + 1, -1); + char *eq = strchr (str, '='); + if (eq) + return _addenv (str, eq + 1, -1); - /* Remove str from the environment. */ - unsetenv (str); + /* Remove str from the environment. */ + unsetenv (str); + } return 0; } @@ -353,19 +351,11 @@ putenv (char *str) extern "C" int setenv (const char *name, const char *value, int overwrite) { - int res; - if ((res = check_null_empty_str (value)) == EFAULT) - { - set_errno (res); - return -1; - } - if ((res = check_null_empty_str (name))) - { - if (res == ENOENT) - return 0; - set_errno (res); - return -1; - } + myfault efault; + if (efault.faulted (EFAULT)) + return -1; + if (!*name) + return 0; if (*value == '=') value++; return _addenv (name, value, !!overwrite); diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 0e7a09fdf..d375c0a07 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -403,6 +403,7 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *) { static bool NO_COPY debugging; static int NO_COPY recursed; + _cygtls& me = _my_tls; if (debugging && ++debugging < 500000) { @@ -520,11 +521,12 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *) break; } - if (!cygwin_finished_initializing - || GetCurrentThreadId () == sigtid - || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL - || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN - || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR) + if (!me.fault_guarded () + && (!cygwin_finished_initializing + || GetCurrentThreadId () == sigtid + || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL + || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN + || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR)) { /* Print the exception to the console */ if (!myself->cygstarted) @@ -559,11 +561,14 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *) RtlUnwind (frame, ret_here, e0, 0); __asm__ volatile (".equ _ret_here,."); + if (me.fault_guarded ()) + me.return_from_fault (); + si.si_addr = ebp; si.si_code = SI_KERNEL; si.si_errno = si.si_pid = si.si_uid = 0; - _my_tls.push ((__stack_t) ebp, true); - sig_send (NULL, si, &_my_tls); // Signal myself + me.push ((__stack_t) ebp, true); + sig_send (NULL, si, &me); // Signal myself return 1; } diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc index 2bcbc7047..c731217ab 100644 --- a/winsup/cygwin/external.cc +++ b/winsup/cygwin/external.cc @@ -199,7 +199,8 @@ cygwin_internal (cygwin_getinfo_types t, ...) case CW_SET_CYGWIN_REGISTRY_NAME: { const char *cr = va_arg (arg, char *); - if (check_null_empty_str_errno (cr)) + myfault efault; + if (efault.faulted (EFAULT) || !*cr) return (DWORD) NULL; cygheap->cygwin_regname = (char *) crealloc (cygheap->cygwin_regname, strlen (cr) + 1); diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index ced45039e..ffe647cb4 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -35,6 +35,7 @@ #include "wininfo.h" #include #include +#include "cygtls.h" #define ASYNC_MASK (FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT) @@ -1659,11 +1660,14 @@ fhandler_socket::getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid) return -1; } - if (!check_null_invalid_struct (pid)) + myfault efault; + if (efault.faulted (EFAULT)) + return -1; + if (pid) *pid = sec_peer_pid; - if (!check_null_invalid_struct (euid)) + if (euid) *euid = sec_peer_uid; - if (!check_null_invalid_struct (egid)) + if (egid) *egid = sec_peer_gid; return 0; } diff --git a/winsup/cygwin/fhandler_tape.cc b/winsup/cygwin/fhandler_tape.cc index 1c7f5aa9e..2b1d458b2 100644 --- a/winsup/cygwin/fhandler_tape.cc +++ b/winsup/cygwin/fhandler_tape.cc @@ -10,6 +10,7 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" +#include "cygtls.h" #include #include #include @@ -967,10 +968,11 @@ mtinfo_drive::set_options (HANDLE mt, long options) int mtinfo_drive::ioctl (HANDLE mt, unsigned int cmd, void *buf) { + myfault efault; + if (efault.faulted ()) + return ERROR_NOACCESS; if (cmd == MTIOCTOP) { - if (__check_invalid_read_ptr (buf, sizeof (struct mtop))) - return ERROR_NOACCESS; struct mtop *op = (struct mtop *) buf; if (lasterr == ERROR_BUS_RESET) { @@ -1115,18 +1117,9 @@ mtinfo_drive::ioctl (HANDLE mt, unsigned int cmd, void *buf) } } else if (cmd == MTIOCGET) - { - if (__check_null_invalid_struct (buf, sizeof (struct mtget))) - return ERROR_NOACCESS; - get_status (mt, (struct mtget *) buf); - } - else if (cmd == MTIOCPOS) - { - if (__check_null_invalid_struct (buf, sizeof (struct mtpos))) - return ERROR_NOACCESS; - if (!get_pos (mt)) - ((struct mtpos *) buf)->mt_blkno = block; - } + get_status (mt, (struct mtget *) buf); + else if (cmd == MTIOCPOS && !get_pos (mt)) + ((struct mtpos *) buf)->mt_blkno = block; return lasterr; } diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index 84157287e..83e9e1245 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -271,8 +271,9 @@ EOF sub longjmp { return < #include #include -typedef void *HANDLE; +#include $pre $def int diff --git a/winsup/cygwin/libc/bsdlib.cc b/winsup/cygwin/libc/bsdlib.cc index c25163e2e..48ccc4578 100644 --- a/winsup/cygwin/libc/bsdlib.cc +++ b/winsup/cygwin/libc/bsdlib.cc @@ -248,7 +248,8 @@ getprogname (void) extern "C" void setprogname (const char *newprogname) { - if (!check_null_str_errno (newprogname)) + myfault efault; + if (!efault.faulted (EFAULT)) { /* Per BSD man page, setprogname keeps a pointer to the last path component of the argument. It does *not* copy the diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc index 79ad5c312..531d2b1f2 100644 --- a/winsup/cygwin/miscfuncs.cc +++ b/winsup/cygwin/miscfuncs.cc @@ -19,6 +19,7 @@ details. */ #include #include #include "cygthread.h" +#include "cygtls.h" long tls_ix = -1; @@ -145,76 +146,6 @@ strcasestr (const char *searchee, const char *lookfor) return NULL; } -int __stdcall -check_null_str (const char *name) -{ - if (name && !IsBadStringPtr (name, CYG_MAX_PATH)) - return 0; - - return EFAULT; -} - -int __stdcall -check_null_empty_str (const char *name) -{ - if (name && !IsBadStringPtr (name, CYG_MAX_PATH)) - return !*name ? ENOENT : 0; - - return EFAULT; -} - -int __stdcall -check_null_empty_str_errno (const char *name) -{ - int __err; - if ((__err = check_null_empty_str (name))) - set_errno (__err); - return __err; -} - -int __stdcall -check_null_str_errno (const char *name) -{ - int __err; - if ((__err = check_null_str (name))) - set_errno (__err); - return __err; -} - -int __stdcall -__check_null_invalid_struct (void *s, unsigned sz) -{ - if (s && !IsBadWritePtr (s, sz)) - return 0; - - return EFAULT; -} - -int __stdcall -__check_null_invalid_struct_errno (void *s, unsigned sz) -{ - int err; - if ((err = __check_null_invalid_struct (s, sz))) - set_errno (err); - return err; -} - -int __stdcall -__check_invalid_read_ptr (const void *s, unsigned sz) -{ - if (s && !IsBadReadPtr (s, sz)) - return 0; - return EFAULT; -} - -int __stdcall -__check_invalid_read_ptr_errno (const void *s, unsigned sz) -{ - if (s && !IsBadReadPtr (s, sz)) - return 0; - return set_errno (EFAULT); -} - int __stdcall check_invalid_virtual_addr (const void *s, unsigned sz) { @@ -228,43 +159,13 @@ check_invalid_virtual_addr (const void *s, unsigned sz) return 0; } -ssize_t -check_iovec_for_read (const struct iovec *iov, int iovcnt) +static char __attribute__ ((noinline)) +dummytest (volatile char *p) { - if (iovcnt <= 0 || iovcnt > IOV_MAX) - { - set_errno (EINVAL); - return -1; - } - - if (__check_invalid_read_ptr_errno (iov, iovcnt * sizeof (*iov))) - return -1; - - size_t tot = 0; - - while (iovcnt != 0) - { - if (iov->iov_len > SSIZE_MAX || (tot += iov->iov_len) > SSIZE_MAX) - { - set_errno (EINVAL); - return -1; - } - - if (iov->iov_len - && __check_null_invalid_struct_errno (iov->iov_base, iov->iov_len)) - return -1; - - iov += 1; - iovcnt -= 1; - } - - assert (tot <= SSIZE_MAX); - - return (ssize_t) tot; + return *p; } - ssize_t -check_iovec_for_write (const struct iovec *iov, int iovcnt) +check_iovec (const struct iovec *iov, int iovcnt, bool forwrite) { if (iovcnt <= 0 || iovcnt > IOV_MAX) { @@ -272,7 +173,8 @@ check_iovec_for_write (const struct iovec *iov, int iovcnt) return -1; } - if (__check_invalid_read_ptr_errno (iov, iovcnt * sizeof (*iov))) + myfault efault; + if (efault.faulted (EFAULT)) return -1; size_t tot = 0; @@ -285,12 +187,16 @@ check_iovec_for_write (const struct iovec *iov, int iovcnt) return -1; } - if (iov->iov_len - && __check_invalid_read_ptr_errno (iov->iov_base, iov->iov_len)) - return -1; + volatile char *p = ((char *) iov->iov_base) + iov->iov_len - 1; + if (!iov->iov_len) + /* nothing to do */; + else if (!forwrite) + *p = dummytest (p); + else + (void) dummytest (p); - iov += 1; - iovcnt -= 1; + iov++; + iovcnt--; } assert (tot <= SSIZE_MAX); diff --git a/winsup/cygwin/msg.cc b/winsup/cygwin/msg.cc index d226cc0c0..00d13a854 100644 --- a/winsup/cygwin/msg.cc +++ b/winsup/cygwin/msg.cc @@ -12,11 +12,11 @@ details. */ #include "cygerrno.h" #include #ifdef USE_SERVER -#include #include #include #include "sigproc.h" +#include "cygtls.h" #include "cygserver_ipc.h" #include "cygserver_msg.h" @@ -100,31 +100,20 @@ msgctl (int msqid, int cmd, struct msqid_ds *buf) #ifdef USE_SERVER syscall_printf ("msgctl (msqid = %d, cmd = 0x%x, buf = %p)", msqid, cmd, buf); + myfault efault; + if (efault.faulted (EFAULT)) + return -1; switch (cmd) { case IPC_STAT: - if (__check_null_invalid_struct_errno (buf, sizeof *buf)) - return -1; break; case IPC_SET: - if (__check_invalid_read_ptr_errno (buf, sizeof *buf)) - return -1; break; case IPC_RMID: break; case IPC_INFO: - /* msqid == 0: Request for msginfo struct. */ - if (!msqid - && __check_null_invalid_struct_errno (buf, sizeof (struct msginfo))) - return -1; - /* Otherwise, request msqid entries from internal msqid_ds array. */ - if (msqid) - if (__check_null_invalid_struct_errno (buf, msqid * sizeof (struct msqid_ds))) - return -1; break; case MSG_INFO: - if (__check_null_invalid_struct_errno (buf, sizeof (struct msg_info))) - return -1; break; default: syscall_printf ("-1 [%d] = msgctl ()", EINVAL); @@ -177,7 +166,8 @@ msgrcv (int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg) syscall_printf ("msgrcv (msqid = %d, msgp = %p, msgsz = %d, " "msgtyp = %d, msgflg = 0x%x)", msqid, msgp, msgsz, msgtyp, msgflg); - if (__check_null_invalid_struct_errno (msgp, msgsz)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; client_request_msg request (msqid, msgp, msgsz, msgtyp, msgflg); if (request.make_request () == -1 || request.rcvval () == -1) @@ -202,7 +192,8 @@ msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg) #ifdef USE_SERVER syscall_printf ("msgsnd (msqid = %d, msgp = %p, msgsz = %d, msgflg = 0x%x)", msqid, msgp, msgsz, msgflg); - if (__check_invalid_read_ptr_errno (msgp, msgsz)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; client_request_msg request (msqid, msgp, msgsz, msgflg); if (request.make_request () == -1 || request.retval () == -1) diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index 23989dd10..1fc54915c 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -134,7 +134,8 @@ cygwin_inet_ntoa (struct in_addr in) extern "C" unsigned long cygwin_inet_addr (const char *cp) { - if (check_null_str_errno (cp)) + myfault efault; + if (efault.faulted (EFAULT)) return INADDR_NONE; unsigned long res = inet_addr (cp); @@ -147,7 +148,8 @@ cygwin_inet_addr (const char *cp) extern "C" int cygwin_inet_aton (const char *cp, struct in_addr *inp) { - if (check_null_str_errno (cp) || check_null_invalid_struct_errno (inp)) + myfault efault; + if (efault.faulted (EFAULT)) return 0; unsigned long res = inet_addr (cp); @@ -165,7 +167,8 @@ extern "C" unsigned int WINAPI inet_network (const char *); extern "C" unsigned int cygwin_inet_network (const char *cp) { - if (check_null_str_errno (cp)) + myfault efault; + if (efault.faulted (EFAULT)) return INADDR_NONE; unsigned int res = inet_network (cp); @@ -536,7 +539,8 @@ __dup_ent (unionent *&dst, unionent *src, struct_type type) extern "C" struct protoent * cygwin_getprotobyname (const char *p) { - if (check_null_str_errno (p)) + myfault efault; + if (efault.faulted (EFAULT)) return NULL; return (protoent *) dup_ent (protoent_buf, getprotobyname (p), t_protoent); } @@ -625,9 +629,8 @@ cygwin_sendto (int fd, const void *buf, int len, int flags, fhandler_socket *fh = get (fd); - if ((len && __check_invalid_read_ptr_errno (buf, (unsigned) len)) - || (to && __check_invalid_read_ptr_errno (to, tolen)) - || !fh) + myfault efault; + if (efault.faulted (EFAULT) || !fh) res = -1; else if ((res = len) != 0) res = fh->sendto (buf, len, flags, to, tolen); @@ -648,11 +651,8 @@ cygwin_recvfrom (int fd, void *buf, int len, int flags, fhandler_socket *fh = get (fd); - if ((len && __check_null_invalid_struct_errno (buf, (unsigned) len)) - || (from - && (check_null_invalid_struct_errno (fromlen) - || __check_null_invalid_struct_errno (from, (unsigned) *fromlen))) - || !fh) + myfault efault; + if (efault.faulted (EFAULT) || !fh) res = -1; else if ((res = len) != 0) res = fh->recvfrom (buf, len, flags, from, fromlen); @@ -707,7 +707,8 @@ cygwin_setsockopt (int fd, int level, int optname, const void *optval, break; } - if ((optval && __check_invalid_read_ptr_errno (optval, optlen)) || !fh) + myfault efault; + if (efault.faulted (EFAULT) || !fh) res = -1; else { @@ -771,10 +772,8 @@ cygwin_getsockopt (int fd, int level, int optname, void *optval, int *optlen) name = "SO_PEERCRED"; } - if ((optval - && (check_null_invalid_struct_errno (optlen) - || __check_null_invalid_struct_errno (optval, (unsigned) *optlen))) - || !fh) + myfault efault; + if (efault.faulted (EFAULT) || !fh) res = -1; else if (optname == SO_PEERCRED) { @@ -822,7 +821,8 @@ cygwin_connect (int fd, const struct sockaddr *name, int namelen) fhandler_socket *fh = get (fd); - if (__check_invalid_read_ptr_errno (name, namelen) || !fh) + myfault efault; + if (efault.faulted (EFAULT) || !fh) res = -1; else { @@ -886,8 +886,8 @@ extern "C" struct servent * cygwin_getservbyname (const char *name, const char *proto) { sig_dispatch_pending (); - if (check_null_str_errno (name) - || (proto != NULL && check_null_str_errno (proto))) + myfault efault; + if (efault.faulted (EFAULT)) return NULL; servent *res = (servent *) dup_ent (servent_buf, getservbyname (name, proto), t_servent); @@ -900,7 +900,8 @@ extern "C" struct servent * cygwin_getservbyport (int port, const char *proto) { sig_dispatch_pending (); - if (proto != NULL && check_null_str_errno (proto)) + myfault efault; + if (efault.faulted (EFAULT)) return NULL; servent *res = (servent *) dup_ent (servent_buf, getservbyport (port, proto), t_servent); @@ -912,7 +913,8 @@ extern "C" int cygwin_gethostname (char *name, size_t len) { sig_dispatch_pending (); - if (__check_null_invalid_struct_errno (name, len)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; if (gethostname (name, len)) @@ -934,7 +936,8 @@ extern "C" struct hostent * cygwin_gethostbyname (const char *name) { sig_dispatch_pending (); - if (check_null_str_errno (name)) + myfault efault; + if (efault.faulted (EFAULT)) return NULL; unsigned char tmp_addr[4]; @@ -980,7 +983,8 @@ extern "C" struct hostent * cygwin_gethostbyaddr (const char *addr, int len, int type) { sig_dispatch_pending (); - if (__check_invalid_read_ptr_errno (addr, len)) + myfault efault; + if (efault.faulted (EFAULT)) return NULL; hostent *res = (hostent *) dup_ent (hostent_buf, gethostbyaddr (addr, len, type), t_hostent); @@ -1000,9 +1004,8 @@ cygwin_accept (int fd, struct sockaddr *peer, int *len) fhandler_socket *fh = get (fd); - if ((peer && (check_null_invalid_struct_errno (len) - || __check_null_invalid_struct_errno (peer, (unsigned) *len))) - || !fh) + myfault efault; + if (efault.faulted (EFAULT) || !fh) res = -1; else { @@ -1031,7 +1034,8 @@ cygwin_bind (int fd, const struct sockaddr *my_addr, int addrlen) sig_dispatch_pending (); fhandler_socket *fh = get (fd); - if (__check_invalid_read_ptr_errno (my_addr, addrlen) || !fh) + myfault efault; + if (efault.faulted (EFAULT) || !fh) res = -1; else res = fh->bind (my_addr, addrlen); @@ -1049,9 +1053,8 @@ cygwin_getsockname (int fd, struct sockaddr *addr, int *namelen) fhandler_socket *fh = get (fd); - if (check_null_invalid_struct_errno (namelen) - || __check_null_invalid_struct_errno (addr, (unsigned) *namelen) - || !fh) + myfault efault; + if (efault.faulted (EFAULT) || !fh) res = -1; else res = fh->getsockname (addr, namelen); @@ -1112,7 +1115,8 @@ cygwin_hstrerror (int err) extern "C" void cygwin_herror (const char *s) { - if (s && check_null_str (s)) + myfault efault; + if (efault.faulted ()) return; if (cygheap->fdtab.not_open (2)) return; @@ -1151,9 +1155,8 @@ cygwin_getpeername (int fd, struct sockaddr *name, int *len) fhandler_socket *fh = get (fd); - if (check_null_invalid_struct_errno (len) - || __check_null_invalid_struct_errno (name, (unsigned) *len) - || !fh) + myfault efault; + if (efault.faulted (EFAULT) || !fh) res = -1; else res = fh->getpeername (name, len); @@ -1188,7 +1191,8 @@ getdomainname (char *domain, size_t len) * Punt for now and assume MS-TCP on Win95. */ sig_dispatch_pending (); - if (__check_null_invalid_struct_errno (domain, len)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; PFIXED_INFO info = NULL; @@ -1801,7 +1805,8 @@ get_ifconf (struct ifconf *ifc, int what) struct sockaddr_in *sa; sig_dispatch_pending (); - if (check_null_invalid_struct_errno (ifc)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; /* Union maps buffer to correct struct */ @@ -1880,11 +1885,14 @@ cygwin_rcmd (char **ahost, unsigned short inport, char *locuser, sig_dispatch_pending (); - if (check_null_invalid_struct_errno (ahost) || - check_null_empty_str_errno (*ahost) || - (locuser && check_null_empty_str_errno (locuser)) || - (remuser && check_null_str_errno (remuser))) + myfault efault; + if (efault.faulted (EFAULT)) return (int) INVALID_SOCKET; + if (!*locuser) + { + set_errno (EINVAL); + return (int) INVALID_SOCKET; + } res = rcmd (ahost, inport, locuser, remuser, cmd, fd2p ? &fd2s : NULL); if (res != (int) INVALID_SOCKET) @@ -1932,7 +1940,8 @@ cygwin_rresvport (int *port) int res; sig_dispatch_pending (); - if (check_null_invalid_struct_errno (port)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; res = rresvport (port); @@ -1960,10 +1969,8 @@ cygwin_rexec (char **ahost, unsigned short inport, char *locuser, SOCKET fd2s; sig_dispatch_pending (); - if (check_null_invalid_struct_errno (ahost) || - check_null_empty_str_errno (*ahost) || - (locuser && check_null_empty_str_errno (locuser)) || - (password && check_null_str_errno (password))) + myfault efault; + if (efault.faulted (EFAULT)) return (int) INVALID_SOCKET; res = rexec (ahost, inport, locuser, password, cmd, fd2p ? &fd2s : NULL); @@ -2016,7 +2023,8 @@ socketpair (int family, int type, int protocol, int *sb) int len; sig_dispatch_pending (); - if (__check_null_invalid_struct_errno (sb, 2 * sizeof (int))) + myfault efault; + if (efault.faulted (EFAULT)) return -1; if (family != AF_LOCAL && family != AF_INET) @@ -2217,11 +2225,8 @@ cygwin_recvmsg (int fd, struct msghdr *msg, int flags) fhandler_socket *fh = get (fd); - if (check_null_invalid_struct_errno (msg) - || (msg->msg_name - && __check_null_invalid_struct_errno (msg->msg_name, - (unsigned) msg->msg_namelen)) - || !fh) + myfault efault; + if (efault.faulted (EFAULT) || !fh) res = -1; else { @@ -2243,11 +2248,8 @@ cygwin_sendmsg (int fd, const struct msghdr *msg, int flags) fhandler_socket *fh = get (fd); - if (__check_invalid_read_ptr_errno (msg, sizeof msg) - || (msg->msg_name - && __check_invalid_read_ptr_errno (msg->msg_name, - (unsigned) msg->msg_namelen)) - || !fh) + myfault efault; + if (efault.faulted (EFAULT) || !fh) res = -1; else { @@ -2287,7 +2289,8 @@ cygwin_inet_ntop (int family, const void *addrptr, char *strptr, size_t len) { const u_char *p = (const u_char *) addrptr; - if (__check_null_invalid_struct_errno (strptr, len)) + myfault efault; + if (efault.faulted (EFAULT)) return NULL; if (family == AF_INET) { diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index ca955cb3a..2aeb1f198 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -542,6 +542,12 @@ path_conv::check (const char *src, unsigned opt, } #endif + myfault efault; + if (efault.faulted ()) + { + error = EFAULT; + return; + } int loop = 0; path_flags = 0; known_suffix = NULL; @@ -554,8 +560,12 @@ path_conv::check (const char *src, unsigned opt, if (!(opt & PC_NULLEMPTY)) error = 0; - else if ((error = check_null_empty_str (src))) - return; + else if (!*src) + { + error = ENOENT; + return; + } + /* This loop handles symlink expansion. */ for (;;) { @@ -2473,8 +2483,11 @@ mount (const char *win32_path, const char *posix_path, unsigned flags) { int res = -1; - if (check_null_empty_str_errno (posix_path)) + myfault efault; + if (efault.faulted (EFAULT)) /* errno set */; + else if (!*posix_path || !*win32_path) + set_errno (EINVAL); else if (strpbrk (posix_path, "\\:")) set_errno (EINVAL); else if (flags & MOUNT_CYGDRIVE) /* normal mount */ @@ -2485,7 +2498,7 @@ mount (const char *win32_path, const char *posix_path, unsigned flags) res = mount_table->write_cygdrive_info_to_registry (posix_path, flags); win32_path = NULL; } - else if (!check_null_empty_str_errno (win32_path)) + else res = mount_table->add_item (win32_path, posix_path, flags, true); syscall_printf ("%d = mount (%s, %s, %p)", res, win32_path, posix_path, flags); @@ -2500,8 +2513,14 @@ mount (const char *win32_path, const char *posix_path, unsigned flags) extern "C" int umount (const char *path) { - if (check_null_empty_str_errno (path)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; + if (!*path) + { + set_errno (EINVAL); + return -1; + } return cygwin_umount (path, 0); } @@ -2619,9 +2638,14 @@ symlink_worker (const char *topath, const char *frompath, bool use_winsym, /* POSIX says that empty 'frompath' is invalid input while empty 'topath' is valid -- it's symlink resolver job to verify if symlink contents point to existing filesystem object */ - if (check_null_empty_str_errno (topath) == EFAULT || - check_null_empty_str_errno (frompath)) + myfault efault; + if (efault.faulted (EFAULT)) goto done; + if (!*topath || !*frompath) + { + set_errno (EINVAL); + goto done; + } if (strlen (topath) >= CYG_MAX_PATH) { @@ -3424,9 +3448,12 @@ char * getcwd (char *buf, size_t ulen) { char* res = NULL; - if (ulen == 0 && buf) + myfault efault; + if (efault.faulted (EFAULT)) + /* errno set */; + else if (ulen == 0 && buf) set_errno (EINVAL); - else if (buf == NULL || !__check_null_invalid_struct_errno (buf, ulen)) + else res = cygheap->cwd.get (buf, 1, 1, ulen); return res; } @@ -3442,8 +3469,14 @@ getwd (char *buf) extern "C" int chdir (const char *in_dir) { - if (check_null_empty_str_errno (in_dir)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; + if (!*in_dir) + { + set_errno (ENOENT); + return -1; + } syscall_printf ("dir '%s'", in_dir); @@ -3566,16 +3599,28 @@ cygwin_conv_to_full_win32_path (const char *path, char *win32_path) extern "C" int cygwin_conv_to_posix_path (const char *path, char *posix_path) { - if (check_null_empty_str_errno (path)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; + if (!*path) + { + set_errno (ENOENT); + return -1; + } return_with_errno (mount_table->conv_to_posix_path (path, posix_path, 1)); } extern "C" int cygwin_conv_to_full_posix_path (const char *path, char *posix_path) { - if (check_null_empty_str_errno (path)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; + if (!*path) + { + set_errno (ENOENT); + return -1; + } return_with_errno (mount_table->conv_to_posix_path (path, posix_path, 0)); } diff --git a/winsup/cygwin/pthread.cc b/winsup/cygwin/pthread.cc index deb771682..d35cee616 100644 --- a/winsup/cygwin/pthread.cc +++ b/winsup/cygwin/pthread.cc @@ -15,6 +15,7 @@ #include "cygerrno.h" #include #include +#include "cygtls.h" extern "C" { @@ -165,8 +166,14 @@ sem_destroy (sem_t * sem) static bool mangle_sem_name (char *mangled, const char *name) { - if (check_null_empty_str_errno (name)) + myfault efault; + if (efault.faulted (EFAULT)) return false; + if (!*name) + { + set_errno (ENOENT); + return false; + } int len = strlen (name); if (len >= CYG_MAX_PATH || (wincap.has_terminal_services () && len >= CYG_MAX_PATH - 7)) diff --git a/winsup/cygwin/resource.cc b/winsup/cygwin/resource.cc index 536dfe8a5..9112bbe77 100644 --- a/winsup/cygwin/resource.cc +++ b/winsup/cygwin/resource.cc @@ -18,6 +18,7 @@ details. */ #include "cygerrno.h" #include "pinfo.h" #include "psapi.h" +#include "cygtls.h" /* add timeval values */ static void @@ -113,7 +114,8 @@ getrlimit (int resource, struct rlimit *rlp) { MEMORY_BASIC_INFORMATION m; - if (check_null_invalid_struct_errno (rlp)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; rlp->rlim_cur = RLIM_INFINITY; @@ -157,7 +159,8 @@ getrlimit (int resource, struct rlimit *rlp) extern "C" int setrlimit (int resource, const struct rlimit *rlp) { - if (__check_invalid_read_ptr_errno (rlp, sizeof (*rlp))) + myfault efault; + if (efault.faulted (EFAULT)) return -1; struct rlimit oldlimits; diff --git a/winsup/cygwin/sec_helper.cc b/winsup/cygwin/sec_helper.cc index 5bfa9d4cd..20ef794a3 100644 --- a/winsup/cygwin/sec_helper.cc +++ b/winsup/cygwin/sec_helper.cc @@ -16,7 +16,6 @@ details. */ #include #include #include -#include #include #include #include diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 1acf80eb2..13913c95f 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -166,19 +166,16 @@ pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval tv; sigset_t oldset = myself->getsigmask (); + myfault efault; + if (efault.faulted (EFAULT)) + return -1; if (ts) { - if (check_invalid_read_struct_errno (ts)) - return -1; tv.tv_sec = ts->tv_sec; tv.tv_usec = ts->tv_nsec / 1000; } if (set) - { - if (check_invalid_read_struct_errno (set)) - return -1; - set_signal_mask (*set); - } + set_signal_mask (*set); int ret = cygwin_select (maxfds, readfds, writefds, exceptfds, ts ? &tv : NULL); if (set) diff --git a/winsup/cygwin/sem.cc b/winsup/cygwin/sem.cc index 1d7f53c67..ea617f664 100644 --- a/winsup/cygwin/sem.cc +++ b/winsup/cygwin/sem.cc @@ -21,6 +21,7 @@ details. */ #include "cygserver_ipc.h" #include "cygserver_sem.h" +#include "cygtls.h" /* * client_request_sem Constructors @@ -93,22 +94,8 @@ semctl (int semid, int semnum, int cmd, ...) } syscall_printf ("semctl (semid = %d, semnum = %d, cmd = %d, arg.val = 0x%x)", semid, semnum, cmd, arg.val); - if ((cmd == IPC_STAT || cmd == IPC_SET) - && __check_null_invalid_struct_errno (arg.buf, sizeof (struct semid_ds))) - return -1; - if (cmd == IPC_INFO) - { - /* semid == 0: Request for seminfo struct. */ - if (!semid - && __check_null_invalid_struct_errno (arg.buf, sizeof (struct seminfo))) - return -1; - /* Otherwise, request semid entries from internal semid_ds array. */ - if (semid) - if (__check_null_invalid_struct_errno (arg.buf, semid * sizeof (struct semid_ds))) - return -1; - } - if (cmd == SEM_INFO - && __check_null_invalid_struct_errno (arg.buf, sizeof (struct sem_info))) + myfault efault; + if (efault.faulted (EFAULT)) return -1; client_request_sem request (semid, semnum, cmd, &arg); if (request.make_request () == -1 || request.retval () == -1) @@ -156,7 +143,8 @@ semop (int semid, struct sembuf *sops, size_t nsops) #ifdef USE_SERVER syscall_printf ("semop (semid = %d, sops = %p, nsops = %d)", semid, sops, nsops); - if (__check_null_invalid_struct_errno (sops, nsops * sizeof (struct sembuf))) + myfault efault; + if (efault.faulted (EFAULT)) return -1; client_request_sem request (semid, sops, nsops); if (request.make_request () == -1 || request.retval () == -1) diff --git a/winsup/cygwin/shm.cc b/winsup/cygwin/shm.cc index 89846914a..f6cc30baf 100644 --- a/winsup/cygwin/shm.cc +++ b/winsup/cygwin/shm.cc @@ -22,6 +22,7 @@ details. */ #include "cygserver_ipc.h" #include "cygserver_shm.h" +#include "cygtls.h" /* * client_request_shm Constructors @@ -244,28 +245,9 @@ shmctl (int shmid, int cmd, struct shmid_ds *buf) #ifdef USE_SERVER syscall_printf ("shmctl (shmid = %d, cmd = %d, buf = 0x%x)", shmid, cmd, buf); - switch (cmd) - { - case IPC_STAT: - case IPC_SET: - if (__check_null_invalid_struct_errno (buf, sizeof (struct shmid_ds))) - return -1; - break; - case IPC_INFO: - /* shmid == 0: Request for shminfo struct. */ - if (!shmid - && __check_null_invalid_struct_errno (buf, sizeof (struct shminfo))) - return -1; - /* Otherwise, request shmid entries from internal shmid_ds array. */ - if (shmid) - if (__check_null_invalid_struct_errno (buf, shmid * sizeof (struct shmid_ds))) - return -1; - break; - case SHM_INFO: - if (__check_null_invalid_struct_errno (buf, sizeof (struct shm_info))) - return -1; - break; - } + myfault efault; + if (efault.faulted (EFAULT)) + return -1; client_request_shm request (shmid, cmd, buf); if (request.make_request () == -1 || request.retval () == -1) { diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 935083ce1..b3a0e31c1 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -147,17 +147,15 @@ handle_sigprocmask (int how, const sigset_t *set, sigset_t *oldset, sigset_t& op return -1; } + myfault efault; + if (efault.faulted (EFAULT)) + return -1; + if (oldset) - { - if (check_null_invalid_struct_errno (oldset)) - return -1; - *oldset = opmask; - } + *oldset = opmask; if (set) { - if (check_invalid_read_struct_errno (set)) - return -1; sigset_t newmask = opmask; switch (how) { diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 3f50a7b99..804965f36 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -550,7 +550,12 @@ open (const char *unix_path, int flags, ...) sig_dispatch_pending (); syscall_printf ("open (%s, %p)", unix_path, flags); - if (!check_null_empty_str_errno (unix_path)) + myfault efault; + if (efault.faulted (EFAULT)) + /* errno already set */; + else if (!*unix_path) + set_errno (ENOENT); + else { /* check for optional mode argument */ va_start (ap, flags); @@ -1008,7 +1013,8 @@ stat_worker (const char *name, struct __stat64 *buf, int nofollow) int res = -1; fhandler_base *fh = NULL; - if (check_null_invalid_struct_errno (buf)) + myfault efault; + if (efault.faulted (EFAULT)) goto error; if (!(fh = build_fh_name (name, NULL, nofollow ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW, @@ -1299,13 +1305,14 @@ system (const char *cmdstring) { pthread_testcancel (); - if (check_null_empty_str_errno (cmdstring)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; int res; const char* command[4]; - if (cmdstring == (const char *) NULL) + if (cmdstring == NULL) return 1; command[0] = "sh"; @@ -1437,11 +1444,17 @@ fpathconf (int fd, int v) extern "C" long int pathconf (const char *file, int v) { + myfault efault; + if (efault.faulted (EFAULT)) + return -1; + if (!*file) + { + set_errno (ENOENT); + return -1; + } switch (v) { case _PC_PATH_MAX: - if (check_null_empty_str_errno (file)) - return -1; return PATH_MAX - strlen (file); case _PC_NAME_MAX: return PATH_MAX; @@ -1483,8 +1496,9 @@ extern "C" int ttyname_r (int fd, char *buf, size_t buflen) { int ret = 0; - if (__check_null_invalid_struct (buf, buflen)) - ret = EINVAL; + myfault efault; + if (efault.faulted ()) + ret = EFAULT; else { cygheap_fdget cfd (fd, true); @@ -1713,9 +1727,14 @@ statvfs (const char *fname, struct statvfs *sfs) int ret = -1; char root[CYG_MAX_PATH]; - if (check_null_empty_str_errno (fname) - || check_null_invalid_struct_errno (sfs)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; + if (!*fname) + { + set_errno (ENOENT); + return -1; + } syscall_printf ("statfs %s", fname); @@ -1798,7 +1817,8 @@ fstatvfs (int fd, struct statvfs *sfs) extern "C" int statfs (const char *fname, struct statfs *sfs) { - if (check_null_invalid_struct_errno (sfs)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; struct statvfs vfs; int ret = statvfs (fname, &vfs); @@ -1837,33 +1857,27 @@ setpgid (pid_t pid, pid_t pgid) pgid = pid; if (pgid < 0) - { - set_errno (EINVAL); - goto out; - } + set_errno (EINVAL); else { pinfo p (pid, PID_MAP_RW); if (!p) - { - set_errno (ESRCH); - goto out; - } + set_errno (ESRCH); + else if (p->pgid == pgid) + res = 0; /* A process may only change the process group of itself and its children */ - if (p == myself || p->ppid == myself->pid) + else if (p != myself && p->ppid != myself->pid) + set_errno (EPERM); + else { p->pgid = pgid; if (p->pid != p->pgid) p->set_has_pgid_children (0); res = 0; - } - else - { - set_errno (EPERM); - goto out; + // init_console_handler (FALSE); } } -out: + syscall_printf ("pid %d, pgid %d, res %d", pid, pgid, res); return res; } @@ -1924,8 +1938,14 @@ mknod_worker (const char *path, mode_t type, mode_t mode, _major_t major, extern "C" int mknod32 (const char *path, mode_t mode, __dev32_t dev) { - if (check_null_empty_str_errno (path)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; + if (!*path) + { + set_errno (ENOENT); + return -1; + } if (strlen (path) >= CYG_MAX_PATH) return -1; @@ -2627,7 +2647,8 @@ endutent () extern "C" void utmpname (const char *file) { - if (check_null_empty_str (file)) + myfault efault; + if (efault.faulted () || !*file) { debug_printf ("Invalid file"); return; @@ -2678,7 +2699,8 @@ getutent () extern "C" struct utmp * getutid (struct utmp *id) { - if (check_null_invalid_struct_errno (id)) + myfault efault; + if (efault.faulted (EFAULT)) return NULL; if (utmp_fd < 0) { @@ -2716,7 +2738,8 @@ getutid (struct utmp *id) extern "C" struct utmp * getutline (struct utmp *line) { - if (check_null_invalid_struct_errno (line)) + myfault efault; + if (efault.faulted (EFAULT)) return NULL; if (utmp_fd < 0) { @@ -2738,7 +2761,8 @@ getutline (struct utmp *line) extern "C" struct utmp * pututline (struct utmp *ut) { - if (check_null_invalid_struct (ut)) + myfault efault; + if (efault.faulted (EFAULT)) return NULL; internal_setutent (true); if (utmp_fd < 0) @@ -2786,7 +2810,8 @@ getutxid (const struct utmpx *id) { static struct utmpx utx; - if (__check_invalid_read_ptr (id, sizeof *id)) + myfault efault; + if (efault.faulted (EFAULT)) return NULL; ((struct utmpx *)id)->ut_time = id->ut_tv.tv_sec; return copy_ut_to_utx (getutid ((struct utmp *) id), &utx); @@ -2797,7 +2822,8 @@ getutxline (const struct utmpx *line) { static struct utmpx utx; - if (__check_invalid_read_ptr (line, sizeof *line)) + myfault efault; + if (efault.faulted (EFAULT)) return NULL; ((struct utmpx *)line)->ut_time = line->ut_tv.tv_sec; return copy_ut_to_utx (getutline ((struct utmp *) line), &utx); @@ -2808,7 +2834,8 @@ pututxline (const struct utmpx *utmpx) { static struct utmpx utx; - if (__check_invalid_read_ptr (utmpx, sizeof *utmpx)) + myfault efault; + if (efault.faulted (EFAULT)) return NULL; ((struct utmpx *)utmpx)->ut_time = utmpx->ut_tv.tv_sec; return copy_ut_to_utx (pututline ((struct utmp *) utmpx), &utx); diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index c0a55dc31..2d5d273df 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -1771,7 +1771,8 @@ semaphore::_timedwait (const struct timespec *abstime) struct timeval tv; long waitlength; - if (__check_invalid_read_ptr (abstime, sizeof *abstime)) + myfault efault; + if (efault.faulted ()) { /* According to SUSv3, abstime need not be checked for validity, if the semaphore can be locked immediately. */ @@ -3233,9 +3234,8 @@ semaphore::post (sem_t *sem) int semaphore::getvalue (sem_t *sem, int *sval) { - - if (!is_good_object (sem) - || __check_null_invalid_struct (sval, sizeof (int))) + myfault efault; + if (efault.faulted () || !is_good_object (sem)) { set_errno (EINVAL); return -1; diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index 5f7b39845..9c1f8eed7 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -11,8 +11,8 @@ This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ -#ifndef _CYGNUS_THREADS_ -#define _CYGNUS_THREADS_ +#ifndef _THREAD_H +#define _THREAD_H #define LOCK_MMAP_LIST 1 @@ -707,4 +707,4 @@ struct MTinterface }; #define MT_INTERFACE user_data->threadinterface -#endif // _CYGNUS_THREADS_ +#endif // _THREAD_H diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index 0714eb160..b6f1b4cdd 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -216,10 +216,10 @@ timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalu return -1; } - if (__check_invalid_read_ptr_errno (value, sizeof (*value)) + myfault efault; + if (efault.faulted (EFAULT) || it_bad (value->it_value) - || it_bad (value->it_interval) - || (ovalue && check_null_invalid_struct_errno (ovalue))) + || it_bad (value->it_interval)) return -1; long long now = in_flags & TIMER_ABSTIME ? 0 : gtod.usecs (false); @@ -271,11 +271,12 @@ timer_tracker::gettime (itimerspec *ovalue) extern "C" int timer_gettime (timer_t timerid, struct itimerspec *ovalue) { - if (check_null_invalid_struct_errno (ovalue)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; timer_tracker *tt = (timer_tracker *) timerid; - if (check_null_invalid_struct (tt) || tt->magic != TT_MAGIC) + if (tt->magic != TT_MAGIC) { set_errno (EINVAL); return -1; @@ -288,8 +289,8 @@ timer_gettime (timer_t timerid, struct itimerspec *ovalue) extern "C" int timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid) { - if (evp && check_null_invalid_struct_errno (evp) - || check_null_invalid_struct_errno (timerid)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; if (clock_id != CLOCK_REALTIME) { @@ -306,7 +307,10 @@ timer_settime (timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue) { timer_tracker *tt = (timer_tracker *) timerid; - if (check_null_invalid_struct (tt) || tt->magic != TT_MAGIC) + myfault efault; + if (efault.faulted (EFAULT)) + return -1; + if (tt->magic != TT_MAGIC) { set_errno (EINVAL); return -1; @@ -319,7 +323,10 @@ extern "C" int timer_delete (timer_t timerid) { timer_tracker *in_tt = (timer_tracker *) timerid; - if (check_null_invalid_struct (in_tt) || in_tt->magic != TT_MAGIC) + myfault efault; + if (efault.faulted (EFAULT)) + return -1; + if (in_tt->magic != TT_MAGIC) { set_errno (EINVAL); return -1; @@ -386,7 +393,8 @@ getitimer (int which, struct itimerval *ovalue) set_errno (EINVAL); return -1; } - if (check_null_invalid_struct_errno (ovalue)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; struct itimerspec spec_ovalue; int ret = timer_gettime ((timer_t) &ttstart, &spec_ovalue); diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc index 708f48df6..aca27c6a5 100644 --- a/winsup/cygwin/times.cc +++ b/winsup/cygwin/times.cc @@ -53,7 +53,8 @@ times (struct tms *buf) { FILETIME creation_time, exit_time, kernel_time, user_time; - if (check_null_invalid_struct_errno (buf)) + myfault efault; + if (efault.faulted (EFAULT)) return ((clock_t) -1); DWORD ticks = GetTickCount (); diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h index bda6bd173..448f24f8f 100644 --- a/winsup/cygwin/tlsoffsets.h +++ b/winsup/cygwin/tlsoffsets.h @@ -1,117 +1,125 @@ //;# autogenerated: Do not edit. -//; $tls::sizeof__cygtls = 3972; -//; $tls::func = -3972; +//; $tls::sizeof__cygtls = 3980; +//; $tls::func = -3980; //; $tls::pfunc = 0; -//; $tls::saved_errno = -3968; +//; $tls::saved_errno = -3976; //; $tls::psaved_errno = 4; -//; $tls::sa_flags = -3964; +//; $tls::sa_flags = -3972; //; $tls::psa_flags = 8; -//; $tls::oldmask = -3960; +//; $tls::oldmask = -3968; //; $tls::poldmask = 12; -//; $tls::deltamask = -3956; +//; $tls::deltamask = -3964; //; $tls::pdeltamask = 16; -//; $tls::event = -3952; +//; $tls::event = -3960; //; $tls::pevent = 20; -//; $tls::errno_addr = -3948; +//; $tls::errno_addr = -3956; //; $tls::perrno_addr = 24; -//; $tls::initialized = -3944; +//; $tls::initialized = -3952; //; $tls::pinitialized = 28; -//; $tls::sigmask = -3940; +//; $tls::sigmask = -3948; //; $tls::psigmask = 32; -//; $tls::sigwait_mask = -3936; +//; $tls::sigwait_mask = -3944; //; $tls::psigwait_mask = 36; -//; $tls::sigwait_info = -3932; +//; $tls::sigwait_info = -3940; //; $tls::psigwait_info = 40; -//; $tls::threadkill = -3928; +//; $tls::threadkill = -3936; //; $tls::pthreadkill = 44; -//; $tls::infodata = -3924; +//; $tls::infodata = -3932; //; $tls::pinfodata = 48; -//; $tls::tid = -3776; +//; $tls::tid = -3784; //; $tls::ptid = 196; -//; $tls::local_clib = -3772; +//; $tls::local_clib = -3780; //; $tls::plocal_clib = 200; -//; $tls::__dontuse = -3772; +//; $tls::__dontuse = -3780; //; $tls::p__dontuse = 200; -//; $tls::locals = -2708; +//; $tls::locals = -2716; //; $tls::plocals = 1264; -//; $tls::_ctinfo = -1084; +//; $tls::_ctinfo = -1092; //; $tls::p_ctinfo = 2888; +//; $tls::_myfault = -1088; +//; $tls::p_myfault = 2892; +//; $tls::_myfault_errno = -1084; +//; $tls::p_myfault_errno = 2896; //; $tls::wq = -1080; -//; $tls::pwq = 2892; +//; $tls::pwq = 2900; //; $tls::prev = -1052; -//; $tls::pprev = 2920; +//; $tls::pprev = 2928; //; $tls::next = -1048; -//; $tls::pnext = 2924; +//; $tls::pnext = 2932; //; $tls::stackptr = -1044; -//; $tls::pstackptr = 2928; +//; $tls::pstackptr = 2936; //; $tls::sig = -1040; -//; $tls::psig = 2932; +//; $tls::psig = 2940; //; $tls::incyg = -1036; -//; $tls::pincyg = 2936; +//; $tls::pincyg = 2944; //; $tls::spinning = -1032; -//; $tls::pspinning = 2940; +//; $tls::pspinning = 2948; //; $tls::stacklock = -1028; -//; $tls::pstacklock = 2944; +//; $tls::pstacklock = 2952; //; $tls::stack = -1024; -//; $tls::pstack = 2948; +//; $tls::pstack = 2956; //; $tls::padding = 0; -//; $tls::ppadding = 3972; +//; $tls::ppadding = 3980; //; __DATA__ -#define tls_func (-3972) +#define tls_func (-3980) #define tls_pfunc (0) -#define tls_saved_errno (-3968) +#define tls_saved_errno (-3976) #define tls_psaved_errno (4) -#define tls_sa_flags (-3964) +#define tls_sa_flags (-3972) #define tls_psa_flags (8) -#define tls_oldmask (-3960) +#define tls_oldmask (-3968) #define tls_poldmask (12) -#define tls_deltamask (-3956) +#define tls_deltamask (-3964) #define tls_pdeltamask (16) -#define tls_event (-3952) +#define tls_event (-3960) #define tls_pevent (20) -#define tls_errno_addr (-3948) +#define tls_errno_addr (-3956) #define tls_perrno_addr (24) -#define tls_initialized (-3944) +#define tls_initialized (-3952) #define tls_pinitialized (28) -#define tls_sigmask (-3940) +#define tls_sigmask (-3948) #define tls_psigmask (32) -#define tls_sigwait_mask (-3936) +#define tls_sigwait_mask (-3944) #define tls_psigwait_mask (36) -#define tls_sigwait_info (-3932) +#define tls_sigwait_info (-3940) #define tls_psigwait_info (40) -#define tls_threadkill (-3928) +#define tls_threadkill (-3936) #define tls_pthreadkill (44) -#define tls_infodata (-3924) +#define tls_infodata (-3932) #define tls_pinfodata (48) -#define tls_tid (-3776) +#define tls_tid (-3784) #define tls_ptid (196) -#define tls_local_clib (-3772) +#define tls_local_clib (-3780) #define tls_plocal_clib (200) -#define tls___dontuse (-3772) +#define tls___dontuse (-3780) #define tls_p__dontuse (200) -#define tls_locals (-2708) +#define tls_locals (-2716) #define tls_plocals (1264) -#define tls__ctinfo (-1084) +#define tls__ctinfo (-1092) #define tls_p_ctinfo (2888) +#define tls__myfault (-1088) +#define tls_p_myfault (2892) +#define tls__myfault_errno (-1084) +#define tls_p_myfault_errno (2896) #define tls_wq (-1080) -#define tls_pwq (2892) +#define tls_pwq (2900) #define tls_prev (-1052) -#define tls_pprev (2920) +#define tls_pprev (2928) #define tls_next (-1048) -#define tls_pnext (2924) +#define tls_pnext (2932) #define tls_stackptr (-1044) -#define tls_pstackptr (2928) +#define tls_pstackptr (2936) #define tls_sig (-1040) -#define tls_psig (2932) +#define tls_psig (2940) #define tls_incyg (-1036) -#define tls_pincyg (2936) +#define tls_pincyg (2944) #define tls_spinning (-1032) -#define tls_pspinning (2940) +#define tls_pspinning (2948) #define tls_stacklock (-1028) -#define tls_pstacklock (2944) +#define tls_pstacklock (2952) #define tls_stack (-1024) -#define tls_pstack (2948) +#define tls_pstack (2956) #define tls_padding (0) -#define tls_ppadding (3972) +#define tls_ppadding (3980) diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index d63f93d3d..0e0da14e5 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -169,9 +169,9 @@ getlogin_r (char *name, size_t namesize) size_t len = strlen (login) + 1; if (len > namesize) return ERANGE; - int err = __check_null_invalid_struct (name, len); - if (err) - return err; + myfault efault; + if (efault.faulted ()) + return EFAULT; strncpy (name, login, len); return 0; } diff --git a/winsup/cygwin/uname.cc b/winsup/cygwin/uname.cc index daad40922..35cf75804 100644 --- a/winsup/cygwin/uname.cc +++ b/winsup/cygwin/uname.cc @@ -14,6 +14,7 @@ details. */ #include #include #include "cygwin_version.h" +#include "cygtls.h" /* uname: POSIX 4.4.1.1 */ extern "C" int @@ -21,7 +22,8 @@ uname (struct utsname *name) { SYSTEM_INFO sysinfo; - if (check_null_invalid_struct_errno (name)) + myfault efault; + if (efault.faulted (EFAULT)) return -1; char *snp = strstr (cygwin_version.dll_build_date, "SNP"); diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index fc9e9ec22..374e5052f 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -266,26 +266,11 @@ void __stdcall set_console_title (char *); void init_console_handler (BOOL); void init_global_security (); -int __stdcall check_null_str (const char *name) __attribute__ ((regparm(1))); -int __stdcall check_null_empty_str (const char *name) __attribute__ ((regparm(1))); -int __stdcall check_null_empty_str_errno (const char *name) __attribute__ ((regparm(1))); -int __stdcall check_null_str_errno (const char *name) __attribute__ ((regparm(1))); -int __stdcall __check_null_invalid_struct (void *s, unsigned sz) __attribute__ ((regparm(2))); -int __stdcall __check_null_invalid_struct_errno (void *s, unsigned sz) __attribute__ ((regparm(2))); -int __stdcall __check_invalid_read_ptr (const void *s, unsigned sz) __attribute__ ((regparm(2))); -int __stdcall __check_invalid_read_ptr_errno (const void *s, unsigned sz) __attribute__ ((regparm(2))); int __stdcall check_invalid_virtual_addr (const void *s, unsigned sz) __attribute__ ((regparm(2))); -#define check_null_invalid_struct(s) \ - __check_null_invalid_struct ((s), sizeof (*(s))) -#define check_null_invalid_struct_errno(s) \ - __check_null_invalid_struct_errno ((s), sizeof (*(s))) -#define check_invalid_read_struct_errno(s) \ - __check_invalid_read_ptr_errno ((s), sizeof (*(s))) - -struct iovec; -ssize_t check_iovec_for_read (const struct iovec *, int) __attribute__ ((regparm(2))); -ssize_t check_iovec_for_write (const struct iovec *, int) __attribute__ ((regparm(2))); +ssize_t check_iovec (const struct iovec *, int, bool) __attribute__ ((regparm(3))); +#define check_iovec_for_read(a, b) check_iovec ((a), (b), false) +#define check_iovec_for_write(a, b) check_iovec ((a), (b), true) #define set_winsock_errno() __set_winsock_errno (__FUNCTION__, __LINE__) void __set_winsock_errno (const char *fn, int ln) __attribute__ ((regparm(2))); -- cgit v1.2.3