aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/xattr.c
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2013-06-03 06:46:19 -0400
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2013-06-11 03:01:03 -0400
commit8ae8f1627f39bae505b90cade50cd8a911b8bda6 (patch)
tree959ca29760d6e751bbf5913cc0339b61a23a1a3a /fs/f2fs/xattr.c
parent5deb82671ae344b28b4e744020afcbc76df1779b (diff)
f2fs: support xattr security labels
This patch adds the support of security labels for f2fs, which will be used by Linus Security Models (LSMs). Quote from http://en.wikipedia.org/wiki/Linux_Security_Modules: "Linux Security Modules (LSM) is a framework that allows the Linux kernel to support a variety of computer security models while avoiding favoritism toward any single security implementation. The framework is licensed under the terms of the GNU General Public License and is standard part of the Linux kernel since Linux 2.6. AppArmor, SELinux, Smack and TOMOYO Linux are the currently accepted modules in the official kernel.". Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs/f2fs/xattr.c')
-rw-r--r--fs/f2fs/xattr.c64
1 files changed, 57 insertions, 7 deletions
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index ae61f359554f..3ab07ecd86ca 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -20,6 +20,7 @@
20 */ 20 */
21#include <linux/rwsem.h> 21#include <linux/rwsem.h>
22#include <linux/f2fs_fs.h> 22#include <linux/f2fs_fs.h>
23#include <linux/security.h>
23#include "f2fs.h" 24#include "f2fs.h"
24#include "xattr.h" 25#include "xattr.h"
25 26
@@ -43,6 +44,10 @@ static size_t f2fs_xattr_generic_list(struct dentry *dentry, char *list,
43 prefix = XATTR_TRUSTED_PREFIX; 44 prefix = XATTR_TRUSTED_PREFIX;
44 prefix_len = XATTR_TRUSTED_PREFIX_LEN; 45 prefix_len = XATTR_TRUSTED_PREFIX_LEN;
45 break; 46 break;
47 case F2FS_XATTR_INDEX_SECURITY:
48 prefix = XATTR_SECURITY_PREFIX;
49 prefix_len = XATTR_SECURITY_PREFIX_LEN;
50 break;
46 default: 51 default:
47 return -EINVAL; 52 return -EINVAL;
48 } 53 }
@@ -50,7 +55,7 @@ static size_t f2fs_xattr_generic_list(struct dentry *dentry, char *list,
50 total_len = prefix_len + name_len + 1; 55 total_len = prefix_len + name_len + 1;
51 if (list && total_len <= list_size) { 56 if (list && total_len <= list_size) {
52 memcpy(list, prefix, prefix_len); 57 memcpy(list, prefix, prefix_len);
53 memcpy(list+prefix_len, name, name_len); 58 memcpy(list + prefix_len, name, name_len);
54 list[prefix_len + name_len] = '\0'; 59 list[prefix_len + name_len] = '\0';
55 } 60 }
56 return total_len; 61 return total_len;
@@ -70,13 +75,14 @@ static int f2fs_xattr_generic_get(struct dentry *dentry, const char *name,
70 if (!capable(CAP_SYS_ADMIN)) 75 if (!capable(CAP_SYS_ADMIN))
71 return -EPERM; 76 return -EPERM;
72 break; 77 break;
78 case F2FS_XATTR_INDEX_SECURITY:
79 break;
73 default: 80 default:
74 return -EINVAL; 81 return -EINVAL;
75 } 82 }
76 if (strcmp(name, "") == 0) 83 if (strcmp(name, "") == 0)
77 return -EINVAL; 84 return -EINVAL;
78 return f2fs_getxattr(dentry->d_inode, type, name, 85 return f2fs_getxattr(dentry->d_inode, type, name, buffer, size);
79 buffer, size);
80} 86}
81 87
82static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name, 88static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name,
@@ -93,13 +99,15 @@ static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name,
93 if (!capable(CAP_SYS_ADMIN)) 99 if (!capable(CAP_SYS_ADMIN))
94 return -EPERM; 100 return -EPERM;
95 break; 101 break;
102 case F2FS_XATTR_INDEX_SECURITY:
103 break;
96 default: 104 default:
97 return -EINVAL; 105 return -EINVAL;
98 } 106 }
99 if (strcmp(name, "") == 0) 107 if (strcmp(name, "") == 0)
100 return -EINVAL; 108 return -EINVAL;
101 109
102 return f2fs_setxattr(dentry->d_inode, type, name, value, size); 110 return f2fs_setxattr(dentry->d_inode, type, name, value, size, NULL);
103} 111}
104 112
105static size_t f2fs_xattr_advise_list(struct dentry *dentry, char *list, 113static size_t f2fs_xattr_advise_list(struct dentry *dentry, char *list,
@@ -145,6 +153,31 @@ static int f2fs_xattr_advise_set(struct dentry *dentry, const char *name,
145 return 0; 153 return 0;
146} 154}
147 155
156#ifdef CONFIG_F2FS_FS_SECURITY
157static int f2fs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
158 void *page)
159{
160 const struct xattr *xattr;
161 int err = 0;
162
163 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
164 err = f2fs_setxattr(inode, F2FS_XATTR_INDEX_SECURITY,
165 xattr->name, xattr->value,
166 xattr->value_len, (struct page *)page);
167 if (err < 0)
168 break;
169 }
170 return err;
171}
172
173int f2fs_init_security(struct inode *inode, struct inode *dir,
174 const struct qstr *qstr, struct page *ipage)
175{
176 return security_inode_init_security(inode, dir, qstr,
177 &f2fs_initxattrs, ipage);
178}
179#endif
180
148const struct xattr_handler f2fs_xattr_user_handler = { 181const struct xattr_handler f2fs_xattr_user_handler = {
149 .prefix = XATTR_USER_PREFIX, 182 .prefix = XATTR_USER_PREFIX,
150 .flags = F2FS_XATTR_INDEX_USER, 183 .flags = F2FS_XATTR_INDEX_USER,
@@ -169,6 +202,14 @@ const struct xattr_handler f2fs_xattr_advise_handler = {
169 .set = f2fs_xattr_advise_set, 202 .set = f2fs_xattr_advise_set,
170}; 203};
171 204
205const struct xattr_handler f2fs_xattr_security_handler = {
206 .prefix = XATTR_SECURITY_PREFIX,
207 .flags = F2FS_XATTR_INDEX_SECURITY,
208 .list = f2fs_xattr_generic_list,
209 .get = f2fs_xattr_generic_get,
210 .set = f2fs_xattr_generic_set,
211};
212
172static const struct xattr_handler *f2fs_xattr_handler_map[] = { 213static const struct xattr_handler *f2fs_xattr_handler_map[] = {
173 [F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler, 214 [F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler,
174#ifdef CONFIG_F2FS_FS_POSIX_ACL 215#ifdef CONFIG_F2FS_FS_POSIX_ACL
@@ -176,6 +217,9 @@ static const struct xattr_handler *f2fs_xattr_handler_map[] = {
176 [F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &f2fs_xattr_acl_default_handler, 217 [F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &f2fs_xattr_acl_default_handler,
177#endif 218#endif
178 [F2FS_XATTR_INDEX_TRUSTED] = &f2fs_xattr_trusted_handler, 219 [F2FS_XATTR_INDEX_TRUSTED] = &f2fs_xattr_trusted_handler,
220#ifdef CONFIG_F2FS_FS_SECURITY
221 [F2FS_XATTR_INDEX_SECURITY] = &f2fs_xattr_security_handler,
222#endif
179 [F2FS_XATTR_INDEX_ADVISE] = &f2fs_xattr_advise_handler, 223 [F2FS_XATTR_INDEX_ADVISE] = &f2fs_xattr_advise_handler,
180}; 224};
181 225
@@ -186,6 +230,9 @@ const struct xattr_handler *f2fs_xattr_handlers[] = {
186 &f2fs_xattr_acl_default_handler, 230 &f2fs_xattr_acl_default_handler,
187#endif 231#endif
188 &f2fs_xattr_trusted_handler, 232 &f2fs_xattr_trusted_handler,
233#ifdef CONFIG_F2FS_FS_SECURITY
234 &f2fs_xattr_security_handler,
235#endif
189 &f2fs_xattr_advise_handler, 236 &f2fs_xattr_advise_handler,
190 NULL, 237 NULL,
191}; 238};
@@ -300,7 +347,7 @@ cleanup:
300} 347}
301 348
302int f2fs_setxattr(struct inode *inode, int name_index, const char *name, 349int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
303 const void *value, size_t value_len) 350 const void *value, size_t value_len, struct page *ipage)
304{ 351{
305 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 352 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
306 struct f2fs_inode_info *fi = F2FS_I(inode); 353 struct f2fs_inode_info *fi = F2FS_I(inode);
@@ -339,7 +386,7 @@ int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
339 set_new_dnode(&dn, inode, NULL, NULL, fi->i_xattr_nid); 386 set_new_dnode(&dn, inode, NULL, NULL, fi->i_xattr_nid);
340 mark_inode_dirty(inode); 387 mark_inode_dirty(inode);
341 388
342 page = new_node_page(&dn, XATTR_NODE_OFFSET); 389 page = new_node_page(&dn, XATTR_NODE_OFFSET, ipage);
343 if (IS_ERR(page)) { 390 if (IS_ERR(page)) {
344 alloc_nid_failed(sbi, fi->i_xattr_nid); 391 alloc_nid_failed(sbi, fi->i_xattr_nid);
345 fi->i_xattr_nid = 0; 392 fi->i_xattr_nid = 0;
@@ -439,7 +486,10 @@ int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
439 inode->i_ctime = CURRENT_TIME; 486 inode->i_ctime = CURRENT_TIME;
440 clear_inode_flag(fi, FI_ACL_MODE); 487 clear_inode_flag(fi, FI_ACL_MODE);
441 } 488 }
442 update_inode_page(inode); 489 if (ipage)
490 update_inode(inode, ipage);
491 else
492 update_inode_page(inode);
443 mutex_unlock_op(sbi, ilock); 493 mutex_unlock_op(sbi, ilock);
444 494
445 return 0; 495 return 0;