This is the second in a series of eight patches to the BSD Secure Levels LSM. It allows setuid and setgid on directories. It also disallows the creation of setuid/setgid executables via open or mknod. Thanks to Brad Spengler for the suggestion.
Signed off by: Michael Halcrow <[EMAIL PROTECTED]>
Index: linux-2.6.11-rc2-mm1-modules/security/seclvl.c =================================================================== --- linux-2.6.11-rc2-mm1-modules.orig/security/seclvl.c 2005-02-03 15:14:54.907684456 -0600 +++ linux-2.6.11-rc2-mm1-modules/security/seclvl.c 2005-02-03 15:36:43.925683472 -0600 @@ -552,7 +552,11 @@ static int seclvl_inode_setattr(struct dentry *dentry, struct iattr *iattr) { if (seclvl > 0) { - if (iattr->ia_valid & ATTR_MODE) + if (dentry && dentry->d_inode + && S_ISDIR(dentry->d_inode->i_mode)) { + return 0; + } + if (iattr && iattr->ia_valid & ATTR_MODE) if (iattr->ia_mode & S_ISUID || iattr->ia_mode & S_ISGID) { seclvl_printk(1, KERN_WARNING "%s: Attempt to " @@ -565,6 +569,36 @@ return 0; } +/** + * Prevent an end-run around the inode_setattr control. + */ +static int seclvl_inode_mknod (struct inode * inode, struct dentry * dentry, + int mode, dev_t dev) +{ + if (seclvl > 0 && (mode & 02000 || mode & 04000)) { + seclvl_printk(1, KERN_WARNING "%s: Attempt to mknod with suid " + "or guid bit set in seclvl [%d]\n", __FUNCTION__, + seclvl ); + return -EPERM; + } + return 0; +} + +/** + * Prevent an end-run around the inode_setattr control. + */ +static int +seclvl_inode_create (struct inode * inode, struct dentry * dentry, int mask) +{ + if (seclvl > 0 && (mask & 02000 || mask & 04000)) { + seclvl_printk(1, KERN_WARNING "%s: Attempt to " + "create inode with suid or guid bit set in " + "seclvl [%d]\n", __FUNCTION__, seclvl ); + return -EPERM; + } + return 0; +} + /* release busied block devices */ static void seclvl_file_free_security(struct file *filp) { @@ -598,6 +632,8 @@ .capable = seclvl_capable, .inode_permission = seclvl_inode_permission, .inode_setattr = seclvl_inode_setattr, + .inode_mknod = seclvl_inode_mknod, + .inode_create = seclvl_inode_create, .file_free_security = seclvl_file_free_security, .settime = seclvl_settime, .sb_umount = seclvl_umount,