aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMimi Zohar <zohar@linux.vnet.ibm.com>2011-06-06 15:29:25 -0400
committerMimi Zohar <zohar@linux.vnet.ibm.com>2011-07-18 12:29:38 -0400
commit9d8f13ba3f4833219e50767b022b82cd0da930eb (patch)
tree3ba2367380d009111ea17696162a62320c88d144 /fs
parent0f2a55d5bb2372058275b0b343d90dd5d640d045 (diff)
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/xattr.c50
-rw-r--r--fs/ext2/xattr_security.c34
-rw-r--r--fs/ext3/xattr_security.c36
-rw-r--r--fs/ext4/xattr_security.c36
-rw-r--r--fs/gfs2/inode.c38
-rw-r--r--fs/jffs2/security.c35
-rw-r--r--fs/jfs/xattr.c57
-rw-r--r--fs/ocfs2/xattr.c38
-rw-r--r--fs/reiserfs/xattr_security.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c39
10 files changed, 194 insertions, 173 deletions
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index 5366fe452ab0..a039e6ed4ce0 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -360,36 +360,36 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
360 XATTR_REPLACE); 360 XATTR_REPLACE);
361} 361}
362 362
363int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, 363int btrfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
364 struct inode *inode, struct inode *dir, 364 void *fs_info)
365 const struct qstr *qstr)
366{ 365{
367 int err; 366 const struct xattr *xattr;
368 size_t len; 367 struct btrfs_trans_handle *trans = fs_info;
369 void *value;
370 char *suffix;
371 char *name; 368 char *name;
369 int err = 0;
372 370
373 err = security_inode_init_security(inode, dir, qstr, &suffix, &value, 371 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
374 &len); 372 name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
375 if (err) { 373 strlen(xattr->name) + 1, GFP_NOFS);
376 if (err == -EOPNOTSUPP) 374 if (!name) {
377 return 0; 375 err = -ENOMEM;
378 return err; 376 break;
379 } 377 }
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); 378 strcpy(name, XATTR_SECURITY_PREFIX);
387 strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); 379 strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
388 err = __btrfs_setxattr(trans, inode, name, value, len, 0); 380 err = __btrfs_setxattr(trans, inode, name,
381 xattr->value, xattr->value_len, 0);
389 kfree(name); 382 kfree(name);
383 if (err < 0)
384 break;
390 } 385 }
391
392 kfree(suffix);
393 kfree(value);
394 return err; 386 return err;
395} 387}
388
389int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
390 struct inode *inode, struct inode *dir,
391 const struct qstr *qstr)
392{
393 return security_inode_init_security(inode, dir, qstr,
394 &btrfs_initxattrs, trans);
395}
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c
index 5d979b4347b0..c922adc8ef41 100644
--- a/fs/ext2/xattr_security.c
+++ b/fs/ext2/xattr_security.c
@@ -46,28 +46,30 @@ ext2_xattr_security_set(struct dentry *dentry, const char *name,
46 value, size, flags); 46 value, size, flags);
47} 47}
48 48
49int 49int ext2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
50ext2_init_security(struct inode *inode, struct inode *dir, 50 void *fs_info)
51 const struct qstr *qstr)
52{ 51{
53 int err; 52 const struct xattr *xattr;
54 size_t len; 53 int err = 0;
55 void *value;
56 char *name;
57 54
58 err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); 55 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
59 if (err) { 56 err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY,
60 if (err == -EOPNOTSUPP) 57 xattr->name, xattr->value,
61 return 0; 58 xattr->value_len, 0);
62 return err; 59 if (err < 0)
60 break;
63 } 61 }
64 err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY,
65 name, value, len, 0);
66 kfree(name);
67 kfree(value);
68 return err; 62 return err;
69} 63}
70 64
65int
66ext2_init_security(struct inode *inode, struct inode *dir,
67 const struct qstr *qstr)
68{
69 return security_inode_init_security(inode, dir, qstr,
70 &ext2_initxattrs, NULL);
71}
72
71const struct xattr_handler ext2_xattr_security_handler = { 73const struct xattr_handler ext2_xattr_security_handler = {
72 .prefix = XATTR_SECURITY_PREFIX, 74 .prefix = XATTR_SECURITY_PREFIX,
73 .list = ext2_xattr_security_list, 75 .list = ext2_xattr_security_list,
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c
index b8d9f83aa5c5..3c218b8a51d4 100644
--- a/fs/ext3/xattr_security.c
+++ b/fs/ext3/xattr_security.c
@@ -48,28 +48,32 @@ ext3_xattr_security_set(struct dentry *dentry, const char *name,
48 name, value, size, flags); 48 name, value, size, flags);
49} 49}
50 50
51int 51int ext3_initxattrs(struct inode *inode, const struct xattr *xattr_array,
52ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir, 52 void *fs_info)
53 const struct qstr *qstr)
54{ 53{
55 int err; 54 const struct xattr *xattr;
56 size_t len; 55 handle_t *handle = fs_info;
57 void *value; 56 int err = 0;
58 char *name;
59 57
60 err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); 58 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
61 if (err) { 59 err = ext3_xattr_set_handle(handle, inode,
62 if (err == -EOPNOTSUPP) 60 EXT3_XATTR_INDEX_SECURITY,
63 return 0; 61 xattr->name, xattr->value,
64 return err; 62 xattr->value_len, 0);
63 if (err < 0)
64 break;
65 } 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; 66 return err;
71} 67}
72 68
69int
70ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
71 const struct qstr *qstr)
72{
73 return security_inode_init_security(inode, dir, qstr,
74 &ext3_initxattrs, handle);
75}
76
73const struct xattr_handler ext3_xattr_security_handler = { 77const struct xattr_handler ext3_xattr_security_handler = {
74 .prefix = XATTR_SECURITY_PREFIX, 78 .prefix = XATTR_SECURITY_PREFIX,
75 .list = ext3_xattr_security_list, 79 .list = ext3_xattr_security_list,
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c
index 007c3bfbf094..34e4350dd4d9 100644
--- a/fs/ext4/xattr_security.c
+++ b/fs/ext4/xattr_security.c
@@ -48,28 +48,32 @@ ext4_xattr_security_set(struct dentry *dentry, const char *name,
48 name, value, size, flags); 48 name, value, size, flags);
49} 49}
50 50
51int 51int ext4_initxattrs(struct inode *inode, const struct xattr *xattr_array,
52ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir, 52 void *fs_info)
53 const struct qstr *qstr)
54{ 53{
55 int err; 54 const struct xattr *xattr;
56 size_t len; 55 handle_t *handle = fs_info;
57 void *value; 56 int err = 0;
58 char *name;
59 57
60 err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); 58 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
61 if (err) { 59 err = ext4_xattr_set_handle(handle, inode,
62 if (err == -EOPNOTSUPP) 60 EXT4_XATTR_INDEX_SECURITY,
63 return 0; 61 xattr->name, xattr->value,
64 return err; 62 xattr->value_len, 0);
63 if (err < 0)
64 break;
65 } 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; 66 return err;
71} 67}
72 68
69int
70ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
71 const struct qstr *qstr)
72{
73 return security_inode_init_security(inode, dir, qstr,
74 &ext4_initxattrs, handle);
75}
76
73const struct xattr_handler ext4_xattr_security_handler = { 77const struct xattr_handler ext4_xattr_security_handler = {
74 .prefix = XATTR_SECURITY_PREFIX, 78 .prefix = XATTR_SECURITY_PREFIX,
75 .list = ext4_xattr_security_list, 79 .list = ext4_xattr_security_list,
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 03e0c529063e..1d3a1a651721 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -624,31 +624,29 @@ fail:
624 return error; 624 return error;
625} 625}
626 626
627static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip, 627int gfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
628 const struct qstr *qstr) 628 void *fs_info)
629{ 629{
630 int err; 630 const struct xattr *xattr;
631 size_t len; 631 int err = 0;
632 void *value; 632
633 char *name; 633 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
634 634 err = __gfs2_xattr_set(inode, xattr->name, xattr->value,
635 err = security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr, 635 xattr->value_len, 0,
636 &name, &value, &len); 636 GFS2_EATYPE_SECURITY);
637 637 if (err < 0)
638 if (err) { 638 break;
639 if (err == -EOPNOTSUPP)
640 return 0;
641 return err;
642 } 639 }
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; 640 return err;
650} 641}
651 642
643static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
644 const struct qstr *qstr)
645{
646 return security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr,
647 &gfs2_initxattrs, NULL);
648}
649
652/** 650/**
653 * gfs2_create_inode - Create a new inode 651 * gfs2_create_inode - Create a new inode
654 * @dir: The parent directory 652 * @dir: The parent directory
diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c
index cfeb7164b085..0f20208df602 100644
--- a/fs/jffs2/security.c
+++ b/fs/jffs2/security.c
@@ -22,26 +22,29 @@
22#include <linux/security.h> 22#include <linux/security.h>
23#include "nodelist.h" 23#include "nodelist.h"
24 24
25/* ---- Initial Security Label Attachment -------------- */ 25/* ---- Initial Security Label(s) Attachment callback --- */
26int jffs2_init_security(struct inode *inode, struct inode *dir, 26int jffs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
27 const struct qstr *qstr) 27 void *fs_info)
28{ 28{
29 int rc; 29 const struct xattr *xattr;
30 size_t len; 30 int err = 0;
31 void *value;
32 char *name;
33 31
34 rc = security_inode_init_security(inode, dir, qstr, &name, &value, &len); 32 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
35 if (rc) { 33 err = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY,
36 if (rc == -EOPNOTSUPP) 34 xattr->name, xattr->value,
37 return 0; 35 xattr->value_len, 0);
38 return rc; 36 if (err < 0)
37 break;
39 } 38 }
40 rc = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, name, value, len, 0); 39 return err;
40}
41 41
42 kfree(name); 42/* ---- Initial Security Label(s) Attachment ----------- */
43 kfree(value); 43int jffs2_init_security(struct inode *inode, struct inode *dir,
44 return rc; 44 const struct qstr *qstr)
45{
46 return security_inode_init_security(inode, dir, qstr,
47 &jffs2_initxattrs, NULL);
45} 48}
46 49
47/* ---- XATTR Handler for "security.*" ----------------- */ 50/* ---- XATTR Handler for "security.*" ----------------- */
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 24838f1eeee5..e982509292f8 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -1091,38 +1091,37 @@ int jfs_removexattr(struct dentry *dentry, const char *name)
1091} 1091}
1092 1092
1093#ifdef CONFIG_JFS_SECURITY 1093#ifdef CONFIG_JFS_SECURITY
1094int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir, 1094int jfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
1095 const struct qstr *qstr) 1095 void *fs_info)
1096{ 1096{
1097 int rc; 1097 const struct xattr *xattr;
1098 size_t len; 1098 tid_t *tid = fs_info;
1099 void *value;
1100 char *suffix;
1101 char *name; 1099 char *name;
1102 1100 int err = 0;
1103 rc = security_inode_init_security(inode, dir, qstr, &suffix, &value, 1101
1104 &len); 1102 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
1105 if (rc) { 1103 name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
1106 if (rc == -EOPNOTSUPP) 1104 strlen(xattr->name) + 1, GFP_NOFS);
1107 return 0; 1105 if (!name) {
1108 return rc; 1106 err = -ENOMEM;
1109 } 1107 break;
1110 name = kmalloc(XATTR_SECURITY_PREFIX_LEN + 1 + strlen(suffix), 1108 }
1111 GFP_NOFS); 1109 strcpy(name, XATTR_SECURITY_PREFIX);
1112 if (!name) { 1110 strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
1113 rc = -ENOMEM; 1111
1114 goto kmalloc_failed; 1112 err = __jfs_setxattr(*tid, inode, name,
1113 xattr->value, xattr->value_len, 0);
1114 kfree(name);
1115 if (err < 0)
1116 break;
1115 } 1117 }
1116 strcpy(name, XATTR_SECURITY_PREFIX); 1118 return err;
1117 strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); 1119}
1118
1119 rc = __jfs_setxattr(tid, inode, name, value, len, 0);
1120
1121 kfree(name);
1122kmalloc_failed:
1123 kfree(suffix);
1124 kfree(value);
1125 1120
1126 return rc; 1121int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir,
1122 const struct qstr *qstr)
1123{
1124 return security_inode_init_security(inode, dir, qstr,
1125 &jfs_initxattrs, &tid);
1127} 1126}
1128#endif 1127#endif
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 81ecf9c0bf0a..194fb22ef79d 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -7185,20 +7185,9 @@ int ocfs2_init_security_and_acl(struct inode *dir,
7185{ 7185{
7186 int ret = 0; 7186 int ret = 0;
7187 struct buffer_head *dir_bh = NULL; 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 if (!ret) { 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 mlog_errno(ret); 7191 mlog_errno(ret);
7203 goto leave; 7192 goto leave;
7204 } 7193 }
@@ -7255,6 +7244,22 @@ static int ocfs2_xattr_security_set(struct dentry *dentry, const char *name,
7255 name, value, size, flags); 7244 name, value, size, flags);
7256} 7245}
7257 7246
7247int ocfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
7248 void *fs_info)
7249{
7250 const struct xattr *xattr;
7251 int err = 0;
7252
7253 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
7254 err = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
7255 xattr->name, xattr->value,
7256 xattr->value_len, XATTR_CREATE);
7257 if (err)
7258 break;
7259 }
7260 return err;
7261}
7262
7258int ocfs2_init_security_get(struct inode *inode, 7263int ocfs2_init_security_get(struct inode *inode,
7259 struct inode *dir, 7264 struct inode *dir,
7260 const struct qstr *qstr, 7265 const struct qstr *qstr,
@@ -7263,8 +7268,13 @@ int ocfs2_init_security_get(struct inode *inode,
7263 /* check whether ocfs2 support feature xattr */ 7268 /* check whether ocfs2 support feature xattr */
7264 if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb))) 7269 if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb)))
7265 return -EOPNOTSUPP; 7270 return -EOPNOTSUPP;
7266 return security_inode_init_security(inode, dir, qstr, &si->name, 7271 if (si)
7267 &si->value, &si->value_len); 7272 return security_old_inode_init_security(inode, dir, qstr,
7273 &si->name, &si->value,
7274 &si->value_len);
7275
7276 return security_inode_init_security(inode, dir, qstr,
7277 &ocfs2_initxattrs, NULL);
7268} 7278}
7269 7279
7270int ocfs2_init_security_set(handle_t *handle, 7280int ocfs2_init_security_set(handle_t *handle,
diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c
index ef66c18a9332..534668fa41be 100644
--- a/fs/reiserfs/xattr_security.c
+++ b/fs/reiserfs/xattr_security.c
@@ -66,8 +66,8 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode,
66 if (IS_PRIVATE(dir)) 66 if (IS_PRIVATE(dir))
67 return 0; 67 return 0;
68 68
69 error = security_inode_init_security(inode, dir, qstr, &sec->name, 69 error = security_old_inode_init_security(inode, dir, qstr, &sec->name,
70 &sec->value, &sec->length); 70 &sec->value, &sec->length);
71 if (error) { 71 if (error) {
72 if (error == -EOPNOTSUPP) 72 if (error == -EOPNOTSUPP)
73 error = 0; 73 error = 0;
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index d44d92cd12b1..27a3658b830f 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -93,37 +93,38 @@ xfs_mark_inode_dirty(
93 mark_inode_dirty(inode); 93 mark_inode_dirty(inode);
94} 94}
95 95
96
97int 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 * Hook in SELinux. This is not quite correct yet, what we really need 114 * Hook in SELinux. This is not quite correct yet, what we really need
98 * here (as we do for default ACLs) is a mechanism by which creation of 115 * here (as we do for default ACLs) is a mechanism by which creation of
99 * these attrs can be journalled at inode creation time (along with the 116 * these attrs can be journalled at inode creation time (along with the
100 * inode, of course, such that log replay can't cause these to be lost). 117 * inode, of course, such that log replay can't cause these to be lost).
101 */ 118 */
119
102STATIC int 120STATIC int
103xfs_init_security( 121xfs_init_security(
104 struct inode *inode, 122 struct inode *inode,
105 struct inode *dir, 123 struct inode *dir,
106 const struct qstr *qstr) 124 const struct qstr *qstr)
107{ 125{
108 struct xfs_inode *ip = XFS_I(inode); 126 return security_inode_init_security(inode, dir, qstr,
109 size_t length; 127 &xfs_initxattrs, NULL);
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;
127} 128}
128 129
129static void 130static void