diff options
Diffstat (limited to 'fs/xattr.c')
-rw-r--r-- | fs/xattr.c | 77 |
1 files changed, 52 insertions, 25 deletions
diff --git a/fs/xattr.c b/fs/xattr.c index 6645b7313b33..3acab1615460 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -105,6 +105,33 @@ out: | |||
105 | EXPORT_SYMBOL_GPL(vfs_setxattr); | 105 | EXPORT_SYMBOL_GPL(vfs_setxattr); |
106 | 106 | ||
107 | ssize_t | 107 | ssize_t |
108 | xattr_getsecurity(struct inode *inode, const char *name, void *value, | ||
109 | size_t size) | ||
110 | { | ||
111 | void *buffer = NULL; | ||
112 | ssize_t len; | ||
113 | |||
114 | if (!value || !size) { | ||
115 | len = security_inode_getsecurity(inode, name, &buffer, false); | ||
116 | goto out_noalloc; | ||
117 | } | ||
118 | |||
119 | len = security_inode_getsecurity(inode, name, &buffer, true); | ||
120 | if (len < 0) | ||
121 | return len; | ||
122 | if (size < len) { | ||
123 | len = -ERANGE; | ||
124 | goto out; | ||
125 | } | ||
126 | memcpy(value, buffer, len); | ||
127 | out: | ||
128 | security_release_secctx(buffer, len); | ||
129 | out_noalloc: | ||
130 | return len; | ||
131 | } | ||
132 | EXPORT_SYMBOL_GPL(xattr_getsecurity); | ||
133 | |||
134 | ssize_t | ||
108 | vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size) | 135 | vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size) |
109 | { | 136 | { |
110 | struct inode *inode = dentry->d_inode; | 137 | struct inode *inode = dentry->d_inode; |
@@ -118,23 +145,23 @@ vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size) | |||
118 | if (error) | 145 | if (error) |
119 | return error; | 146 | return error; |
120 | 147 | ||
121 | if (inode->i_op->getxattr) | ||
122 | error = inode->i_op->getxattr(dentry, name, value, size); | ||
123 | else | ||
124 | error = -EOPNOTSUPP; | ||
125 | |||
126 | if (!strncmp(name, XATTR_SECURITY_PREFIX, | 148 | if (!strncmp(name, XATTR_SECURITY_PREFIX, |
127 | XATTR_SECURITY_PREFIX_LEN)) { | 149 | XATTR_SECURITY_PREFIX_LEN)) { |
128 | const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; | 150 | const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; |
129 | int ret = security_inode_getsecurity(inode, suffix, value, | 151 | int ret = xattr_getsecurity(inode, suffix, value, size); |
130 | size, error); | ||
131 | /* | 152 | /* |
132 | * Only overwrite the return value if a security module | 153 | * Only overwrite the return value if a security module |
133 | * is actually active. | 154 | * is actually active. |
134 | */ | 155 | */ |
135 | if (ret != -EOPNOTSUPP) | 156 | if (ret == -EOPNOTSUPP) |
136 | error = ret; | 157 | goto nolsm; |
158 | return ret; | ||
137 | } | 159 | } |
160 | nolsm: | ||
161 | if (inode->i_op->getxattr) | ||
162 | error = inode->i_op->getxattr(dentry, name, value, size); | ||
163 | else | ||
164 | error = -EOPNOTSUPP; | ||
138 | 165 | ||
139 | return error; | 166 | return error; |
140 | } | 167 | } |
@@ -235,8 +262,8 @@ sys_setxattr(char __user *path, char __user *name, void __user *value, | |||
235 | error = user_path_walk(path, &nd); | 262 | error = user_path_walk(path, &nd); |
236 | if (error) | 263 | if (error) |
237 | return error; | 264 | return error; |
238 | error = setxattr(nd.dentry, name, value, size, flags); | 265 | error = setxattr(nd.path.dentry, name, value, size, flags); |
239 | path_release(&nd); | 266 | path_put(&nd.path); |
240 | return error; | 267 | return error; |
241 | } | 268 | } |
242 | 269 | ||
@@ -250,8 +277,8 @@ sys_lsetxattr(char __user *path, char __user *name, void __user *value, | |||
250 | error = user_path_walk_link(path, &nd); | 277 | error = user_path_walk_link(path, &nd); |
251 | if (error) | 278 | if (error) |
252 | return error; | 279 | return error; |
253 | error = setxattr(nd.dentry, name, value, size, flags); | 280 | error = setxattr(nd.path.dentry, name, value, size, flags); |
254 | path_release(&nd); | 281 | path_put(&nd.path); |
255 | return error; | 282 | return error; |
256 | } | 283 | } |
257 | 284 | ||
@@ -320,8 +347,8 @@ sys_getxattr(char __user *path, char __user *name, void __user *value, | |||
320 | error = user_path_walk(path, &nd); | 347 | error = user_path_walk(path, &nd); |
321 | if (error) | 348 | if (error) |
322 | return error; | 349 | return error; |
323 | error = getxattr(nd.dentry, name, value, size); | 350 | error = getxattr(nd.path.dentry, name, value, size); |
324 | path_release(&nd); | 351 | path_put(&nd.path); |
325 | return error; | 352 | return error; |
326 | } | 353 | } |
327 | 354 | ||
@@ -335,8 +362,8 @@ sys_lgetxattr(char __user *path, char __user *name, void __user *value, | |||
335 | error = user_path_walk_link(path, &nd); | 362 | error = user_path_walk_link(path, &nd); |
336 | if (error) | 363 | if (error) |
337 | return error; | 364 | return error; |
338 | error = getxattr(nd.dentry, name, value, size); | 365 | error = getxattr(nd.path.dentry, name, value, size); |
339 | path_release(&nd); | 366 | path_put(&nd.path); |
340 | return error; | 367 | return error; |
341 | } | 368 | } |
342 | 369 | ||
@@ -394,8 +421,8 @@ sys_listxattr(char __user *path, char __user *list, size_t size) | |||
394 | error = user_path_walk(path, &nd); | 421 | error = user_path_walk(path, &nd); |
395 | if (error) | 422 | if (error) |
396 | return error; | 423 | return error; |
397 | error = listxattr(nd.dentry, list, size); | 424 | error = listxattr(nd.path.dentry, list, size); |
398 | path_release(&nd); | 425 | path_put(&nd.path); |
399 | return error; | 426 | return error; |
400 | } | 427 | } |
401 | 428 | ||
@@ -408,8 +435,8 @@ sys_llistxattr(char __user *path, char __user *list, size_t size) | |||
408 | error = user_path_walk_link(path, &nd); | 435 | error = user_path_walk_link(path, &nd); |
409 | if (error) | 436 | if (error) |
410 | return error; | 437 | return error; |
411 | error = listxattr(nd.dentry, list, size); | 438 | error = listxattr(nd.path.dentry, list, size); |
412 | path_release(&nd); | 439 | path_put(&nd.path); |
413 | return error; | 440 | return error; |
414 | } | 441 | } |
415 | 442 | ||
@@ -455,8 +482,8 @@ sys_removexattr(char __user *path, char __user *name) | |||
455 | error = user_path_walk(path, &nd); | 482 | error = user_path_walk(path, &nd); |
456 | if (error) | 483 | if (error) |
457 | return error; | 484 | return error; |
458 | error = removexattr(nd.dentry, name); | 485 | error = removexattr(nd.path.dentry, name); |
459 | path_release(&nd); | 486 | path_put(&nd.path); |
460 | return error; | 487 | return error; |
461 | } | 488 | } |
462 | 489 | ||
@@ -469,8 +496,8 @@ sys_lremovexattr(char __user *path, char __user *name) | |||
469 | error = user_path_walk_link(path, &nd); | 496 | error = user_path_walk_link(path, &nd); |
470 | if (error) | 497 | if (error) |
471 | return error; | 498 | return error; |
472 | error = removexattr(nd.dentry, name); | 499 | error = removexattr(nd.path.dentry, name); |
473 | path_release(&nd); | 500 | path_put(&nd.path); |
474 | return error; | 501 | return error; |
475 | } | 502 | } |
476 | 503 | ||