diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/conf/options | 3 | ||||
-rw-r--r-- | sys/kern/vfs_extattr.c | 6 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 6 | ||||
-rw-r--r-- | sys/sys/mount.h | 41 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 104 |
5 files changed, 134 insertions, 26 deletions
diff --git a/sys/conf/options b/sys/conf/options index e89580c..89f1552 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -1,4 +1,4 @@ -# $Id: options,v 1.36 1997/10/18 01:15:32 peter Exp $ +# $Id: options,v 1.37 1997/11/05 20:17:06 joerg Exp $ # Format: # Option name filename @@ -9,6 +9,7 @@ DDB DDB_UNATTENDED opt_ddb.h GDB_REMOTE_CHAT opt_ddb.h DEVFS_ROOT opt_devfs.h +SUIDDIR KTRACE QUOTA SYSVMSG opt_sysvipc.h diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 5e1fa19..eb8cb4e 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 - * $Id: vfs_syscalls.c,v 1.80 1997/11/06 19:29:30 phk Exp $ + * $Id: vfs_syscalls.c,v 1.81 1997/11/12 05:42:17 julian Exp $ */ /* @@ -261,10 +261,10 @@ update: mp->mnt_kern_flag |= MNTK_WANTRDWR; mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOATIME | - MNT_NOCLUSTERR | MNT_NOCLUSTERW); + MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR); mp->mnt_flag |= SCARG(uap, flags) & (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_FORCE | - MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW); + MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR); /* * Mount the filesystem. */ diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 5e1fa19..eb8cb4e 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 - * $Id: vfs_syscalls.c,v 1.80 1997/11/06 19:29:30 phk Exp $ + * $Id: vfs_syscalls.c,v 1.81 1997/11/12 05:42:17 julian Exp $ */ /* @@ -261,10 +261,10 @@ update: mp->mnt_kern_flag |= MNTK_WANTRDWR; mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOATIME | - MNT_NOCLUSTERR | MNT_NOCLUSTERW); + MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR); mp->mnt_flag |= SCARG(uap, flags) & (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_FORCE | - MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW); + MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR); /* * Mount the filesystem. */ diff --git a/sys/sys/mount.h b/sys/sys/mount.h index d787a01..25895ae 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)mount.h 8.21 (Berkeley) 5/20/95 - * $Id: mount.h,v 1.48 1997/10/12 20:26:02 phk Exp $ + * $Id: mount.h,v 1.49 1997/11/12 05:42:23 julian Exp $ */ #ifndef _SYS_MOUNT_H_ @@ -146,7 +146,7 @@ struct mount { struct vnode *mnt_vnodecovered; /* vnode we mounted on */ struct vnodelst mnt_vnodelist; /* list of vnodes this mount */ struct lock mnt_lock; /* mount structure lock */ - int mnt_flag; /* exported flags */ + int mnt_flag; /* flags shared with user */ int mnt_kern_flag; /* kernel only flags */ int mnt_maxsymlinklen; /* max size of short symlink */ struct statfs mnt_stat; /* cache of filesystem stats */ @@ -155,9 +155,7 @@ struct mount { }; /* - * Mount flags. - * - * Unmount uses MNT_FORCE flag. + * User specifiable flags. */ #define MNT_RDONLY 0x00000001 /* read only filesystem */ #define MNT_SYNCHRONOUS 0x00000002 /* file system written synchronously */ @@ -166,12 +164,13 @@ struct mount { #define MNT_NODEV 0x00000010 /* don't interpret special files */ #define MNT_UNION 0x00000020 /* union with underlying filesystem */ #define MNT_ASYNC 0x00000040 /* file system written asynchronously */ +#define MNT_SUIDDIR 0x00100000 /* Disable cluster read */ #define MNT_NOATIME 0x10000000 /* Disable update of file access time */ #define MNT_NOCLUSTERR 0x40000000 /* Disable cluster read */ #define MNT_NOCLUSTERW 0x80000000 /* Disable cluster read */ /* - * exported mount flags. + * NFS export related mount flags. */ #define MNT_EXRDONLY 0x00000080 /* exported read only */ #define MNT_EXPORTED 0x00000100 /* file system is exported */ @@ -181,7 +180,9 @@ struct mount { #define MNT_EXPUBLIC 0x20000000 /* public export (WebNFS) */ /* - * Flags set by internal operations. + * Flags set by internal operations, + * but visible to the user. + * XXX some of these are not quite right.. (I've never seen the root flag set) */ #define MNT_LOCAL 0x00001000 /* filesystem is stored locally */ #define MNT_QUOTA 0x00002000 /* quotas are enabled on filesystem */ @@ -190,25 +191,31 @@ struct mount { /* * Mask of flags that are visible to statfs() + * XXX I think that this could now become (~(MNT_CMDFLAGS)) + * but the 'mount' program may need changing to handle this. + * XXX MNT_EXPUBLIC is presently left out. I don't know why. */ -#define MNT_VISFLAGMASK (MNT_RDONLY|MNT_SYNCHRONOUS|MNT_NOEXEC|MNT_NOSUID| \ - MNT_NODEV|MNT_UNION|MNT_ASYNC|MNT_EXRDONLY| \ - MNT_EXPORTED|MNT_DEFEXPORTED|MNT_EXPORTANON| \ - MNT_EXKERB|MNT_LOCAL|MNT_USER|MNT_QUOTA|MNT_ROOTFS| \ - MNT_NOATIME|MNT_NOCLUSTERR|MNT_NOCLUSTERW \ - /* | MNT_EXPUBLIC */) - +#define MNT_VISFLAGMASK (MNT_RDONLY | MNT_SYNCHRONOUS | MNT_NOEXEC | \ + MNT_NOSUID | MNT_NODEV | MNT_UNION | \ + MNT_ASYNC | MNT_EXRDONLY | MNT_EXPORTED | \ + MNT_DEFEXPORTED | MNT_EXPORTANON| MNT_EXKERB | \ + MNT_LOCAL | MNT_USER | MNT_QUOTA | \ + MNT_ROOTFS | MNT_NOATIME | MNT_NOCLUSTERR| \ + MNT_NOCLUSTERW | MNT_SUIDDIR/* | MNT_EXPUBLIC */) /* - * External filesystem control flags. + * External filesystem command modifier flags. + * Unmount can use the MNT_FORCE flag. + * XXX These are not STATES and really should be somewhere else. */ #define MNT_UPDATE 0x00010000 /* not a real mount, just an update */ #define MNT_DELEXPORT 0x00020000 /* delete export host lists */ #define MNT_RELOAD 0x00040000 /* reload filesystem data */ #define MNT_FORCE 0x00080000 /* force unmount or readonly change */ +#define MNT_CMDFLAGS (MNT_UPDATE|MNT_DELEXPORT|MNT_RELOAD|MNT_FORCE) /* - * Internal filesystem control flags. + * Internal filesystem control flags stored in mnt_kern_flag. * - * MNT_UNMOUNT locks the mount entry so that name lookup cannot proceed + * MNTK_UNMOUNT locks the mount entry so that name lookup cannot proceed * past the mount point. This keeps the subtree stable during mounts * and unmounts. */ diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index bc13a05..613fe5d 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 - * $Id: ufs_vnops.c,v 1.64 1997/10/26 20:55:39 phk Exp $ + * $Id: ufs_vnops.c,v 1.65 1997/10/27 13:33:47 bde Exp $ */ #include "opt_quota.h" @@ -1329,8 +1329,57 @@ ufs_mkdir(ap) if (error) goto out; ip = VTOI(tvp); - ip->i_uid = cnp->cn_cred->cr_uid; ip->i_gid = dp->i_gid; +#ifdef SUIDDIR + { +#ifdef QUOTA + struct ucred ucred, *ucp; + ucp = cnp->cn_cred +#endif I + /* + * if we are hacking owners here, (only do this where told to) + * and we are not giving it TOO root, (would subvert quotas) + * then go ahead and give it to the other user. + * The new directory also inherits the SUID bit. + * If user's UID an ddir UID are the same, + * 'give it away' so that the SUID is still forced on. + */ + if ( (dvp->v_mount->mnt_flag & MNT_SUIDDIR) && + (dp->i_mode & ISUID) && dp->i_uid) { + dmode |= ISUID; + ip->i_uid = dp->i_uid; +#ifdef QUOTA + if (pdir->i_uid != cnp->cn_cred->cr_uid) { + /* + * make sure the correct user gets charged + * for the space. + * Make a dummy credential for the victim. + * XXX This seems to never be accessed out of + * our context so a stack variable is ok. + */ + ucred.cr_ref = 1 + ucred.cr_uid = ip->i_uid; + ucred.cr_ngroups = 1 + ucred.cr_groups[0] = dp->i_gid; + ucp = *ucred; + } +#endif I + } else { + ip->i_uid = cnp->cn_cred->cr_uid; + } +#ifdef QUOTA + if ((error = getinoquota(ip)) || + (error = chkiq(ip, 1, ucp, 0))) { + free(cnp->cn_pnbuf, M_NAMEI); + VOP_VFREE(tvp, ip->i_number, dmode); + vput(tvp); + vput(dvp); + return (error); + } +#endif + } +#else + ip->i_uid = cnp->cn_cred->cr_uid; #ifdef QUOTA if ((error = getinoquota(ip)) || (error = chkiq(ip, 1, cnp->cn_cred, 0))) { @@ -1341,6 +1390,7 @@ ufs_mkdir(ap) return (error); } #endif +#endif ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; ip->i_mode = dmode; tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */ @@ -2007,6 +2057,55 @@ ufs_makeinode(mode, dvp, vpp, cnp) } ip = VTOI(tvp); ip->i_gid = pdir->i_gid; +#ifdef SUIDDIR + { +#ifdef QUOTA + struct ucred ucred, *ucp; + ucp = cnp->cn_cred +#endif I + /* + * if we are + * not the owner of the directory, + * and we are hacking owners here, (only do this where told to) + * and we are not giving it TOO root, (would subvert quotas) + * then go ahead and give it to the other user. + * Note that this drops off the execute bits for security. + */ + if ( (dvp->v_mount->mnt_flag & MNT_SUIDDIR) && + (pdir->i_mode & ISUID) && + (pdir->i_uid != cnp->cn_cred->cr_uid) && pdir->i_uid) { + ip->i_uid = pdir->i_uid; + mode &= ~07111; +#ifdef QUOTA + /* + * make sure the correct user gets charged + * for the space. + * Quickly knock up a dummy credential for the victim. + * XXX This seems to never be accessed out of our + * context so a stack variable is ok. + */ + ucred.cr_ref = 1 + ucred.cr_uid = ip->i_uid; + ucred.cr_ngroups = 1 + ucred.cr_groups[0] = pdir->i_gid; + ucp = *ucred; +#endif I + } else { + ip->i_uid = cnp->cn_cred->cr_uid; + } + +#ifdef QUOTA + if ((error = getinoquota(ip)) || + (error = chkiq(ip, 1, ucp, 0))) { + free(cnp->cn_pnbuf, M_NAMEI); + VOP_VFREE(tvp, ip->i_number, mode); + vput(tvp); + vput(dvp); + return (error); + } +#endif + } +#else ip->i_uid = cnp->cn_cred->cr_uid; #ifdef QUOTA if ((error = getinoquota(ip)) || @@ -2018,6 +2117,7 @@ ufs_makeinode(mode, dvp, vpp, cnp) return (error); } #endif +#endif ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; ip->i_mode = mode; tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */ |