This adds the XATTR_KERNEL_CONTEXT extended attributes flag. Kernel code may use this flag to override extended attribute permission restrictions that would otherwise be imposed on the calling process. --- linux-2.5.60~xattr-flags-policy/fs/ext2/xattr_user.c 2003-02-11 12:40:20.000000000 +0100 +++ linux-2.5.60/fs/ext2/xattr_user.c 2003-02-11 12:40:29.000000000 +0100 @@ -23,7 +23,8 @@ { const int prefix_len = sizeof(XATTR_USER_PREFIX)-1; - if (!test_opt(inode->i_sb, XATTR_USER)) + if (!(flags & XATTR_KERNEL_CONTEXT) && + !test_opt(inode->i_sb, XATTR_USER)) return 0; if (list) { @@ -38,20 +39,21 @@ ext2_xattr_user_get(struct inode *inode, const char *name, void *buffer, size_t size, int flags) { - int error; - if (strcmp(name, "") == 0) return -EINVAL; - if (!test_opt(inode->i_sb, XATTR_USER)) - return -EOPNOTSUPP; + if (!(flags & XATTR_KERNEL_CONTEXT)) { + int error; + + if (!test_opt(inode->i_sb, XATTR_USER)) + return -EOPNOTSUPP; #ifdef CONFIG_EXT2_FS_POSIX_ACL - error = ext2_permission_locked(inode, MAY_READ); + error = ext2_permission_locked(inode, MAY_READ); #else - error = permission(inode, MAY_READ); + error = permission(inode, MAY_READ); #endif - if (error) - return error; - + if (error) + return error; + } return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name, buffer, size); } @@ -60,23 +62,24 @@ ext2_xattr_user_set(struct inode *inode, const char *name, const void *value, size_t size, int flags) { - int error; - if (strcmp(name, "") == 0) return -EINVAL; - if (!test_opt(inode->i_sb, XATTR_USER)) - return -EOPNOTSUPP; if ( !S_ISREG(inode->i_mode) && (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) return -EPERM; + if (!(flags & XATTR_KERNEL_CONTEXT)) { + int error; + + if (!test_opt(inode->i_sb, XATTR_USER)) + return -EOPNOTSUPP; #ifdef CONFIG_EXT2_FS_POSIX_ACL - error = ext2_permission_locked(inode, MAY_WRITE); + error = ext2_permission_locked(inode, MAY_WRITE); #else - error = permission(inode, MAY_WRITE); + error = permission(inode, MAY_WRITE); #endif - if (error) - return error; - + if (error) + return error; + } return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name, value, size, flags); } Index: linux-2.5.60/fs/ext3/xattr_user.c --- linux-2.5.60~xattr-flags-policy/fs/ext3/xattr_user.c 2003-02-11 12:40:20.000000000 +0100 +++ linux-2.5.60/fs/ext3/xattr_user.c 2003-02-11 12:46:12.000000000 +0100 @@ -25,7 +25,8 @@ { const int prefix_len = sizeof(XATTR_USER_PREFIX)-1; - if (!test_opt(inode->i_sb, XATTR_USER)) + if (!(flags & XATTR_KERNEL_CONTEXT) && + !test_opt(inode->i_sb, XATTR_USER)) return 0; if (list) { @@ -40,20 +41,21 @@ ext3_xattr_user_get(struct inode *inode, const char *name, void *buffer, size_t size, int flags) { - int error; - if (strcmp(name, "") == 0) return -EINVAL; - if (!test_opt(inode->i_sb, XATTR_USER)) - return -EOPNOTSUPP; + if (!(flags & XATTR_KERNEL_CONTEXT)) { + int error; + + if (!test_opt(inode->i_sb, XATTR_USER)) + return -EOPNOTSUPP; #ifdef CONFIG_EXT3_FS_POSIX_ACL - error = ext3_permission_locked(inode, MAY_READ); + error = ext3_permission_locked(inode, MAY_READ); #else - error = permission(inode, MAY_READ); + error = permission(inode, MAY_READ); #endif - if (error) - return error; - + if (error) + return error; + } return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name, buffer, size); } @@ -62,26 +64,26 @@ ext3_xattr_user_set(struct inode *inode, const char *name, const void *value, size_t size, int flags) { - int error; - if (strcmp(name, "") == 0) return -EINVAL; - if (!test_opt(inode->i_sb, XATTR_USER)) - return -EOPNOTSUPP; if ( !S_ISREG(inode->i_mode) && (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) return -EPERM; + if (!(flags & XATTR_KERNEL_CONTEXT)) { + int error; + + if (!test_opt(inode->i_sb, XATTR_USER)) + return -EOPNOTSUPP; #ifdef CONFIG_EXT3_FS_POSIX_ACL - error = ext3_permission_locked(inode, MAY_WRITE); + error = ext3_permission_locked(inode, MAY_WRITE); #else - error = permission(inode, MAY_WRITE); + error = permission(inode, MAY_WRITE); #endif - if (error) - return error; - + if (error) + return error; + } return ext3_xattr_set(inode, EXT3_XATTR_INDEX_USER, name, value, size, flags); - } struct ext3_xattr_handler ext3_xattr_user_handler = { Index: linux-2.5.60/include/linux/xattr.h --- linux-2.5.60~xattr-flags-policy/include/linux/xattr.h 2003-02-10 19:38:44.000000000 +0100 +++ linux-2.5.60/include/linux/xattr.h 2003-02-11 12:40:29.000000000 +0100 @@ -9,7 +9,8 @@ #ifndef _LINUX_XATTR_H #define _LINUX_XATTR_H -#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ -#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ +#define XATTR_CREATE 0x1 /* fail if attr already exists */ +#define XATTR_REPLACE 0x2 /* fail if attr does not exist */ +#define XATTR_KERNEL_CONTEXT 0x4 /* called from kernel context */ #endif /* _LINUX_XATTR_H */