Commit 8ae8f1627f39bae505b90cade50cd8a911b8bda6

Authored by Jaegeuk Kim
1 parent 5deb82671a

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>

Showing 7 changed files with 100 additions and 21 deletions Side-by-side Diff

... ... @@ -51,4 +51,16 @@
51 51 Linux website <http://acl.bestbits.at/>.
52 52  
53 53 If you don't know what Access Control Lists are, say N
  54 +
  55 +config F2FS_FS_SECURITY
  56 + bool "F2FS Security Labels"
  57 + depends on F2FS_FS_XATTR
  58 + help
  59 + Security labels provide an access control facility to support Linux
  60 + Security Models (LSMs) accepted by AppArmor, SELinux, Smack and TOMOYO
  61 + Linux. This option enables an extended attribute handler for file
  62 + security labels in the f2fs filesystem, so that it requires enabling
  63 + the extended attribute support in advance.
  64 +
  65 + If you are not using a security module, say N.
... ... @@ -250,7 +250,7 @@
250 250 }
251 251 }
252 252  
253   - error = f2fs_setxattr(inode, name_index, "", value, size);
  253 + error = f2fs_setxattr(inode, name_index, "", value, size, NULL);
254 254  
255 255 kfree(value);
256 256 if (!error)
... ... @@ -13,6 +13,7 @@
13 13 #include "f2fs.h"
14 14 #include "node.h"
15 15 #include "acl.h"
  16 +#include "xattr.h"
16 17  
17 18 static unsigned long dir_blocks(struct inode *inode)
18 19 {
... ... @@ -331,6 +332,10 @@
331 332 }
332 333  
333 334 err = f2fs_init_acl(inode, dir);
  335 + if (err)
  336 + goto error;
  337 +
  338 + err = f2fs_init_security(inode, dir, name, page);
334 339 if (err)
335 340 goto error;
336 341  
... ... @@ -968,7 +968,7 @@
968 968 int truncate_inode_blocks(struct inode *, pgoff_t);
969 969 int remove_inode_page(struct inode *);
970 970 struct page *new_inode_page(struct inode *, const struct qstr *);
971   -struct page *new_node_page(struct dnode_of_data *, unsigned int);
  971 +struct page *new_node_page(struct dnode_of_data *, unsigned int, struct page *);
972 972 void ra_node_page(struct f2fs_sb_info *, nid_t);
973 973 struct page *get_node_page(struct f2fs_sb_info *, pgoff_t);
974 974 struct page *get_node_page_ra(struct page *, int);
... ... @@ -433,7 +433,7 @@
433 433 }
434 434  
435 435 dn->nid = nids[i];
436   - npage[i] = new_node_page(dn, noffset[i]);
  436 + npage[i] = new_node_page(dn, noffset[i], NULL);
437 437 if (IS_ERR(npage[i])) {
438 438 alloc_nid_failed(sbi, nids[i]);
439 439 err = PTR_ERR(npage[i]);
440 440  
... ... @@ -814,10 +814,11 @@
814 814 set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino);
815 815  
816 816 /* caller should f2fs_put_page(page, 1); */
817   - return new_node_page(&dn, 0);
  817 + return new_node_page(&dn, 0, NULL);
818 818 }
819 819  
820   -struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs)
  820 +struct page *new_node_page(struct dnode_of_data *dn,
  821 + unsigned int ofs, struct page *ipage)
821 822 {
822 823 struct f2fs_sb_info *sbi = F2FS_SB(dn->inode->i_sb);
823 824 struct address_space *mapping = sbi->node_inode->i_mapping;
... ... @@ -850,7 +851,10 @@
850 851 set_cold_node(dn->inode, page);
851 852  
852 853 dn->node_page = page;
853   - sync_inode_page(dn);
  854 + if (ipage)
  855 + update_inode(dn->inode, ipage);
  856 + else
  857 + sync_inode_page(dn);
854 858 set_page_dirty(page);
855 859 if (ofs == 0)
856 860 inc_valid_inode_count(sbi);
... ... @@ -20,6 +20,7 @@
20 20 */
21 21 #include <linux/rwsem.h>
22 22 #include <linux/f2fs_fs.h>
  23 +#include <linux/security.h>
23 24 #include "f2fs.h"
24 25 #include "xattr.h"
25 26  
... ... @@ -43,6 +44,10 @@
43 44 prefix = XATTR_TRUSTED_PREFIX;
44 45 prefix_len = XATTR_TRUSTED_PREFIX_LEN;
45 46 break;
  47 + case F2FS_XATTR_INDEX_SECURITY:
  48 + prefix = XATTR_SECURITY_PREFIX;
  49 + prefix_len = XATTR_SECURITY_PREFIX_LEN;
  50 + break;
46 51 default:
47 52 return -EINVAL;
48 53 }
... ... @@ -50,7 +55,7 @@
50 55 total_len = prefix_len + name_len + 1;
51 56 if (list && total_len <= list_size) {
52 57 memcpy(list, prefix, prefix_len);
53   - memcpy(list+prefix_len, name, name_len);
  58 + memcpy(list + prefix_len, name, name_len);
54 59 list[prefix_len + name_len] = '\0';
55 60 }
56 61 return total_len;
57 62  
... ... @@ -70,13 +75,14 @@
70 75 if (!capable(CAP_SYS_ADMIN))
71 76 return -EPERM;
72 77 break;
  78 + case F2FS_XATTR_INDEX_SECURITY:
  79 + break;
73 80 default:
74 81 return -EINVAL;
75 82 }
76 83 if (strcmp(name, "") == 0)
77 84 return -EINVAL;
78   - return f2fs_getxattr(dentry->d_inode, type, name,
79   - buffer, size);
  85 + return f2fs_getxattr(dentry->d_inode, type, name, buffer, size);
80 86 }
81 87  
82 88 static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name,
83 89  
... ... @@ -93,13 +99,15 @@
93 99 if (!capable(CAP_SYS_ADMIN))
94 100 return -EPERM;
95 101 break;
  102 + case F2FS_XATTR_INDEX_SECURITY:
  103 + break;
96 104 default:
97 105 return -EINVAL;
98 106 }
99 107 if (strcmp(name, "") == 0)
100 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  
105 113 static size_t f2fs_xattr_advise_list(struct dentry *dentry, char *list,
... ... @@ -145,6 +153,31 @@
145 153 return 0;
146 154 }
147 155  
  156 +#ifdef CONFIG_F2FS_FS_SECURITY
  157 +static 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 +
  173 +int 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 +
148 181 const struct xattr_handler f2fs_xattr_user_handler = {
149 182 .prefix = XATTR_USER_PREFIX,
150 183 .flags = F2FS_XATTR_INDEX_USER,
... ... @@ -169,6 +202,14 @@
169 202 .set = f2fs_xattr_advise_set,
170 203 };
171 204  
  205 +const 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 +
172 213 static const struct xattr_handler *f2fs_xattr_handler_map[] = {
173 214 [F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler,
174 215 #ifdef CONFIG_F2FS_FS_POSIX_ACL
... ... @@ -176,6 +217,9 @@
176 217 [F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &f2fs_xattr_acl_default_handler,
177 218 #endif
178 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 223 [F2FS_XATTR_INDEX_ADVISE] = &f2fs_xattr_advise_handler,
180 224 };
181 225  
... ... @@ -186,6 +230,9 @@
186 230 &f2fs_xattr_acl_default_handler,
187 231 #endif
188 232 &f2fs_xattr_trusted_handler,
  233 +#ifdef CONFIG_F2FS_FS_SECURITY
  234 + &f2fs_xattr_security_handler,
  235 +#endif
189 236 &f2fs_xattr_advise_handler,
190 237 NULL,
191 238 };
... ... @@ -300,7 +347,7 @@
300 347 }
301 348  
302 349 int 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 352 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
306 353 struct f2fs_inode_info *fi = F2FS_I(inode);
... ... @@ -339,7 +386,7 @@
339 386 set_new_dnode(&dn, inode, NULL, NULL, fi->i_xattr_nid);
340 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 390 if (IS_ERR(page)) {
344 391 alloc_nid_failed(sbi, fi->i_xattr_nid);
345 392 fi->i_xattr_nid = 0;
... ... @@ -439,7 +486,10 @@
439 486 inode->i_ctime = CURRENT_TIME;
440 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 493 mutex_unlock_op(sbi, ilock);
444 494  
445 495 return 0;
... ... @@ -112,21 +112,19 @@
112 112 extern const struct xattr_handler f2fs_xattr_acl_access_handler;
113 113 extern const struct xattr_handler f2fs_xattr_acl_default_handler;
114 114 extern const struct xattr_handler f2fs_xattr_advise_handler;
  115 +extern const struct xattr_handler f2fs_xattr_security_handler;
115 116  
116 117 extern const struct xattr_handler *f2fs_xattr_handlers[];
117 118  
118   -extern int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
119   - const void *value, size_t value_len);
120   -extern int f2fs_getxattr(struct inode *inode, int name_index, const char *name,
121   - void *buffer, size_t buffer_size);
122   -extern ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer,
123   - size_t buffer_size);
124   -
  119 +extern int f2fs_setxattr(struct inode *, int, const char *,
  120 + const void *, size_t, struct page *);
  121 +extern int f2fs_getxattr(struct inode *, int, const char *, void *, size_t);
  122 +extern ssize_t f2fs_listxattr(struct dentry *, char *, size_t);
125 123 #else
126 124  
127 125 #define f2fs_xattr_handlers NULL
128 126 static inline int f2fs_setxattr(struct inode *inode, int name_index,
129   - const char *name, const void *value, size_t value_len)
  127 + const char *name, const void *value, size_t value_len)
130 128 {
131 129 return -EOPNOTSUPP;
132 130 }
... ... @@ -142,5 +140,15 @@
142 140 }
143 141 #endif
144 142  
  143 +#ifdef CONFIG_F2FS_FS_SECURITY
  144 +extern int f2fs_init_security(struct inode *, struct inode *,
  145 + const struct qstr *, struct page *);
  146 +#else
  147 +static inline int f2fs_init_security(struct inode *inode, struct inode *dir,
  148 + const struct qstr *qstr, struct page *ipage)
  149 +{
  150 + return 0;
  151 +}
  152 +#endif
145 153 #endif /* __F2FS_XATTR_H__ */