diff options
author | Miles Bader <miles@gnu.org> | 1996-07-26 19:43:16 +0000 |
---|---|---|
committer | Miles Bader <miles@gnu.org> | 1996-07-26 19:43:16 +0000 |
commit | 14d2b70801d0d2da70241066ab54b65776891ff7 (patch) | |
tree | c7588991ca76bfafe7039f8dfb64e63457c2a3ff /libnetfs/file-exec.c | |
parent | 797a097739bb3e6609f3e3ea089f3790a1e29056 (diff) |
(netfs_S_file_exec):
Unlock NP before we attempt to do setuid/setgid (which otherwise can
deadlock during port reauth).
Pay attention to the error code returned by fshelp_exec_reauth, and don't
make NEWPI if it's an error.
Diffstat (limited to 'libnetfs/file-exec.c')
-rw-r--r-- | libnetfs/file-exec.c | 61 |
1 files changed, 27 insertions, 34 deletions
diff --git a/libnetfs/file-exec.c b/libnetfs/file-exec.c index af882028..7268e7c7 100644 --- a/libnetfs/file-exec.c +++ b/libnetfs/file-exec.c @@ -51,7 +51,9 @@ netfs_S_file_exec (struct protid *cred, { struct node *np; error_t err; - struct protid *newpi; + uid_t uid; + gid_t gid; + mode_t mode; int suid, sgid; if (!cred) @@ -61,40 +63,31 @@ netfs_S_file_exec (struct protid *cred, _netfs_exec = file_name_lookup (_SERVERS_EXEC, 0, 0); if (_netfs_exec == MACH_PORT_NULL) return EOPNOTSUPP; + + if ((cred->po->openstat & O_EXEC) == 0) + return EBADF; np = cred->po->np; mutex_lock (&np->lock); - - if ((cred->po->openstat & O_EXEC) == 0) - { - mutex_unlock (&np->lock); - return EBADF; - } - + mode = np->nn_stat.st_mode; + uid = np->nn_stat.st_uid; + gid = np->nn_stat.st_gid; err = netfs_validate_stat (np, cred->credential); + mutex_unlock (&np->lock); + if (err) - { - mutex_unlock (&np->lock); - return err; - } + return err; - if (!((np->nn_stat.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) - || ((np->nn_stat.st_mode & S_IUSEUNK) - && (np->nn_stat.st_mode & (S_IEXEC << S_IUNKSHIFT))))) - { - mutex_unlock (&np->lock); - return EACCES; - } + if (!((mode & (S_IXUSR|S_IXGRP|S_IXOTH)) + || ((mode & S_IUSEUNK) && (mode & (S_IEXEC << S_IUNKSHIFT))))) + return EACCES; - if ((np->nn_stat.st_mode & S_IFMT) == S_IFDIR) - { - mutex_unlock (&np->lock); - return EACCES; - } + if ((mode & S_IFMT) == S_IFDIR) + return EACCES; - suid = np->nn_stat.st_mode & S_ISUID; - sgid = np->nn_stat.st_mode & S_ISGID; + suid = mode & S_ISUID; + sgid = mode & S_ISGID; if (suid || sgid) { int secure = 0; @@ -114,9 +107,10 @@ netfs_S_file_exec (struct protid *cred, free (gids); return err; } - fshelp_exec_reauth (suid, np->nn_stat.st_uid, sgid, np->nn_stat.st_gid, - netfs_auth_server_port, get_file_ids, - portarray, portarraylen, fds, fdslen, &secure); + err = + fshelp_exec_reauth (suid, uid, sgid, gid, + netfs_auth_server_port, get_file_ids, + portarray, portarraylen, fds, fdslen, &secure); if (secure) flags |= EXEC_SECURE | EXEC_NEWTASK; } @@ -131,13 +125,12 @@ netfs_S_file_exec (struct protid *cred, flags |= EXEC_NEWTASK; #endif - newpi = netfs_make_protid (netfs_make_peropen (np, O_READ, - cred->po->dotdotport), - netfs_copy_credential (cred->credential)); - mutex_unlock (&np->lock); - if (! err) { + struct protid *newpi = + netfs_make_protid (netfs_make_peropen (np, O_READ, + cred->po->dotdotport), + netfs_copy_credential (cred->credential)); err = exec_exec (_netfs_exec, ports_get_right (newpi), MACH_MSG_TYPE_MAKE_SEND, |