Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

security: new security_inode_init_security API adds function callback

This patch changes the security_inode_init_security API by adding a
filesystem specific callback to write security extended attributes.
This change is in preparation for supporting the initialization of
multiple LSM xattrs and the EVM xattr. Initially the callback function
walks an array of xattrs, writing each xattr separately, but could be
optimized to write multiple xattrs at once.

For existing security_inode_init_security() calls, which have not yet
been converted to use the new callback function, such as those in
reiserfs and ocfs2, this patch defines security_old_inode_init_security().

Signed-off-by: Mimi Zohar <zohar@us.ibm.com>

+255 -188
+28 -28
fs/btrfs/xattr.c
··· 360 360 XATTR_REPLACE); 361 361 } 362 362 363 + int btrfs_initxattrs(struct inode *inode, const struct xattr *xattr_array, 364 + void *fs_info) 365 + { 366 + const struct xattr *xattr; 367 + struct btrfs_trans_handle *trans = fs_info; 368 + char *name; 369 + int err = 0; 370 + 371 + for (xattr = xattr_array; xattr->name != NULL; xattr++) { 372 + name = kmalloc(XATTR_SECURITY_PREFIX_LEN + 373 + strlen(xattr->name) + 1, GFP_NOFS); 374 + if (!name) { 375 + err = -ENOMEM; 376 + break; 377 + } 378 + strcpy(name, XATTR_SECURITY_PREFIX); 379 + strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name); 380 + err = __btrfs_setxattr(trans, inode, name, 381 + xattr->value, xattr->value_len, 0); 382 + kfree(name); 383 + if (err < 0) 384 + break; 385 + } 386 + return err; 387 + } 388 + 363 389 int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, 364 390 struct inode *inode, struct inode *dir, 365 391 const struct qstr *qstr) 366 392 { 367 - int err; 368 - size_t len; 369 - void *value; 370 - char *suffix; 371 - char *name; 372 - 373 - err = security_inode_init_security(inode, dir, qstr, &suffix, &value, 374 - &len); 375 - if (err) { 376 - if (err == -EOPNOTSUPP) 377 - return 0; 378 - return err; 379 - } 380 - 381 - name = kmalloc(XATTR_SECURITY_PREFIX_LEN + strlen(suffix) + 1, 382 - GFP_NOFS); 383 - if (!name) { 384 - err = -ENOMEM; 385 - } else { 386 - strcpy(name, XATTR_SECURITY_PREFIX); 387 - strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); 388 - err = __btrfs_setxattr(trans, inode, name, value, len, 0); 389 - kfree(name); 390 - } 391 - 392 - kfree(suffix); 393 - kfree(value); 394 - return err; 393 + return security_inode_init_security(inode, dir, qstr, 394 + &btrfs_initxattrs, trans); 395 395 }
+18 -16
fs/ext2/xattr_security.c
··· 46 46 value, size, flags); 47 47 } 48 48 49 + int ext2_initxattrs(struct inode *inode, const struct xattr *xattr_array, 50 + void *fs_info) 51 + { 52 + const struct xattr *xattr; 53 + int err = 0; 54 + 55 + for (xattr = xattr_array; xattr->name != NULL; xattr++) { 56 + err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY, 57 + xattr->name, xattr->value, 58 + xattr->value_len, 0); 59 + if (err < 0) 60 + break; 61 + } 62 + return err; 63 + } 64 + 49 65 int 50 66 ext2_init_security(struct inode *inode, struct inode *dir, 51 67 const struct qstr *qstr) 52 68 { 53 - int err; 54 - size_t len; 55 - void *value; 56 - char *name; 57 - 58 - err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); 59 - if (err) { 60 - if (err == -EOPNOTSUPP) 61 - return 0; 62 - return err; 63 - } 64 - err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY, 65 - name, value, len, 0); 66 - kfree(name); 67 - kfree(value); 68 - return err; 69 + return security_inode_init_security(inode, dir, qstr, 70 + &ext2_initxattrs, NULL); 69 71 } 70 72 71 73 const struct xattr_handler ext2_xattr_security_handler = {
+20 -16
fs/ext3/xattr_security.c
··· 48 48 name, value, size, flags); 49 49 } 50 50 51 + int ext3_initxattrs(struct inode *inode, const struct xattr *xattr_array, 52 + void *fs_info) 53 + { 54 + const struct xattr *xattr; 55 + handle_t *handle = fs_info; 56 + int err = 0; 57 + 58 + for (xattr = xattr_array; xattr->name != NULL; xattr++) { 59 + err = ext3_xattr_set_handle(handle, inode, 60 + EXT3_XATTR_INDEX_SECURITY, 61 + xattr->name, xattr->value, 62 + xattr->value_len, 0); 63 + if (err < 0) 64 + break; 65 + } 66 + return err; 67 + } 68 + 51 69 int 52 70 ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir, 53 71 const struct qstr *qstr) 54 72 { 55 - int err; 56 - size_t len; 57 - void *value; 58 - char *name; 59 - 60 - err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); 61 - if (err) { 62 - if (err == -EOPNOTSUPP) 63 - return 0; 64 - return err; 65 - } 66 - err = ext3_xattr_set_handle(handle, inode, EXT3_XATTR_INDEX_SECURITY, 67 - name, value, len, 0); 68 - kfree(name); 69 - kfree(value); 70 - return err; 73 + return security_inode_init_security(inode, dir, qstr, 74 + &ext3_initxattrs, handle); 71 75 } 72 76 73 77 const struct xattr_handler ext3_xattr_security_handler = {
+20 -16
fs/ext4/xattr_security.c
··· 48 48 name, value, size, flags); 49 49 } 50 50 51 + int ext4_initxattrs(struct inode *inode, const struct xattr *xattr_array, 52 + void *fs_info) 53 + { 54 + const struct xattr *xattr; 55 + handle_t *handle = fs_info; 56 + int err = 0; 57 + 58 + for (xattr = xattr_array; xattr->name != NULL; xattr++) { 59 + err = ext4_xattr_set_handle(handle, inode, 60 + EXT4_XATTR_INDEX_SECURITY, 61 + xattr->name, xattr->value, 62 + xattr->value_len, 0); 63 + if (err < 0) 64 + break; 65 + } 66 + return err; 67 + } 68 + 51 69 int 52 70 ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir, 53 71 const struct qstr *qstr) 54 72 { 55 - int err; 56 - size_t len; 57 - void *value; 58 - char *name; 59 - 60 - err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); 61 - if (err) { 62 - if (err == -EOPNOTSUPP) 63 - return 0; 64 - return err; 65 - } 66 - err = ext4_xattr_set_handle(handle, inode, EXT4_XATTR_INDEX_SECURITY, 67 - name, value, len, 0); 68 - kfree(name); 69 - kfree(value); 70 - return err; 73 + return security_inode_init_security(inode, dir, qstr, 74 + &ext4_initxattrs, handle); 71 75 } 72 76 73 77 const struct xattr_handler ext4_xattr_security_handler = {
+18 -20
fs/gfs2/inode.c
··· 624 624 return error; 625 625 } 626 626 627 + int gfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array, 628 + void *fs_info) 629 + { 630 + const struct xattr *xattr; 631 + int err = 0; 632 + 633 + for (xattr = xattr_array; xattr->name != NULL; xattr++) { 634 + err = __gfs2_xattr_set(inode, xattr->name, xattr->value, 635 + xattr->value_len, 0, 636 + GFS2_EATYPE_SECURITY); 637 + if (err < 0) 638 + break; 639 + } 640 + return err; 641 + } 642 + 627 643 static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip, 628 644 const struct qstr *qstr) 629 645 { 630 - int err; 631 - size_t len; 632 - void *value; 633 - char *name; 634 - 635 - err = security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr, 636 - &name, &value, &len); 637 - 638 - if (err) { 639 - if (err == -EOPNOTSUPP) 640 - return 0; 641 - return err; 642 - } 643 - 644 - err = __gfs2_xattr_set(&ip->i_inode, name, value, len, 0, 645 - GFS2_EATYPE_SECURITY); 646 - kfree(value); 647 - kfree(name); 648 - 649 - return err; 646 + return security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr, 647 + &gfs2_initxattrs, NULL); 650 648 } 651 649 652 650 /**
+20 -17
fs/jffs2/security.c
··· 22 22 #include <linux/security.h> 23 23 #include "nodelist.h" 24 24 25 - /* ---- Initial Security Label Attachment -------------- */ 25 + /* ---- Initial Security Label(s) Attachment callback --- */ 26 + int jffs2_initxattrs(struct inode *inode, const struct xattr *xattr_array, 27 + void *fs_info) 28 + { 29 + const struct xattr *xattr; 30 + int err = 0; 31 + 32 + for (xattr = xattr_array; xattr->name != NULL; xattr++) { 33 + err = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, 34 + xattr->name, xattr->value, 35 + xattr->value_len, 0); 36 + if (err < 0) 37 + break; 38 + } 39 + return err; 40 + } 41 + 42 + /* ---- Initial Security Label(s) Attachment ----------- */ 26 43 int jffs2_init_security(struct inode *inode, struct inode *dir, 27 44 const struct qstr *qstr) 28 45 { 29 - int rc; 30 - size_t len; 31 - void *value; 32 - char *name; 33 - 34 - rc = security_inode_init_security(inode, dir, qstr, &name, &value, &len); 35 - if (rc) { 36 - if (rc == -EOPNOTSUPP) 37 - return 0; 38 - return rc; 39 - } 40 - rc = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, name, value, len, 0); 41 - 42 - kfree(name); 43 - kfree(value); 44 - return rc; 46 + return security_inode_init_security(inode, dir, qstr, 47 + &jffs2_initxattrs, NULL); 45 48 } 46 49 47 50 /* ---- XATTR Handler for "security.*" ----------------- */
+29 -30
fs/jfs/xattr.c
··· 1091 1091 } 1092 1092 1093 1093 #ifdef CONFIG_JFS_SECURITY 1094 + int jfs_initxattrs(struct inode *inode, const struct xattr *xattr_array, 1095 + void *fs_info) 1096 + { 1097 + const struct xattr *xattr; 1098 + tid_t *tid = fs_info; 1099 + char *name; 1100 + int err = 0; 1101 + 1102 + for (xattr = xattr_array; xattr->name != NULL; xattr++) { 1103 + name = kmalloc(XATTR_SECURITY_PREFIX_LEN + 1104 + strlen(xattr->name) + 1, GFP_NOFS); 1105 + if (!name) { 1106 + err = -ENOMEM; 1107 + break; 1108 + } 1109 + strcpy(name, XATTR_SECURITY_PREFIX); 1110 + strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name); 1111 + 1112 + err = __jfs_setxattr(*tid, inode, name, 1113 + xattr->value, xattr->value_len, 0); 1114 + kfree(name); 1115 + if (err < 0) 1116 + break; 1117 + } 1118 + return err; 1119 + } 1120 + 1094 1121 int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir, 1095 1122 const struct qstr *qstr) 1096 1123 { 1097 - int rc; 1098 - size_t len; 1099 - void *value; 1100 - char *suffix; 1101 - char *name; 1102 - 1103 - rc = security_inode_init_security(inode, dir, qstr, &suffix, &value, 1104 - &len); 1105 - if (rc) { 1106 - if (rc == -EOPNOTSUPP) 1107 - return 0; 1108 - return rc; 1109 - } 1110 - name = kmalloc(XATTR_SECURITY_PREFIX_LEN + 1 + strlen(suffix), 1111 - GFP_NOFS); 1112 - if (!name) { 1113 - rc = -ENOMEM; 1114 - goto kmalloc_failed; 1115 - } 1116 - strcpy(name, XATTR_SECURITY_PREFIX); 1117 - strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); 1118 - 1119 - rc = __jfs_setxattr(tid, inode, name, value, len, 0); 1120 - 1121 - kfree(name); 1122 - kmalloc_failed: 1123 - kfree(suffix); 1124 - kfree(value); 1125 - 1126 - return rc; 1124 + return security_inode_init_security(inode, dir, qstr, 1125 + &jfs_initxattrs, &tid); 1127 1126 } 1128 1127 #endif
+24 -14
fs/ocfs2/xattr.c
··· 7185 7185 { 7186 7186 int ret = 0; 7187 7187 struct buffer_head *dir_bh = NULL; 7188 - struct ocfs2_security_xattr_info si = { 7189 - .enable = 1, 7190 - }; 7191 7188 7192 - ret = ocfs2_init_security_get(inode, dir, qstr, &si); 7189 + ret = ocfs2_init_security_get(inode, dir, qstr, NULL); 7193 7190 if (!ret) { 7194 - ret = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY, 7195 - si.name, si.value, si.value_len, 7196 - XATTR_CREATE); 7197 - if (ret) { 7198 - mlog_errno(ret); 7199 - goto leave; 7200 - } 7201 - } else if (ret != -EOPNOTSUPP) { 7202 7191 mlog_errno(ret); 7203 7192 goto leave; 7204 7193 } ··· 7244 7255 name, value, size, flags); 7245 7256 } 7246 7257 7258 + int ocfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array, 7259 + void *fs_info) 7260 + { 7261 + const struct xattr *xattr; 7262 + int err = 0; 7263 + 7264 + for (xattr = xattr_array; xattr->name != NULL; xattr++) { 7265 + err = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY, 7266 + xattr->name, xattr->value, 7267 + xattr->value_len, XATTR_CREATE); 7268 + if (err) 7269 + break; 7270 + } 7271 + return err; 7272 + } 7273 + 7247 7274 int ocfs2_init_security_get(struct inode *inode, 7248 7275 struct inode *dir, 7249 7276 const struct qstr *qstr, ··· 7268 7263 /* check whether ocfs2 support feature xattr */ 7269 7264 if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb))) 7270 7265 return -EOPNOTSUPP; 7271 - return security_inode_init_security(inode, dir, qstr, &si->name, 7272 - &si->value, &si->value_len); 7266 + if (si) 7267 + return security_old_inode_init_security(inode, dir, qstr, 7268 + &si->name, &si->value, 7269 + &si->value_len); 7270 + 7271 + return security_inode_init_security(inode, dir, qstr, 7272 + &ocfs2_initxattrs, NULL); 7273 7273 } 7274 7274 7275 7275 int ocfs2_init_security_set(handle_t *handle,
+2 -2
fs/reiserfs/xattr_security.c
··· 66 66 if (IS_PRIVATE(dir)) 67 67 return 0; 68 68 69 - error = security_inode_init_security(inode, dir, qstr, &sec->name, 70 - &sec->value, &sec->length); 69 + error = security_old_inode_init_security(inode, dir, qstr, &sec->name, 70 + &sec->value, &sec->length); 71 71 if (error) { 72 72 if (error == -EOPNOTSUPP) 73 73 error = 0;
+20 -19
fs/xfs/linux-2.6/xfs_iops.c
··· 93 93 mark_inode_dirty(inode); 94 94 } 95 95 96 + 97 + int xfs_initxattrs(struct inode *inode, const struct xattr *xattr_array, 98 + void *fs_info) 99 + { 100 + const struct xattr *xattr; 101 + struct xfs_inode *ip = XFS_I(inode); 102 + int error = 0; 103 + 104 + for (xattr = xattr_array; xattr->name != NULL; xattr++) { 105 + error = xfs_attr_set(ip, xattr->name, xattr->value, 106 + xattr->value_len, ATTR_SECURE); 107 + if (error < 0) 108 + break; 109 + } 110 + return error; 111 + } 112 + 96 113 /* 97 114 * Hook in SELinux. This is not quite correct yet, what we really need 98 115 * here (as we do for default ACLs) is a mechanism by which creation of 99 116 * these attrs can be journalled at inode creation time (along with the 100 117 * inode, of course, such that log replay can't cause these to be lost). 101 118 */ 119 + 102 120 STATIC int 103 121 xfs_init_security( 104 122 struct inode *inode, 105 123 struct inode *dir, 106 124 const struct qstr *qstr) 107 125 { 108 - struct xfs_inode *ip = XFS_I(inode); 109 - size_t length; 110 - void *value; 111 - unsigned char *name; 112 - int error; 113 - 114 - error = security_inode_init_security(inode, dir, qstr, (char **)&name, 115 - &value, &length); 116 - if (error) { 117 - if (error == -EOPNOTSUPP) 118 - return 0; 119 - return -error; 120 - } 121 - 122 - error = xfs_attr_set(ip, name, value, length, ATTR_SECURE); 123 - 124 - kfree(name); 125 - kfree(value); 126 - return error; 126 + return security_inode_init_security(inode, dir, qstr, 127 + &xfs_initxattrs, NULL); 127 128 } 128 129 129 130 static void
+12 -5
include/linux/security.h
··· 36 36 #include <linux/key.h> 37 37 #include <linux/xfrm.h> 38 38 #include <linux/slab.h> 39 + #include <linux/xattr.h> 39 40 #include <net/flow.h> 40 41 41 42 /* Maximum number of letters for an LSM name string */ ··· 147 146 extern int mmap_min_addr_handler(struct ctl_table *table, int write, 148 147 void __user *buffer, size_t *lenp, loff_t *ppos); 149 148 #endif 149 + 150 + /* security_inode_init_security callback function to write xattrs */ 151 + typedef int (*initxattrs) (struct inode *inode, 152 + const struct xattr *xattr_array, void *fs_data); 150 153 151 154 #ifdef CONFIG_SECURITY 152 155 ··· 1709 1704 int security_inode_alloc(struct inode *inode); 1710 1705 void security_inode_free(struct inode *inode); 1711 1706 int security_inode_init_security(struct inode *inode, struct inode *dir, 1712 - const struct qstr *qstr, char **name, 1713 - void **value, size_t *len); 1707 + const struct qstr *qstr, 1708 + initxattrs initxattrs, void *fs_data); 1709 + int security_old_inode_init_security(struct inode *inode, struct inode *dir, 1710 + const struct qstr *qstr, char **name, 1711 + void **value, size_t *len); 1714 1712 int security_inode_create(struct inode *dir, struct dentry *dentry, int mode); 1715 1713 int security_inode_link(struct dentry *old_dentry, struct inode *dir, 1716 1714 struct dentry *new_dentry); ··· 2043 2035 static inline int security_inode_init_security(struct inode *inode, 2044 2036 struct inode *dir, 2045 2037 const struct qstr *qstr, 2046 - char **name, 2047 - void **value, 2048 - size_t *len) 2038 + initxattrs initxattrs, 2039 + void *fs_data) 2049 2040 { 2050 2041 return -EOPNOTSUPP; 2051 2042 }
+6
include/linux/xattr.h
··· 67 67 size_t size, int flags, int handler_flags); 68 68 }; 69 69 70 + struct xattr { 71 + char *name; 72 + void *value; 73 + size_t value_len; 74 + }; 75 + 70 76 ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t); 71 77 ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t); 72 78 ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
+2 -2
mm/shmem.c
··· 1878 1878 inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE); 1879 1879 if (inode) { 1880 1880 error = security_inode_init_security(inode, dir, 1881 - &dentry->d_name, NULL, 1881 + &dentry->d_name, 1882 1882 NULL, NULL); 1883 1883 if (error) { 1884 1884 if (error != -EOPNOTSUPP) { ··· 2018 2018 if (!inode) 2019 2019 return -ENOSPC; 2020 2020 2021 - error = security_inode_init_security(inode, dir, &dentry->d_name, NULL, 2021 + error = security_inode_init_security(inode, dir, &dentry->d_name, 2022 2022 NULL, NULL); 2023 2023 if (error) { 2024 2024 if (error != -EOPNOTSUPP) {
+36 -3
security/security.c
··· 18 18 #include <linux/security.h> 19 19 #include <linux/ima.h> 20 20 21 + #define MAX_LSM_XATTR 1 22 + 21 23 /* Boot-time LSM user choice */ 22 24 static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = 23 25 CONFIG_DEFAULT_SECURITY; ··· 341 339 } 342 340 343 341 int security_inode_init_security(struct inode *inode, struct inode *dir, 344 - const struct qstr *qstr, char **name, 345 - void **value, size_t *len) 342 + const struct qstr *qstr, 343 + const initxattrs initxattrs, void *fs_data) 344 + { 345 + struct xattr new_xattrs[MAX_LSM_XATTR + 1]; 346 + struct xattr *lsm_xattr; 347 + int ret; 348 + 349 + if (unlikely(IS_PRIVATE(inode))) 350 + return -EOPNOTSUPP; 351 + 352 + memset(new_xattrs, 0, sizeof new_xattrs); 353 + if (!initxattrs) 354 + return security_ops->inode_init_security(inode, dir, qstr, 355 + NULL, NULL, NULL); 356 + lsm_xattr = new_xattrs; 357 + ret = security_ops->inode_init_security(inode, dir, qstr, 358 + &lsm_xattr->name, 359 + &lsm_xattr->value, 360 + &lsm_xattr->value_len); 361 + if (ret) 362 + goto out; 363 + ret = initxattrs(inode, new_xattrs, fs_data); 364 + out: 365 + kfree(lsm_xattr->name); 366 + kfree(lsm_xattr->value); 367 + 368 + return (ret == -EOPNOTSUPP) ? 0 : ret; 369 + } 370 + EXPORT_SYMBOL(security_inode_init_security); 371 + 372 + int security_old_inode_init_security(struct inode *inode, struct inode *dir, 373 + const struct qstr *qstr, char **name, 374 + void **value, size_t *len) 346 375 { 347 376 if (unlikely(IS_PRIVATE(inode))) 348 377 return -EOPNOTSUPP; 349 378 return security_ops->inode_init_security(inode, dir, qstr, name, value, 350 379 len); 351 380 } 352 - EXPORT_SYMBOL(security_inode_init_security); 381 + EXPORT_SYMBOL(security_old_inode_init_security); 353 382 354 383 #ifdef CONFIG_SECURITY_PATH 355 384 int security_path_mknod(struct path *dir, struct dentry *dentry, int mode,