--- linux-2.6.11-rc1/fs/attr.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/attr.c 2005-01-15 12:34:10 +0100 @@ -87,6 +130,8 @@ int inode_setattr(struct inode * inode, 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 = timespec_trunc(attr->ia_atime, inode->i_sb->s_time_gran); --- linux-2.6.11-rc1/fs/attr.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/attr.c 2005-01-15 12:34:10 +0100 @@ -118,6 +165,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 */ --- linux-2.6.11-rc1/fs/attr.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/attr.c 2005-01-15 12:34:10 +0100 @@ -184,7 +233,8 @@ int notify_change(struct dentry * dentry 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); --- linux-2.6.11-rc1/fs/ext2/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext2/inode.c 2005-01-15 11:27:52 +0100 @@ -1028,6 +1040,8 @@ void ext2_read_inode (struct inode * ino ino_t ino = inode->i_ino; struct buffer_head * bh; struct ext2_inode * raw_inode = ext2_get_inode(inode->i_sb, ino, &bh); + uid_t uid; + gid_t gid; int n; #ifdef CONFIG_EXT2_FS_POSIX_ACL --- linux-2.6.11-rc1/fs/ext2/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext2/inode.c 2005-01-15 11:27:52 +0100 @@ -1038,12 +1052,17 @@ void ext2_read_inode (struct inode * ino goto bad_inode; inode->i_mode = le16_to_cpu(raw_inode->i_mode); - inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); - inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); + uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); + gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); if (!(test_opt (inode->i_sb, NO_UID32))) { - inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; - inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; + uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; + gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; } + inode->i_uid = INOXID_UID(XID_TAG(inode), uid, gid); + inode->i_gid = INOXID_GID(XID_TAG(inode), uid, gid); + inode->i_xid = INOXID_XID(XID_TAG(inode), uid, gid, + le16_to_cpu(raw_inode->i_raw_xid)); + inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); inode->i_size = le32_to_cpu(raw_inode->i_size); inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime); --- linux-2.6.11-rc1/fs/ext2/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext2/inode.c 2005-01-15 11:27:52 +0100 @@ -1136,8 +1155,8 @@ static int ext2_update_inode(struct inod struct ext2_inode_info *ei = EXT2_I(inode); struct super_block *sb = inode->i_sb; ino_t ino = inode->i_ino; - uid_t uid = inode->i_uid; - gid_t gid = inode->i_gid; + uid_t uid = XIDINO_UID(XID_TAG(inode), inode->i_uid, inode->i_xid); + gid_t gid = XIDINO_GID(XID_TAG(inode), inode->i_gid, inode->i_xid); struct buffer_head * bh; struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh); int n; --- linux-2.6.11-rc1/fs/ext2/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext2/inode.c 2005-01-15 11:27:52 +0100 @@ -1172,6 +1191,9 @@ static int ext2_update_inode(struct inod raw_inode->i_uid_high = 0; raw_inode->i_gid_high = 0; } +#ifdef CONFIG_INOXID_INTERN + raw_inode->i_raw_xid = cpu_to_le16(inode->i_xid); +#endif raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); raw_inode->i_size = cpu_to_le32(inode->i_size); raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec); --- linux-2.6.11-rc1/fs/ext2/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext2/inode.c 2005-01-15 11:27:52 +0100 @@ -1258,11 +1301,15 @@ int ext2_setattr(struct dentry *dentry, if (error) return error; if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || - (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { + (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) || + (iattr->ia_valid & ATTR_XID && iattr->ia_xid != inode->i_xid)) { error = DQUOT_TRANSFER(inode, iattr) ? -EDQUOT : 0; if (error) return error; } + if (iattr->ia_valid & ATTR_ATTR_FLAG) + ext2_setattr_flags(inode, iattr->ia_attr_flags); + error = inode_setattr(inode, iattr); if (!error && (iattr->ia_valid & ATTR_MODE)) error = ext2_acl_chmod(inode); --- linux-2.6.11-rc1/fs/ext2/namei.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext2/namei.c 2005-01-15 11:27:52 +0100 @@ -81,6 +82,7 @@ static struct dentry *ext2_lookup(struct inode = iget(dir->i_sb, ino); if (!inode) return ERR_PTR(-EACCES); + vx_propagate_xid(nd, inode); } if (inode) return d_splice_alias(inode, dentry); --- linux-2.6.11-rc1/fs/ext2/super.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext2/super.c 2005-01-15 11:27:52 +0100 @@ -259,7 +259,7 @@ enum { Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, Opt_nobh, - Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, + Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_tagxid, Opt_ignore, Opt_err, }; --- linux-2.6.11-rc1/fs/ext2/super.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext2/super.c 2005-01-15 11:27:52 +0100 @@ -288,6 +288,7 @@ static match_table_t tokens = { {Opt_nouser_xattr, "nouser_xattr"}, {Opt_acl, "acl"}, {Opt_noacl, "noacl"}, + {Opt_tagxid, "tagxid"}, {Opt_ignore, "grpquota"}, {Opt_ignore, "noquota"}, {Opt_ignore, "quota"}, --- linux-2.6.11-rc1/fs/ext2/super.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext2/super.c 2005-01-15 11:27:52 +0100 @@ -351,6 +352,11 @@ static int parse_options (char * options case Opt_nouid32: set_opt (sbi->s_mount_opt, NO_UID32); break; +#ifndef CONFIG_INOXID_NONE + case Opt_tagxid: + set_opt (sbi->s_mount_opt, TAG_XID); + break; +#endif case Opt_check: #ifdef CONFIG_EXT2_CHECK set_opt (sbi->s_mount_opt, CHECK); --- linux-2.6.11-rc1/fs/ext2/super.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext2/super.c 2005-01-15 11:27:52 +0100 @@ -632,6 +638,8 @@ static int ext2_fill_super(struct super_ if (!parse_options ((char *) data, sbi)) goto failed_mount; + if (EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_TAG_XID) + sb->s_flags |= MS_TAGXID; sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); --- linux-2.6.11-rc1/fs/ext3/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext3/inode.c 2005-01-15 11:27:52 +0100 @@ -2406,6 +2418,8 @@ void ext3_read_inode(struct inode * inod struct ext3_inode_info *ei = EXT3_I(inode); struct buffer_head *bh; int block; + uid_t uid; + gid_t gid; #ifdef CONFIG_EXT3_FS_POSIX_ACL ei->i_acl = EXT3_ACL_NOT_CACHED; --- linux-2.6.11-rc1/fs/ext3/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext3/inode.c 2005-01-15 11:27:52 +0100 @@ -2418,12 +2432,17 @@ void ext3_read_inode(struct inode * inod bh = iloc.bh; raw_inode = ext3_raw_inode(&iloc); inode->i_mode = le16_to_cpu(raw_inode->i_mode); - inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); - inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); + uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); + gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); if(!(test_opt (inode->i_sb, NO_UID32))) { - inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; - inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; + uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; + gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; } + inode->i_uid = INOXID_UID(XID_TAG(inode), uid, gid); + inode->i_gid = INOXID_GID(XID_TAG(inode), uid, gid); + inode->i_xid = INOXID_XID(XID_TAG(inode), uid, gid, + le16_to_cpu(raw_inode->i_raw_xid)); + inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); inode->i_size = le32_to_cpu(raw_inode->i_size); inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime); --- linux-2.6.11-rc1/fs/ext3/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext3/inode.c 2005-01-15 11:27:52 +0100 @@ -2536,6 +2555,8 @@ static int ext3_do_update_inode(handle_t struct ext3_inode *raw_inode = ext3_raw_inode(iloc); struct ext3_inode_info *ei = EXT3_I(inode); struct buffer_head *bh = iloc->bh; + uid_t uid = XIDINO_UID(XID_TAG(inode), inode->i_uid, inode->i_xid); + gid_t gid = XIDINO_GID(XID_TAG(inode), inode->i_gid, inode->i_xid); int err = 0, rc, block; /* For fields not not tracking in the in-memory inode, --- linux-2.6.11-rc1/fs/ext3/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext3/inode.c 2005-01-15 11:27:52 +0100 @@ -2545,29 +2566,32 @@ static int ext3_do_update_inode(handle_t raw_inode->i_mode = cpu_to_le16(inode->i_mode); if(!(test_opt(inode->i_sb, NO_UID32))) { - raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); - raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid)); + raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid)); + raw_inode->i_gid_low = cpu_to_le16(low_16_bits(gid)); /* * Fix up interoperability with old kernels. Otherwise, old inodes get * re-used with the upper 16 bits of the uid/gid intact */ if(!ei->i_dtime) { raw_inode->i_uid_high = - cpu_to_le16(high_16_bits(inode->i_uid)); + cpu_to_le16(high_16_bits(uid)); raw_inode->i_gid_high = - cpu_to_le16(high_16_bits(inode->i_gid)); + cpu_to_le16(high_16_bits(gid)); } else { raw_inode->i_uid_high = 0; raw_inode->i_gid_high = 0; } } else { raw_inode->i_uid_low = - cpu_to_le16(fs_high2lowuid(inode->i_uid)); + cpu_to_le16(fs_high2lowuid(uid)); raw_inode->i_gid_low = - cpu_to_le16(fs_high2lowgid(inode->i_gid)); + cpu_to_le16(fs_high2lowgid(gid)); raw_inode->i_uid_high = 0; raw_inode->i_gid_high = 0; } +#ifdef CONFIG_INOXID_INTERN + raw_inode->i_raw_xid = cpu_to_le16(inode->i_xid); +#endif raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); raw_inode->i_size = cpu_to_le32(ei->i_disksize); raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec); --- linux-2.6.11-rc1/fs/ext3/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext3/inode.c 2005-01-15 11:27:52 +0100 @@ -2720,7 +2782,8 @@ int ext3_setattr(struct dentry *dentry, return 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)) { handle_t *handle; /* (user+group)*(old+new) structure, inode write (sb, --- linux-2.6.11-rc1/fs/ext3/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext3/inode.c 2005-01-15 11:27:52 +0100 @@ -2741,6 +2804,10 @@ int ext3_setattr(struct dentry *dentry, inode->i_uid = attr->ia_uid; if (attr->ia_valid & ATTR_GID) inode->i_gid = attr->ia_gid; + if ((attr->ia_valid & ATTR_XID) + && inode->i_sb + && (inode->i_sb->s_flags & MS_TAGXID)) + inode->i_xid = attr->ia_xid; error = ext3_mark_inode_dirty(handle, inode); ext3_journal_stop(handle); } --- linux-2.6.11-rc1/fs/ext3/super.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext3/super.c 2005-01-15 12:25:29 +0100 @@ -581,7 +581,7 @@ enum { Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, - Opt_ignore, Opt_barrier, Opt_err, Opt_resize, + Opt_tagxid, Opt_barrier, Opt_ignore, Opt_err, Opt_resize, }; static match_table_t tokens = { --- linux-2.6.11-rc1/fs/ext3/super.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext3/super.c 2005-01-15 12:25:29 +0100 @@ -624,6 +624,7 @@ static match_table_t tokens = { {Opt_grpjquota, "grpjquota=%s"}, {Opt_jqfmt_vfsold, "jqfmt=vfsold"}, {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"}, + {Opt_tagxid, "tagxid"}, {Opt_ignore, "grpquota"}, {Opt_ignore, "noquota"}, {Opt_ignore, "quota"}, --- linux-2.6.11-rc1/fs/ext3/super.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext3/super.c 2005-01-15 12:25:29 +0100 @@ -720,6 +721,16 @@ static int parse_options (char * options case Opt_nouid32: set_opt (sbi->s_mount_opt, NO_UID32); break; +#ifndef CONFIG_INOXID_NONE + case Opt_tagxid: + if (is_remount) { + printk(KERN_ERR "EXT3-fs: cannot specify " + "tagxid on remount\n"); + return 0; + } + set_opt (sbi->s_mount_opt, TAG_XID); + break; +#endif case Opt_check: #ifdef CONFIG_EXT3_CHECK set_opt (sbi->s_mount_opt, CHECK); --- linux-2.6.11-rc1/fs/ext3/super.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/ext3/super.c 2005-01-15 12:25:29 +0100 @@ -1316,6 +1327,9 @@ static int ext3_fill_super (struct super if (!parse_options ((char *) data, sb, &journal_inum, NULL, 0)) goto failed_mount; + if (EXT3_SB(sb)->s_mount_opt & EXT3_MOUNT_TAG_XID) + sb->s_flags |= MS_TAGXID; + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); --- linux-2.6.11-rc1/fs/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/inode.c 2005-01-15 11:27:52 +0100 @@ -115,6 +115,10 @@ static struct inode *alloc_inode(struct struct address_space * const mapping = &inode->i_data; inode->i_sb = sb; + // inode->i_dqh = dqhget(sb->s_dqh); + + /* essential because of inode slab reuse */ + inode->i_xid = 0; inode->i_blkbits = sb->s_blocksize_bits; inode->i_flags = 0; atomic_set(&inode->i_count, 1); --- linux-2.6.11-rc1/fs/jfs/jfs_imap.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/jfs/jfs_imap.c 2005-01-15 11:27:52 +0100 @@ -3098,14 +3099,21 @@ static void duplicateIXtree(struct super static int copy_from_dinode(struct dinode * dip, struct inode *ip) { struct jfs_inode_info *jfs_ip = JFS_IP(ip); + uid_t uid; + gid_t gid; jfs_ip->fileset = le32_to_cpu(dip->di_fileset); jfs_ip->mode2 = le32_to_cpu(dip->di_mode); ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff; ip->i_nlink = le32_to_cpu(dip->di_nlink); - ip->i_uid = le32_to_cpu(dip->di_uid); - ip->i_gid = le32_to_cpu(dip->di_gid); + + uid = le32_to_cpu(dip->di_uid); + gid = le32_to_cpu(dip->di_gid); + ip->i_uid = INOXID_UID(XID_TAG(ip), uid, gid); + ip->i_gid = INOXID_GID(XID_TAG(ip), uid, gid); + ip->i_xid = INOXID_XID(XID_TAG(ip), uid, gid, 0); + ip->i_size = le64_to_cpu(dip->di_size); ip->i_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec); ip->i_atime.tv_nsec = le32_to_cpu(dip->di_atime.tv_nsec); --- linux-2.6.11-rc1/fs/jfs/jfs_imap.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/jfs/jfs_imap.c 2005-01-15 11:27:52 +0100 @@ -3156,6 +3164,8 @@ static int copy_from_dinode(struct dinod static void copy_to_dinode(struct dinode * dip, struct inode *ip) { struct jfs_inode_info *jfs_ip = JFS_IP(ip); + uid_t uid; + gid_t gid; dip->di_fileset = cpu_to_le32(jfs_ip->fileset); dip->di_inostamp = cpu_to_le32(JFS_SBI(ip->i_sb)->inostamp); --- linux-2.6.11-rc1/fs/jfs/jfs_imap.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/jfs/jfs_imap.c 2005-01-15 11:27:52 +0100 @@ -3164,8 +3174,11 @@ static void copy_to_dinode(struct dinode dip->di_size = cpu_to_le64(ip->i_size); dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks)); dip->di_nlink = cpu_to_le32(ip->i_nlink); - dip->di_uid = cpu_to_le32(ip->i_uid); - dip->di_gid = cpu_to_le32(ip->i_gid); + + uid = XIDINO_UID(XID_TAG(ip), ip->i_uid, ip->i_xid); + gid = XIDINO_GID(XID_TAG(ip), ip->i_gid, ip->i_xid); + dip->di_uid = cpu_to_le32(uid); + dip->di_gid = cpu_to_le32(gid); /* * mode2 is only needed for storing the higher order bits. * Trust i_mode for the lower order ones --- linux-2.6.11-rc1/fs/namei.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/namei.c 2005-01-15 11:27:52 +0100 @@ -225,6 +229,24 @@ int generic_permission(struct inode *ino return -EACCES; } +static inline int xid_permission(struct inode *inode, int mask, struct nameidata *nd) +{ + if (IS_BARRIER(inode) && !vx_check(0, VX_ADMIN)) { + vxwprintk(1, "xid=%d did hit the barrier.", + vx_current_xid()); + return -EACCES; + } + if (inode->i_xid == 0) + return 0; + if (vx_check(inode->i_xid, VX_ADMIN|VX_WATCH|VX_IDENT)) + return 0; + + vxwprintk(1, "xid=%d denied access to %p[#%d,%lu] »%s«.", + vx_current_xid(), inode, inode->i_xid, inode->i_ino, + vxd_path(nd->dentry, nd->mnt)); + return -EACCES; +} + int permission(struct inode * inode,int mask, struct nameidata *nd) { int retval; --- linux-2.6.11-rc1/fs/namei.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/namei.c 2005-01-15 11:27:52 +0100 @@ -233,6 +255,8 @@ int permission(struct inode * inode,int /* Ordinary permission routines do not understand MAY_APPEND. */ submask = mask & ~MAY_APPEND; + if ((retval = xid_permission(inode, mask, nd))) + return retval; if (inode->i_op && inode->i_op->permission) retval = inode->i_op->permission(inode, submask, nd); else --- linux-2.6.11-rc1/fs/namei.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/namei.c 2005-01-15 11:27:52 +0100 @@ -635,15 +659,33 @@ static int do_lookup(struct nameidata *n { struct vfsmount *mnt = nd->mnt; struct dentry *dentry = __d_lookup(nd->dentry, name); + struct inode *inode; if (!dentry) goto need_lookup; if (dentry->d_op && dentry->d_op->d_revalidate) goto need_revalidate; + inode = dentry->d_inode; + if (!inode) + goto done; + if (!vx_check(inode->i_xid, VX_WATCH|VX_HOSTID|VX_IDENT)) + goto hidden; + if (inode->i_sb->s_magic == PROC_SUPER_MAGIC) { + struct proc_dir_entry *de = PDE(inode); + + if (de && !vx_hide_check(0, de->vx_flags)) + goto hidden; + } done: path->mnt = mnt; path->dentry = dentry; return 0; +hidden: + vxwprintk(1, "xid=%d did lookup hidden %p[#%d,%lu] »%s«.", + vx_current_xid(), inode, inode->i_xid, inode->i_ino, + vxd_path(dentry, mnt)); + dput(dentry); + return -ENOENT; need_lookup: dentry = real_lookup(nd->dentry, name, nd); --- linux-2.6.11-rc1/fs/namespace.c 2004-12-25 01:55:21 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/namespace.c 2005-01-15 11:27:52 +0100 @@ -228,6 +232,7 @@ static int show_vfsmnt(struct seq_file * { MS_MANDLOCK, ",mand" }, { MS_NOATIME, ",noatime" }, { MS_NODIRATIME, ",nodiratime" }, + { MS_TAGXID, ",tagxid" }, { 0, NULL } }; static struct proc_fs_info mnt_info[] = { --- linux-2.6.11-rc1/fs/nfs/dir.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/dir.c 2005-01-15 11:27:52 +0100 @@ -739,6 +740,7 @@ static struct dentry *nfs_lookup(struct inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr); if (!inode) goto out_unlock; + vx_propagate_xid(nd, inode); no_entry: res = d_add_unique(dentry, inode); if (res != NULL) --- linux-2.6.11-rc1/fs/nfs/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/inode.c 2005-01-15 16:25:00 +0100 @@ -313,6 +314,9 @@ nfs_sb_init(struct super_block *sb, rpc_ } server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD; + if (server->flags & NFS_MOUNT_TAGXID) + sb->s_flags |= MS_TAGXID; + sb->s_maxbytes = fsinfo.maxfilesize; if (sb->s_maxbytes > MAX_LFS_FILESIZE) sb->s_maxbytes = MAX_LFS_FILESIZE; --- linux-2.6.11-rc1/fs/nfs/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/inode.c 2005-01-15 16:25:00 +0100 @@ -367,6 +371,7 @@ nfs_create_client(struct nfs_server *ser clnt->cl_intr = (server->flags & NFS_MOUNT_INTR) ? 1 : 0; clnt->cl_softrtry = (server->flags & NFS_MOUNT_SOFT) ? 1 : 0; clnt->cl_droppriv = (server->flags & NFS_MOUNT_BROKEN_SUID) ? 1 : 0; + clnt->cl_tagxid = (server->flags & NFS_MOUNT_TAGXID) ? 1 : 0; clnt->cl_chatty = 1; return clnt; --- linux-2.6.11-rc1/fs/nfs/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/inode.c 2005-01-15 16:25:00 +0100 @@ -539,6 +544,7 @@ static int nfs_show_options(struct seq_f { NFS_MOUNT_NOAC, ",noac", "" }, { NFS_MOUNT_NONLM, ",nolock", ",lock" }, { NFS_MOUNT_BROKEN_SUID, ",broken_suid", "" }, + { NFS_MOUNT_TAGXID, ",tagxid", "" }, { 0, NULL, NULL } }; struct proc_nfs_info *nfs_infop; --- linux-2.6.11-rc1/fs/nfs/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/inode.c 2005-01-15 16:25:00 +0100 @@ -703,8 +709,10 @@ nfs_fhget(struct super_block *sb, struct nfsi->change_attr = fattr->change_attr; inode->i_size = nfs_size_to_loff_t(fattr->size); inode->i_nlink = fattr->nlink; - inode->i_uid = fattr->uid; - inode->i_gid = fattr->gid; + inode->i_uid = INOXID_UID(XID_TAG(inode), fattr->uid, fattr->gid); + inode->i_gid = INOXID_GID(XID_TAG(inode), fattr->uid, fattr->gid); + inode->i_xid = INOXID_XID(XID_TAG(inode), fattr->uid, fattr->gid, 0); + /* maybe fattr->xid someday */ if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) { /* * report the blocks in 512byte units --- linux-2.6.11-rc1/fs/nfs/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/inode.c 2005-01-15 16:25:00 +0100 @@ -776,6 +789,8 @@ nfs_setattr(struct dentry *dentry, struc inode->i_uid = attr->ia_uid; if ((attr->ia_valid & ATTR_GID) != 0) inode->i_gid = attr->ia_gid; + if ((attr->ia_valid & ATTR_XID) != 0) + inode->i_xid = attr->ia_xid; if ((attr->ia_valid & ATTR_SIZE) != 0) { inode->i_size = attr->ia_size; vmtruncate(inode, attr->ia_size); --- linux-2.6.11-rc1/fs/nfs/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/inode.c 2005-01-15 16:25:00 +0100 @@ -1123,6 +1138,9 @@ int nfs_refresh_inode(struct inode *inod struct nfs_inode *nfsi = NFS_I(inode); loff_t cur_size, new_isize; int data_unstable; + uid_t uid; + gid_t gid; + xid_t xid = 0; /* Do we hold a delegation? */ if (nfs_have_delegation(inode, FMODE_READ)) --- linux-2.6.11-rc1/fs/nfs/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/inode.c 2005-01-15 16:25:00 +0100 @@ -1166,10 +1184,15 @@ int nfs_refresh_inode(struct inode *inod } else if (S_ISREG(inode->i_mode) && new_isize > cur_size) nfsi->flags |= NFS_INO_INVALID_ATTR; + uid = INOXID_UID(XID_TAG(inode), fattr->uid, fattr->gid); + gid = INOXID_GID(XID_TAG(inode), fattr->uid, fattr->gid); + xid = INOXID_XID(XID_TAG(inode), fattr->uid, fattr->gid, 0); + /* Have any file permissions changed? */ if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) - || inode->i_uid != fattr->uid - || inode->i_gid != fattr->gid) + || inode->i_uid != uid + || inode->i_gid != gid + || inode->i_xid != xid) nfsi->flags |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; /* Has the link count changed? */ --- linux-2.6.11-rc1/fs/nfs/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/inode.c 2005-01-15 16:25:00 +0100 @@ -1203,6 +1226,9 @@ static int nfs_update_inode(struct inode unsigned int invalid = 0; loff_t cur_isize; int data_unstable; + uid_t uid; + gid_t gid; + xid_t xid = 0; dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", __FUNCTION__, inode->i_sb->s_id, inode->i_ino, --- linux-2.6.11-rc1/fs/nfs/inode.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/inode.c 2005-01-15 16:25:00 +0100 @@ -1285,15 +1311,21 @@ static int nfs_update_inode(struct inode memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); + uid = INOXID_UID(XID_TAG(inode), fattr->uid, fattr->gid); + gid = INOXID_GID(XID_TAG(inode), fattr->uid, fattr->gid); + xid = INOXID_XID(XID_TAG(inode), fattr->uid, fattr->gid, 0); + if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) || - inode->i_uid != fattr->uid || - inode->i_gid != fattr->gid) + inode->i_uid != uid || + inode->i_gid != gid || + inode->i_xid != xid) invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS; inode->i_mode = fattr->mode; inode->i_nlink = fattr->nlink; - inode->i_uid = fattr->uid; - inode->i_gid = fattr->gid; + inode->i_uid = uid; + inode->i_gid = gid; + inode->i_xid = xid; if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) { /* --- linux-2.6.11-rc1/fs/nfs/nfs3xdr.c 2004-10-23 05:06:17 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/nfs3xdr.c 2005-01-15 11:27:52 +0100 @@ -173,7 +174,7 @@ xdr_decode_fattr(u32 *p, struct nfs_fatt } static inline u32 * -xdr_encode_sattr(u32 *p, struct iattr *attr) +xdr_encode_sattr(u32 *p, struct iattr *attr, int tagxid) { if (attr->ia_valid & ATTR_MODE) { *p++ = xdr_one; --- linux-2.6.11-rc1/fs/nfs/nfs3xdr.c 2004-10-23 05:06:17 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/nfs3xdr.c 2005-01-15 11:27:52 +0100 @@ -181,15 +182,17 @@ xdr_encode_sattr(u32 *p, struct iattr *a } else { *p++ = xdr_zero; } - if (attr->ia_valid & ATTR_UID) { + if (attr->ia_valid & ATTR_UID || + (tagxid && (attr->ia_valid & ATTR_XID))) { *p++ = xdr_one; - *p++ = htonl(attr->ia_uid); + *p++ = htonl(XIDINO_UID(tagxid, attr->ia_uid, attr->ia_xid)); } else { *p++ = xdr_zero; } - if (attr->ia_valid & ATTR_GID) { + if (attr->ia_valid & ATTR_GID || + (tagxid && (attr->ia_valid & ATTR_XID))) { *p++ = xdr_one; - *p++ = htonl(attr->ia_gid); + *p++ = htonl(XIDINO_GID(tagxid, attr->ia_gid, attr->ia_xid)); } else { *p++ = xdr_zero; } --- linux-2.6.11-rc1/fs/nfs/nfs3xdr.c 2004-10-23 05:06:17 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/nfs3xdr.c 2005-01-15 11:27:52 +0100 @@ -274,7 +277,8 @@ static int nfs3_xdr_sattrargs(struct rpc_rqst *req, u32 *p, struct nfs3_sattrargs *args) { p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_sattr(p, args->sattr); + p = xdr_encode_sattr(p, args->sattr, + req->rq_task->tk_client->cl_tagxid); *p++ = htonl(args->guard); if (args->guard) p = xdr_encode_time3(p, &args->guardtime); --- linux-2.6.11-rc1/fs/nfs/nfs3xdr.c 2004-10-23 05:06:17 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/nfs3xdr.c 2005-01-15 11:27:52 +0100 @@ -365,7 +369,8 @@ nfs3_xdr_createargs(struct rpc_rqst *req *p++ = args->verifier[0]; *p++ = args->verifier[1]; } else - p = xdr_encode_sattr(p, args->sattr); + p = xdr_encode_sattr(p, args->sattr, + req->rq_task->tk_client->cl_tagxid); req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); return 0; --- linux-2.6.11-rc1/fs/nfs/nfs3xdr.c 2004-10-23 05:06:17 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/nfs3xdr.c 2005-01-15 11:27:52 +0100 @@ -379,7 +384,8 @@ nfs3_xdr_mkdirargs(struct rpc_rqst *req, { p = xdr_encode_fhandle(p, args->fh); p = xdr_encode_array(p, args->name, args->len); - p = xdr_encode_sattr(p, args->sattr); + p = xdr_encode_sattr(p, args->sattr, + req->rq_task->tk_client->cl_tagxid); req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); return 0; } --- linux-2.6.11-rc1/fs/nfs/nfs3xdr.c 2004-10-23 05:06:17 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/nfs3xdr.c 2005-01-15 11:27:52 +0100 @@ -392,7 +398,8 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *re { p = xdr_encode_fhandle(p, args->fromfh); p = xdr_encode_array(p, args->fromname, args->fromlen); - p = xdr_encode_sattr(p, args->sattr); + p = xdr_encode_sattr(p, args->sattr, + req->rq_task->tk_client->cl_tagxid); p = xdr_encode_array(p, args->topath, args->tolen); req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); return 0; --- linux-2.6.11-rc1/fs/nfs/nfs3xdr.c 2004-10-23 05:06:17 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/nfs3xdr.c 2005-01-15 11:27:52 +0100 @@ -407,7 +414,8 @@ nfs3_xdr_mknodargs(struct rpc_rqst *req, p = xdr_encode_fhandle(p, args->fh); p = xdr_encode_array(p, args->name, args->len); *p++ = htonl(args->type); - p = xdr_encode_sattr(p, args->sattr); + p = xdr_encode_sattr(p, args->sattr, + req->rq_task->tk_client->cl_tagxid); if (args->type == NF3CHR || args->type == NF3BLK) { *p++ = htonl(MAJOR(args->rdev)); *p++ = htonl(MINOR(args->rdev)); --- linux-2.6.11-rc1/fs/nfs/nfsroot.c 2004-08-14 12:55:48 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/nfsroot.c 2005-01-15 11:27:52 +0100 @@ -124,7 +125,7 @@ enum { Opt_soft, Opt_hard, Opt_intr, Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac, Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp, - Opt_broken_suid, + Opt_broken_suid, Opt_tagxid, /* Error token */ Opt_err }; --- linux-2.6.11-rc1/fs/nfs/nfsroot.c 2004-08-14 12:55:48 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/nfsroot.c 2005-01-15 11:27:52 +0100 @@ -160,6 +161,7 @@ static match_table_t __initdata tokens = {Opt_tcp, "proto=tcp"}, {Opt_tcp, "tcp"}, {Opt_broken_suid, "broken_suid"}, + {Opt_tagxid, "tagxid"}, {Opt_err, NULL} }; --- linux-2.6.11-rc1/fs/nfs/nfsroot.c 2004-08-14 12:55:48 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfs/nfsroot.c 2005-01-15 11:27:52 +0100 @@ -271,6 +273,9 @@ static int __init root_nfs_parse(char *n case Opt_broken_suid: nfs_data.flags |= NFS_MOUNT_BROKEN_SUID; break; + case Opt_tagxid: + nfs_data.flags |= NFS_MOUNT_TAGXID; + break; default : return 0; } --- linux-2.6.11-rc1/fs/nfsd/auth.c 2004-08-14 12:56:14 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfsd/auth.c 2005-01-15 11:27:52 +0100 @@ -42,18 +43,20 @@ int nfsd_setuser(struct svc_rqst *rqstp, } if (cred->cr_uid != (uid_t) -1) - current->fsuid = cred->cr_uid; + current->fsuid = INOXID_UID(1, cred->cr_uid, cred->cr_gid); else current->fsuid = exp->ex_anon_uid; if (cred->cr_gid != (gid_t) -1) - current->fsgid = cred->cr_gid; + current->fsgid = INOXID_GID(1, cred->cr_uid, cred->cr_gid); else current->fsgid = exp->ex_anon_gid; + current->xid = INOXID_XID(1, cred->cr_uid, cred->cr_gid, 0); + if (!cred->cr_group_info) return -ENOMEM; ret = set_current_groups(cred->cr_group_info); - if ((cred->cr_uid)) { + if (INOXID_UID(1, cred->cr_uid, cred->cr_gid)) { cap_t(current->cap_effective) &= ~CAP_NFSD_MASK; } else { cap_t(current->cap_effective) |= (CAP_NFSD_MASK & --- linux-2.6.11-rc1/fs/nfsd/nfs3xdr.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfsd/nfs3xdr.c 2005-01-15 11:27:52 +0100 @@ -105,6 +106,8 @@ static inline u32 * decode_sattr3(u32 *p, struct iattr *iap) { u32 tmp; + uid_t uid = 0; + gid_t gid = 0; iap->ia_valid = 0; --- linux-2.6.11-rc1/fs/nfsd/nfs3xdr.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfsd/nfs3xdr.c 2005-01-15 11:27:52 +0100 @@ -114,12 +117,15 @@ decode_sattr3(u32 *p, struct iattr *iap) } if (*p++) { iap->ia_valid |= ATTR_UID; - iap->ia_uid = ntohl(*p++); + uid = ntohl(*p++); } if (*p++) { iap->ia_valid |= ATTR_GID; - iap->ia_gid = ntohl(*p++); + gid = ntohl(*p++); } + iap->ia_uid = INOXID_UID(1, uid, gid); + iap->ia_gid = INOXID_GID(1, uid, gid); + iap->ia_xid = INOXID_XID(1, uid, gid, 0); if (*p++) { u64 newsize; --- linux-2.6.11-rc1/fs/nfsd/nfs3xdr.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfsd/nfs3xdr.c 2005-01-15 11:27:52 +0100 @@ -160,8 +166,10 @@ encode_fattr3(struct svc_rqst *rqstp, u3 *p++ = htonl(nfs3_ftypes[(stat.mode & S_IFMT) >> 12]); *p++ = htonl((u32) stat.mode); *p++ = htonl((u32) stat.nlink); - *p++ = htonl((u32) nfsd_ruid(rqstp, stat.uid)); - *p++ = htonl((u32) nfsd_rgid(rqstp, stat.gid)); + *p++ = htonl((u32) nfsd_ruid(rqstp, + XIDINO_UID(XID_TAG(dentry->d_inode), stat.uid, stat.xid))); + *p++ = htonl((u32) nfsd_rgid(rqstp, + XIDINO_GID(XID_TAG(dentry->d_inode), stat.gid, stat.xid))); if (S_ISLNK(stat.mode) && stat.size > NFS3_MAXPATHLEN) { p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN); } else { --- linux-2.6.11-rc1/fs/nfsd/nfs4xdr.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfsd/nfs4xdr.c 2005-01-15 11:27:52 +0100 @@ -1680,14 +1681,18 @@ out_acl: WRITE32(stat.nlink); } if (bmval1 & FATTR4_WORD1_OWNER) { - status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen); + status = nfsd4_encode_user(rqstp, + XIDINO_UID(XID_TAG(dentry->d_inode), + stat.uid, stat.xid), &p, &buflen); if (status == nfserr_resource) goto out_resource; if (status) goto out; } if (bmval1 & FATTR4_WORD1_OWNER_GROUP) { - status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen); + status = nfsd4_encode_group(rqstp, + XIDINO_GID(XID_TAG(dentry->d_inode), + stat.gid, stat.xid), &p, &buflen); if (status == nfserr_resource) goto out_resource; if (status) --- linux-2.6.11-rc1/fs/nfsd/nfsxdr.c 2004-08-14 12:54:47 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfsd/nfsxdr.c 2005-01-15 11:27:52 +0100 @@ -96,6 +97,8 @@ static inline u32 * decode_sattr(u32 *p, struct iattr *iap) { u32 tmp, tmp1; + uid_t uid = 0; + gid_t gid = 0; iap->ia_valid = 0; --- linux-2.6.11-rc1/fs/nfsd/nfsxdr.c 2004-08-14 12:54:47 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfsd/nfsxdr.c 2005-01-15 11:27:52 +0100 @@ -109,12 +112,15 @@ decode_sattr(u32 *p, struct iattr *iap) } if ((tmp = ntohl(*p++)) != (u32)-1) { iap->ia_valid |= ATTR_UID; - iap->ia_uid = tmp; + uid = tmp; } if ((tmp = ntohl(*p++)) != (u32)-1) { iap->ia_valid |= ATTR_GID; - iap->ia_gid = tmp; + gid = tmp; } + iap->ia_uid = INOXID_UID(1, uid, gid); + iap->ia_gid = INOXID_GID(1, uid, gid); + iap->ia_xid = INOXID_XID(1, uid, gid, 0); if ((tmp = ntohl(*p++)) != (u32)-1) { iap->ia_valid |= ATTR_SIZE; iap->ia_size = tmp; --- linux-2.6.11-rc1/fs/nfsd/nfsxdr.c 2004-08-14 12:54:47 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/nfsd/nfsxdr.c 2005-01-15 11:27:52 +0100 @@ -160,8 +166,10 @@ encode_fattr(struct svc_rqst *rqstp, u32 *p++ = htonl(nfs_ftypes[type >> 12]); *p++ = htonl((u32) stat.mode); *p++ = htonl((u32) stat.nlink); - *p++ = htonl((u32) nfsd_ruid(rqstp, stat.uid)); - *p++ = htonl((u32) nfsd_rgid(rqstp, stat.gid)); + *p++ = htonl((u32) nfsd_ruid(rqstp, + XIDINO_UID(XID_TAG(dentry->d_inode), stat.uid, stat.xid))); + *p++ = htonl((u32) nfsd_rgid(rqstp, + XIDINO_GID(XID_TAG(dentry->d_inode), stat.gid, stat.xid))); if (S_ISLNK(type) && stat.size > NFS_MAXPATHLEN) { *p++ = htonl(NFS_MAXPATHLEN); --- linux-2.6.11-rc1/fs/open.c 2005-01-14 12:35:55 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/open.c 2005-01-15 11:27:52 +0100 @@ -678,14 +683,15 @@ static int chown_common(struct dentry * error = -EPERM; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) goto out; + newattrs.ia_valid = ATTR_CTIME; if (user != (uid_t) -1) { newattrs.ia_valid |= ATTR_UID; - newattrs.ia_uid = user; + newattrs.ia_uid = vx_map_uid(user); } if (group != (gid_t) -1) { newattrs.ia_valid |= ATTR_GID; - newattrs.ia_gid = group; + newattrs.ia_gid = vx_map_gid(group); } if (!S_ISDIR(inode->i_mode)) newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID; --- linux-2.6.11-rc1/fs/reiserfs/inode.c 2005-01-14 12:35:56 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/reiserfs/inode.c 2005-01-15 11:27:52 +0100 @@ -1047,6 +1048,8 @@ static void init_inode (struct inode * i struct buffer_head * bh; struct item_head * ih; __u32 rdev; + uid_t uid; + gid_t gid; //int version = ITEM_VERSION_1; bh = PATH_PLAST_BUFFER (path); --- linux-2.6.11-rc1/fs/reiserfs/inode.c 2005-01-14 12:35:56 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/reiserfs/inode.c 2005-01-15 11:27:52 +0100 @@ -1070,12 +1073,13 @@ static void init_inode (struct inode * i struct stat_data_v1 * sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih); unsigned long blocks; + uid = sd_v1_uid(sd); + gid = sd_v1_gid(sd); + set_inode_item_key_version (inode, KEY_FORMAT_3_5); set_inode_sd_version (inode, STAT_DATA_V1); inode->i_mode = sd_v1_mode(sd); inode->i_nlink = sd_v1_nlink(sd); - inode->i_uid = sd_v1_uid(sd); - inode->i_gid = sd_v1_gid(sd); inode->i_size = sd_v1_size(sd); inode->i_atime.tv_sec = sd_v1_atime(sd); inode->i_mtime.tv_sec = sd_v1_mtime(sd); --- linux-2.6.11-rc1/fs/reiserfs/inode.c 2005-01-14 12:35:56 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/reiserfs/inode.c 2005-01-15 11:27:52 +0100 @@ -1115,11 +1119,12 @@ static void init_inode (struct inode * i // (directories and symlinks) struct stat_data * sd = (struct stat_data *)B_I_PITEM (bh, ih); + uid = sd_v2_uid(sd); + gid = sd_v2_gid(sd); + inode->i_mode = sd_v2_mode(sd); inode->i_nlink = sd_v2_nlink(sd); - inode->i_uid = sd_v2_uid(sd); inode->i_size = sd_v2_size(sd); - inode->i_gid = sd_v2_gid(sd); inode->i_mtime.tv_sec = sd_v2_mtime(sd); inode->i_atime.tv_sec = sd_v2_atime(sd); inode->i_ctime.tv_sec = sd_v2_ctime(sd); --- linux-2.6.11-rc1/fs/reiserfs/inode.c 2005-01-14 12:35:56 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/reiserfs/inode.c 2005-01-15 11:27:52 +0100 @@ -1146,6 +1151,9 @@ static void init_inode (struct inode * i REISERFS_I(inode)->i_attrs = sd_v2_attrs( sd ); sd_attrs_to_i_attrs( sd_v2_attrs( sd ), inode ); } + inode->i_uid = INOXID_UID(XID_TAG(inode), uid, gid); + inode->i_gid = INOXID_GID(XID_TAG(inode), uid, gid); + inode->i_xid = INOXID_XID(XID_TAG(inode), uid, gid, 0); pathrelse (path); if (S_ISREG (inode->i_mode)) { --- linux-2.6.11-rc1/fs/reiserfs/inode.c 2005-01-14 12:35:56 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/reiserfs/inode.c 2005-01-15 11:27:52 +0100 @@ -1170,13 +1178,15 @@ static void init_inode (struct inode * i static void inode2sd (void * sd, struct inode * inode, loff_t size) { struct stat_data * sd_v2 = (struct stat_data *)sd; + uid_t uid = XIDINO_UID(XID_TAG(inode), inode->i_uid, inode->i_xid); + gid_t gid = XIDINO_GID(XID_TAG(inode), inode->i_gid, inode->i_xid); __u16 flags; + set_sd_v2_uid(sd_v2, uid ); + set_sd_v2_gid(sd_v2, gid ); set_sd_v2_mode(sd_v2, inode->i_mode ); set_sd_v2_nlink(sd_v2, inode->i_nlink ); - set_sd_v2_uid(sd_v2, inode->i_uid ); set_sd_v2_size(sd_v2, size ); - set_sd_v2_gid(sd_v2, inode->i_gid ); set_sd_v2_mtime(sd_v2, inode->i_mtime.tv_sec ); set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec ); set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec ); --- linux-2.6.11-rc1/fs/reiserfs/namei.c 2005-01-14 12:35:56 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/reiserfs/namei.c 2005-01-15 11:27:52 +0100 @@ -350,6 +351,7 @@ static struct dentry * reiserfs_lookup ( reiserfs_write_unlock(dir->i_sb); return ERR_PTR(-EACCES); } + vx_propagate_xid(nd, inode); /* Propogate the priv_object flag so we know we're in the priv tree */ if (is_reiserfs_priv_object (dir)) --- linux-2.6.11-rc1/fs/reiserfs/super.c 2005-01-14 12:35:56 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/fs/reiserfs/super.c 2005-01-15 11:27:52 +0100 @@ -848,6 +848,7 @@ static int reiserfs_parse_options (struc {"user_xattr", .setmask = 1<nlink = inode->i_nlink; stat->uid = inode->i_uid; stat->gid = inode->i_gid; + stat->xid = inode->i_xid; stat->rdev = inode->i_rdev; stat->atime = inode->i_atime; stat->mtime = inode->i_mtime; --- linux-2.6.11-rc1/include/linux/ext2_fs.h 2004-10-23 05:06:22 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/ext2_fs.h 2005-01-15 11:27:52 +0100 @@ -240,7 +247,7 @@ struct ext2_inode { struct { __u8 l_i_frag; /* Fragment number */ __u8 l_i_fsize; /* Fragment size */ - __u16 i_pad1; + __u16 l_i_xid; /* LRU Context */ __le16 l_i_uid_high; /* these 2 fields */ __le16 l_i_gid_high; /* were reserved2[0] */ __u32 l_i_reserved2; --- linux-2.6.11-rc1/include/linux/ext2_fs.h 2004-10-23 05:06:22 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/ext2_fs.h 2005-01-15 11:27:52 +0100 @@ -272,6 +279,7 @@ struct ext2_inode { #define i_gid_low i_gid #define i_uid_high osd2.linux2.l_i_uid_high #define i_gid_high osd2.linux2.l_i_gid_high +#define i_raw_xid osd2.linux2.l_i_xid #define i_reserved2 osd2.linux2.l_i_reserved2 #endif --- linux-2.6.11-rc1/include/linux/ext2_fs.h 2004-10-23 05:06:22 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/ext2_fs.h 2005-01-15 11:27:52 +0100 @@ -312,6 +320,7 @@ struct ext2_inode { #define EXT2_MOUNT_NO_UID32 0x0200 /* Disable 32-bit UIDs */ #define EXT2_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ #define EXT2_MOUNT_POSIX_ACL 0x8000 /* POSIX Access Control Lists */ +#define EXT2_MOUNT_TAG_XID (1<<24) /* Enable Context Tags */ #define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt #define set_opt(o, opt) o |= EXT2_MOUNT_##opt --- linux-2.6.11-rc1/include/linux/ext3_fs.h 2005-01-14 12:35:58 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/ext3_fs.h 2005-01-15 11:27:52 +0100 @@ -273,7 +283,7 @@ struct ext3_inode { struct { __u8 l_i_frag; /* Fragment number */ __u8 l_i_fsize; /* Fragment size */ - __u16 i_pad1; + __u16 l_i_xid; /* LRU Context */ __le16 l_i_uid_high; /* these 2 fields */ __le16 l_i_gid_high; /* were reserved2[0] */ __u32 l_i_reserved2; --- linux-2.6.11-rc1/include/linux/ext3_fs.h 2005-01-14 12:35:58 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/ext3_fs.h 2005-01-15 11:27:52 +0100 @@ -307,6 +317,7 @@ struct ext3_inode { #define i_gid_low i_gid #define i_uid_high osd2.linux2.l_i_uid_high #define i_gid_high osd2.linux2.l_i_gid_high +#define i_raw_xid osd2.linux2.l_i_xid #define i_reserved2 osd2.linux2.l_i_reserved2 #elif defined(__GNU__) --- linux-2.6.11-rc1/include/linux/ext3_fs.h 2005-01-14 12:35:58 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/ext3_fs.h 2005-01-15 11:27:52 +0100 @@ -357,6 +368,7 @@ struct ext3_inode { #define EXT3_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ #define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */ #define EXT3_MOUNT_BARRIER 0x20000 /* Use block barriers */ +#define EXT3_MOUNT_TAG_XID (1<<24) /* Enable Context Tags */ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ #ifndef _LINUX_EXT2_FS_H --- linux-2.6.11-rc1/include/linux/fs.h 2005-01-14 12:35:58 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/fs.h 2005-01-15 12:05:56 +0100 @@ -121,6 +121,8 @@ extern int dir_notify_enable; #define MS_REC 16384 #define MS_VERBOSE 32768 #define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ +#define MS_TAGXID (1<<24) /* tag inodes with context information */ +#define MS_XID (1<<25) /* use specific xid for this mount */ #define MS_ACTIVE (1<<30) #define MS_NOUSER (1<<31) --- linux-2.6.11-rc1/include/linux/fs.h 2005-01-14 12:35:58 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/fs.h 2005-01-15 12:05:56 +0100 @@ -258,6 +265,7 @@ typedef void (dio_iodone_t)(struct inode #define ATTR_ATTR_FLAG 1024 #define ATTR_KILL_SUID 2048 #define ATTR_KILL_SGID 4096 +#define ATTR_XID 8192 /* * This is the Inode Attributes structure, used for notify_change(). It --- linux-2.6.11-rc1/include/linux/fs.h 2005-01-14 12:35:58 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/fs.h 2005-01-15 12:05:56 +0100 @@ -273,6 +281,7 @@ struct iattr { umode_t ia_mode; uid_t ia_uid; gid_t ia_gid; + xid_t ia_xid; loff_t ia_size; struct timespec ia_atime; struct timespec ia_mtime; --- linux-2.6.11-rc1/include/linux/fs.h 2005-01-14 12:35:58 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/fs.h 2005-01-15 12:05:56 +0100 @@ -433,6 +445,7 @@ struct inode { unsigned int i_nlink; uid_t i_uid; gid_t i_gid; + xid_t i_xid; dev_t i_rdev; loff_t i_size; struct timespec i_atime; --- linux-2.6.11-rc1/include/linux/fs.h 2005-01-14 12:35:58 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/fs.h 2005-01-15 12:05:56 +0100 @@ -586,6 +599,8 @@ struct file { unsigned int f_uid, f_gid; struct file_ra_state f_ra; + xid_t f_xid; + unsigned long f_version; void *f_security; --- linux-2.6.11-rc1/include/linux/mount.h 2004-12-25 01:55:29 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/mount.h 2005-01-15 11:27:52 +0100 @@ -19,6 +19,7 @@ #define MNT_NOSUID 1 #define MNT_NODEV 2 #define MNT_NOEXEC 4 +#define MNT_XID 256 struct vfsmount { --- linux-2.6.11-rc1/include/linux/mount.h 2004-12-25 01:55:29 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/mount.h 2005-01-15 11:27:52 +0100 @@ -36,6 +37,7 @@ struct vfsmount struct list_head mnt_list; struct list_head mnt_fslink; /* link in fs-specific expiry list */ struct namespace *mnt_namespace; /* containing namespace */ + xid_t mnt_xid; /* xid tagging used for vfsmount */ }; static inline struct vfsmount *mntget(struct vfsmount *mnt) --- linux-2.6.11-rc1/include/linux/nfs_mount.h 2004-08-14 12:54:47 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/nfs_mount.h 2005-01-15 11:27:52 +0100 @@ -60,6 +60,7 @@ struct nfs_mount_data { #define NFS_MOUNT_BROKEN_SUID 0x0400 /* 4 */ #define NFS_MOUNT_STRICTLOCK 0x1000 /* reserved for NFSv4 */ #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */ +#define NFS_MOUNT_TAGXID 0x8000 /* tagxid */ #define NFS_MOUNT_FLAGMASK 0xFFFF #endif --- linux-2.6.11-rc1/include/linux/reiserfs_fs_sb.h 2005-01-14 12:35:58 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/reiserfs_fs_sb.h 2005-01-15 11:27:52 +0100 @@ -461,6 +461,7 @@ enum reiserfs_mount_options { REISERFS_POSIXACL, REISERFS_BARRIER_NONE, REISERFS_BARRIER_FLUSH, + REISERFS_TAGXID, /* Actions on error */ REISERFS_ERROR_PANIC, --- linux-2.6.11-rc1/include/linux/stat.h 2004-08-14 12:55:10 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/stat.h 2005-01-15 11:27:52 +0100 @@ -63,6 +63,7 @@ struct kstat { unsigned int nlink; uid_t uid; gid_t gid; + xid_t xid; dev_t rdev; loff_t size; struct timespec atime; --- linux-2.6.11-rc1/include/linux/sunrpc/auth.h 2005-01-14 12:35:58 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/sunrpc/auth.h 2005-01-15 11:27:52 +0100 @@ -28,6 +28,7 @@ struct auth_cred { uid_t uid; gid_t gid; + xid_t xid; struct group_info *group_info; }; --- linux-2.6.11-rc1/include/linux/sunrpc/clnt.h 2004-08-14 12:55:34 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/sunrpc/clnt.h 2005-01-15 11:27:52 +0100 @@ -53,7 +53,8 @@ struct rpc_clnt { cl_autobind : 1,/* use getport() */ cl_droppriv : 1,/* enable NFS suid hack */ cl_oneshot : 1,/* dispose after use */ - cl_dead : 1;/* abandoned */ + cl_dead : 1,/* abandoned */ + cl_tagxid : 1;/* do xid tagging */ struct rpc_rtt * cl_rtt; /* RTO estimator data */ struct rpc_portmap * cl_pmap; /* port mapping */ --- linux-2.6.11-rc1/include/linux/vserver/xid.h 1970-01-01 01:00:00 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/vserver/xid.h 2005-01-15 11:27:52 +0100 @@ -0,0 +1,126 @@ +#ifndef _VX_XID_H +#define _VX_XID_H + + +#define XID_TAG(in) (!(in) || \ + (((struct inode *)in)->i_sb && \ + (((struct inode *)in)->i_sb->s_flags & MS_TAGXID))) + + +#ifdef CONFIG_INOXID_NONE + +#define MAX_UID 0xFFFFFFFF +#define MAX_GID 0xFFFFFFFF + +#define INOXID_XID(tag, uid, gid, xid) (0) + +#define XIDINO_UID(tag, uid, xid) (uid) +#define XIDINO_GID(tag, gid, xid) (gid) + +#endif + + +#ifdef CONFIG_INOXID_GID16 + +#define MAX_UID 0xFFFFFFFF +#define MAX_GID 0x0000FFFF + +#define INOXID_XID(tag, uid, gid, xid) \ + ((tag) ? (((gid) >> 16) & 0xFFFF) : 0) + +#define XIDINO_UID(tag, uid, xid) (uid) +#define XIDINO_GID(tag, gid, xid) \ + ((tag) ? (((gid) & 0xFFFF) | ((xid) << 16)) : (gid)) + +#endif + + +#ifdef CONFIG_INOXID_UGID24 + +#define MAX_UID 0x00FFFFFF +#define MAX_GID 0x00FFFFFF + +#define INOXID_XID(tag, uid, gid, xid) \ + ((tag) ? ((((uid) >> 16) & 0xFF00) | (((gid) >> 24) & 0xFF)) : 0) + +#define XIDINO_UID(tag, uid, xid) \ + ((tag) ? (((uid) & 0xFFFFFF) | (((xid) & 0xFF00) << 16)) : (uid)) +#define XIDINO_GID(tag, gid, xid) \ + ((tag) ? (((gid) & 0xFFFFFF) | (((xid) & 0x00FF) << 24)) : (gid)) + +#endif + + +#ifdef CONFIG_INOXID_UID16 + +#define MAX_UID 0x0000FFFF +#define MAX_GID 0xFFFFFFFF + +#define INOXID_XID(tag, uid, gid, xid) \ + ((tag) ? ((uid) >> 16) & 0xFFFF) : 0) + +#define XIDINO_UID(tag, uid, xid) \ + ((tag) ? (((uid) & 0xFFFF) | ((xid) << 16)) : (uid)) +#define XIDINO_GID(tag, gid, xid) (gid) + +#endif + + +#ifdef CONFIG_INOXID_INTERN + +#define MAX_UID 0xFFFFFFFF +#define MAX_GID 0xFFFFFFFF + +#define INOXID_XID(tag, uid, gid, xid) \ + ((tag) ? (xid) : 0) + +#define XIDINO_UID(tag, uid, xid) (uid) +#define XIDINO_GID(tag, gid, xid) (gid) + +#endif + + +#ifdef CONFIG_INOXID_RUNTIME + +#define MAX_UID 0xFFFFFFFF +#define MAX_GID 0xFFFFFFFF + +#define INOXID_XID(tag, uid, gid, xid) (0) + +#define XIDINO_UID(tag, uid, xid) (uid) +#define XIDINO_GID(tag, gid, xid) (gid) + +#endif + + +#define INOXID_UID(tag, uid, gid) \ + ((tag) ? ((uid) & MAX_UID) : (uid)) +#define INOXID_GID(tag, uid, gid) \ + ((tag) ? ((gid) & MAX_GID) : (gid)) + + +static inline uid_t vx_map_uid(uid_t uid) +{ + if ((uid > MAX_UID) && (uid != -1)) + uid = -2; + return (uid & MAX_UID); +} + +static inline gid_t vx_map_gid(gid_t gid) +{ + if ((gid > MAX_GID) && (gid != -1)) + gid = -2; + return (gid & MAX_GID); +} + + +#ifdef CONFIG_VSERVER_LEGACY +#define FIOC_GETXID _IOR('x', 1, long) +#define FIOC_SETXID _IOW('x', 2, long) +#define FIOC_SETXIDJ _IOW('x', 3, long) +#endif + +int vx_parse_xid(char *string, xid_t *xid, int remove); +void vx_propagate_xid(struct nameidata *nd, struct inode *inode); + +#endif /* _VX_XID_H */ --- linux-2.6.11-rc1/net/sunrpc/auth_unix.c 2004-08-14 12:55:33 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/net/sunrpc/auth_unix.c 2005-01-15 11:27:52 +0100 @@ -13,14 +13,17 @@ #include #include #include +#include #define NFS_NGROUPS 16 struct unx_cred { struct rpc_cred uc_base; gid_t uc_gid; + xid_t uc_xid; uid_t uc_puid; /* process uid */ gid_t uc_pgid; /* process gid */ + xid_t uc_pxid; /* process xid */ gid_t uc_gids[NFS_NGROUPS]; }; #define uc_uid uc_base.cr_uid --- linux-2.6.11-rc1/net/sunrpc/auth.c 2005-01-14 12:36:02 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/net/sunrpc/auth.c 2005-01-15 11:27:52 +0100 @@ -259,6 +260,7 @@ rpcauth_lookupcred(struct rpc_auth *auth get_group_info(current->group_info); acred.uid = current->fsuid; acred.gid = current->fsgid; + acred.xid = vx_current_xid(); acred.group_info = current->group_info; dprintk("RPC: looking up %s cred\n", --- linux-2.6.11-rc1/net/sunrpc/auth.c 2005-01-14 12:36:02 +0100 +++ linux-2.6.11-rc1-vs1.9.4-rc2/net/sunrpc/auth.c 2005-01-15 11:27:52 +0100 @@ -278,6 +280,7 @@ rpcauth_bindcred(struct rpc_task *task) get_group_info(current->group_info); acred.uid = current->fsuid; acred.gid = current->fsgid; + acred.xid = vx_current_xid(); acred.group_info = current->group_info; dprintk("RPC: %4d looking up %s cred\n", --- linux-2.6.11-rc1/net/sunrpc/auth_unix.c 2004-08-14 12:55:33 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/net/sunrpc/auth_unix.c 2005-01-15 11:27:52 +0100 @@ -80,6 +83,7 @@ unx_create_cred(struct rpc_auth *auth, s if (flags & RPC_TASK_ROOTCREDS) { cred->uc_uid = cred->uc_puid = 0; cred->uc_gid = cred->uc_pgid = 0; + cred->uc_xid = cred->uc_pxid = vx_current_xid(); cred->uc_gids[0] = NOGROUP; } else { int groups = acred->group_info->ngroups; --- linux-2.6.11-rc1/net/sunrpc/auth_unix.c 2004-08-14 12:55:33 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/net/sunrpc/auth_unix.c 2005-01-15 11:27:52 +0100 @@ -88,8 +92,10 @@ unx_create_cred(struct rpc_auth *auth, s cred->uc_uid = acred->uid; cred->uc_gid = acred->gid; + cred->uc_xid = acred->xid; cred->uc_puid = current->uid; cred->uc_pgid = current->gid; + cred->uc_pxid = vx_current_xid(); for (i = 0; i < groups; i++) cred->uc_gids[i] = GROUP_AT(acred->group_info, i); if (i < NFS_NGROUPS) --- linux-2.6.11-rc1/net/sunrpc/auth_unix.c 2004-08-14 12:55:33 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/net/sunrpc/auth_unix.c 2005-01-15 11:27:52 +0100 @@ -122,8 +128,10 @@ unx_match(struct auth_cred *acred, struc if (cred->uc_uid != acred->uid || cred->uc_gid != acred->gid + || cred->uc_xid != acred->xid || cred->uc_puid != current->uid - || cred->uc_pgid != current->gid) + || cred->uc_pgid != current->gid + || cred->uc_pxid != vx_current_xid()) return 0; groups = acred->group_info->ngroups; --- linux-2.6.11-rc1/net/sunrpc/auth_unix.c 2004-08-14 12:55:33 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/net/sunrpc/auth_unix.c 2005-01-15 11:27:52 +0100 @@ -149,7 +157,7 @@ unx_marshal(struct rpc_task *task, u32 * struct rpc_clnt *clnt = task->tk_client; struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred; u32 *base, *hold; - int i; + int i, tagxid; *p++ = htonl(RPC_AUTH_UNIX); base = p++; --- linux-2.6.11-rc1/net/sunrpc/auth_unix.c 2004-08-14 12:55:33 +0200 +++ linux-2.6.11-rc1-vs1.9.4-rc2/net/sunrpc/auth_unix.c 2005-01-15 11:27:52 +0100 @@ -159,14 +167,19 @@ unx_marshal(struct rpc_task *task, u32 * * Copy the UTS nodename captured when the client was created. */ p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen); + tagxid = task->tk_client->cl_tagxid; /* Note: we don't use real uid if it involves raising privilege */ if (ruid && cred->uc_puid != 0 && cred->uc_pgid != 0) { - *p++ = htonl((u32) cred->uc_puid); - *p++ = htonl((u32) cred->uc_pgid); + *p++ = htonl((u32) XIDINO_UID(tagxid, + cred->uc_puid, cred->uc_pxid)); + *p++ = htonl((u32) XIDINO_GID(tagxid, + cred->uc_pgid, cred->uc_pxid)); } else { - *p++ = htonl((u32) cred->uc_uid); - *p++ = htonl((u32) cred->uc_gid); + *p++ = htonl((u32) XIDINO_UID(tagxid, + cred->uc_uid, cred->uc_xid)); + *p++ = htonl((u32) XIDINO_GID(tagxid, + cred->uc_gid, cred->uc_xid)); } hold = p++; for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++)