X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fattr.c;h=3317d4fe522014a6908d27211aeec8feda86501e;hb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;hp=34dcb1a87d087607e5f6973c2a71e8d193c67d14;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/fs/attr.c b/fs/attr.c index 34dcb1a87..3317d4fe5 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -14,6 +14,10 @@ #include #include #include +#include +#include +#include +#include /* Taken over from the old code... */ @@ -35,7 +39,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 +59,28 @@ 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)) { + vxwprintk(1, "xid=%d messing with the barrier.", + vx_current_xid()); + goto error; + } + switch (inode->i_sb->s_magic) { + case PROC_SUPER_MAGIC: + vxwprintk(1, "xid=%d messing with the procfs.", + vx_current_xid()); + goto error; + case DEVPTS_SUPER_MAGIC: + if (vx_check(inode->i_xid, VX_IDENT)) + goto fine; + vxwprintk(1, "xid=%d messing with the devpts.", + vx_current_xid()); + goto error; + } fine: retval = 0; error: @@ -106,11 +133,14 @@ int inode_setattr(struct inode * inode, struct iattr * attr) if (ia_valid & ATTR_XID) inode->i_xid = attr->ia_xid; if (ia_valid & ATTR_ATIME) - inode->i_atime = attr->ia_atime; + inode->i_atime = timespec_trunc(attr->ia_atime, + inode->i_sb->s_time_gran); if (ia_valid & ATTR_MTIME) - inode->i_mtime = attr->ia_mtime; + inode->i_mtime = timespec_trunc(attr->ia_mtime, + inode->i_sb->s_time_gran); if (ia_valid & ATTR_CTIME) - inode->i_ctime = attr->ia_ctime; + inode->i_ctime = timespec_trunc(attr->ia_ctime, + inode->i_sb->s_time_gran); if (ia_valid & ATTR_MODE) { umode_t mode = attr->ia_mode; @@ -154,14 +184,17 @@ int setattr_mask(unsigned int ia_valid) int notify_change(struct dentry * dentry, struct iattr * attr) { struct inode *inode = dentry->d_inode; - mode_t mode = inode->i_mode; + mode_t mode; int error; - struct timespec now = CURRENT_TIME; + struct timespec now; unsigned int ia_valid = attr->ia_valid; if (!inode) BUG(); + mode = inode->i_mode; + now = current_fs_time(inode->i_sb); + attr->ia_ctime = now; if (!(ia_valid & ATTR_ATIME_SET)) attr->ia_atime = now; @@ -190,6 +223,9 @@ int notify_change(struct dentry * dentry, struct iattr * attr) if (!attr->ia_valid) return 0; + if (ia_valid & ATTR_SIZE) + down_write(&dentry->d_inode->i_alloc_sem); + if (inode->i_op && inode->i_op->setattr) { error = security_inode_setattr(dentry, attr); if (!error) @@ -207,6 +243,10 @@ int notify_change(struct dentry * dentry, struct iattr * attr) error = inode_setattr(inode, attr); } } + + if (ia_valid & ATTR_SIZE) + up_write(&dentry->d_inode->i_alloc_sem); + if (!error) { unsigned long dn_mask = setattr_mask(ia_valid); if (dn_mask)