diff options
author | Miles Bader <miles@gnu.org> | 1996-07-26 19:42:18 +0000 |
---|---|---|
committer | Miles Bader <miles@gnu.org> | 1996-07-26 19:42:18 +0000 |
commit | 797a097739bb3e6609f3e3ea089f3790a1e29056 (patch) | |
tree | 7067748eca933f37d00a399f0526c1366e9b95c4 /libdiskfs/file-exec.c | |
parent | 86724e84237219a01acf4d4a0a621b009a159824 (diff) |
(diskfs_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.
Initialize ERR.
Diffstat (limited to 'libdiskfs/file-exec.c')
-rw-r--r-- | libdiskfs/file-exec.c | 56 |
1 files changed, 27 insertions, 29 deletions
diff --git a/libdiskfs/file-exec.c b/libdiskfs/file-exec.c index 7cde0e37..c21f12e1 100644 --- a/libdiskfs/file-exec.c +++ b/libdiskfs/file-exec.c @@ -48,9 +48,12 @@ diskfs_S_file_exec (struct protid *cred, u_int destroynameslen) { struct node *np; - error_t err; - struct protid *newpi; + uid_t uid; + gid_t gid; + mode_t mode; int suid, sgid; + struct protid *newpi; + error_t err = 0; if (!cred) return EOPNOTSUPP; @@ -63,29 +66,23 @@ diskfs_S_file_exec (struct protid *cred, np = cred->po->np; mutex_lock (&np->lock); + mode = np->dn_stat.st_mode; + uid = np->dn_stat.st_uid; + gid = np->dn_stat.st_uid; + mutex_unlock (&np->lock); if ((cred->po->openstat & O_EXEC) == 0) - { - mutex_unlock (&np->lock); - return EBADF; - } + return EBADF; - if (!((np->dn_stat.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) - || ((np->dn_stat.st_mode & S_IUSEUNK) - && (np->dn_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->dn_stat.st_mode & S_IFMT) == S_IFDIR) - { - mutex_unlock (&np->lock); - return EACCES; - } + if ((mode & S_IFMT) == S_IFDIR) + return EACCES; - suid = np->dn_stat.st_mode & S_ISUID; - sgid = np->dn_stat.st_mode & S_ISGID; + suid = mode & S_ISUID; + sgid = mode & S_ISGID; if (suid || sgid) { int secure = 0; @@ -96,9 +93,10 @@ diskfs_S_file_exec (struct protid *cred, err = idvec_merge_ids (gids, cred->gids, cred->ngids); return err; } - fshelp_exec_reauth (suid, np->dn_stat.st_uid, sgid, np->dn_stat.st_gid, - diskfs_auth_server_port, get_file_ids, - portarray, portarraylen, fds, fdslen, &secure); + err = + fshelp_exec_reauth (suid, uid, sgid, gid, + diskfs_auth_server_port, get_file_ids, + portarray, portarraylen, fds, fdslen, &secure); if (secure) flags |= EXEC_SECURE | EXEC_NEWTASK; } @@ -113,12 +111,12 @@ diskfs_S_file_exec (struct protid *cred, flags |= EXEC_NEWTASK; #endif - err = diskfs_create_protid (diskfs_make_peropen (np, O_READ, - cred->po->dotdotport), - cred->uids, cred->nuids, - cred->gids, cred->ngids, - &newpi); - mutex_unlock (&np->lock); + if (! err) + err = diskfs_create_protid (diskfs_make_peropen (np, O_READ, + cred->po->dotdotport), + cred->uids, cred->nuids, + cred->gids, cred->ngids, + &newpi); if (! err) { |