X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fattr.c;h=89e03f7bb497ee4243a878d928974d18ed4c5825;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=5bb63a85541f2af338d82258ad20eb5bd2422359;hpb=a8e794ca871505c8ea96cc102f4ad555c5231d7f;p=linux-2.6.git diff --git a/fs/attr.c b/fs/attr.c index 5bb63a855..89e03f7bb 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -14,6 +14,9 @@ #include #include #include +#include +#include +#include /* Taken over from the old code... */ @@ -35,7 +38,8 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) /* Make sure caller can chgrp. */ if ((ia_valid & ATTR_GID) && - (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid) && + (current->fsuid != inode->i_uid || + (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) && !capable(CAP_CHOWN)) goto error; @@ -54,6 +58,31 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER)) goto error; } + + /* Check for evil vserver activity */ + if (vx_check(0, VX_ADMIN)) + goto fine; + + if (IS_BARRIER(inode)) { + printk(KERN_WARNING + "VSW: xid=%d messing with the barrier.\n", + vx_current_xid()); + goto error; + } + switch (inode->i_sb->s_magic) { + case PROC_SUPER_MAGIC: + printk(KERN_WARNING + "VSW: xid=%d messing with the procfs.\n", + vx_current_xid()); + goto error; + case DEVPTS_SUPER_MAGIC: + if (vx_check(inode->i_xid, VX_IDENT)) + goto fine; + printk(KERN_WARNING + "VSW: xid=%d messing with the devpts.\n", + vx_current_xid()); + goto error; + } fine: retval = 0; error: @@ -103,6 +132,8 @@ int inode_setattr(struct inode * inode, struct iattr * attr) inode->i_uid = attr->ia_uid; if (ia_valid & ATTR_GID) inode->i_gid = attr->ia_gid; + if (ia_valid & ATTR_XID) + inode->i_xid = attr->ia_xid; if (ia_valid & ATTR_ATIME) inode->i_atime = attr->ia_atime; if (ia_valid & ATTR_MTIME) @@ -133,6 +164,8 @@ int setattr_mask(unsigned int ia_valid) dn_mask |= DN_ATTRIB; if (ia_valid & ATTR_GID) dn_mask |= DN_ATTRIB; + if (ia_valid & ATTR_XID) + dn_mask |= DN_ATTRIB; if (ia_valid & ATTR_SIZE) dn_mask |= DN_MODIFY; /* both times implies a utime(s) call */ @@ -196,7 +229,8 @@ int notify_change(struct dentry * dentry, struct iattr * attr) error = security_inode_setattr(dentry, attr); if (!error) { if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || - (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) + (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) || + (ia_valid & ATTR_XID && attr->ia_xid != inode->i_xid)) error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; if (!error) error = inode_setattr(inode, attr);