aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xattr.c')
-rw-r--r--fs/xattr.c77
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:
105EXPORT_SYMBOL_GPL(vfs_setxattr); 105EXPORT_SYMBOL_GPL(vfs_setxattr);
106 106
107ssize_t 107ssize_t
108xattr_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);
127out:
128 security_release_secctx(buffer, len);
129out_noalloc:
130 return len;
131}
132EXPORT_SYMBOL_GPL(xattr_getsecurity);
133
134ssize_t
108vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size) 135vfs_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 }
160nolsm:
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