4 Extended attribute handling.
6 Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
7 Copyright (C) 2001 SGI - Silicon Graphics, Inc <linux-xfs@oss.sgi.com>
10 #include <linux/slab.h>
11 #include <linux/smp_lock.h>
12 #include <linux/file.h>
13 #include <linux/xattr.h>
14 #include <linux/namei.h>
15 #include <linux/security.h>
16 #include <asm/uaccess.h>
19 * Extended attribute memory allocation wrappers, originally
20 * based on the Intermezzo PRESTO_ALLOC/PRESTO_FREE macros.
21 * Values larger than a page are uncommon - extended attributes
22 * are supposed to be small chunks of metadata, and it is quite
23 * unusual to have very many extended attributes, so lists tend
24 * to be quite short as well. The 64K upper limit is derived
25 * from the extended attribute size limit used by XFS.
26 * Intentionally allow zero @size for value/list size requests.
29 xattr_alloc(size_t size
, size_t limit
)
34 return ERR_PTR(-E2BIG
);
36 if (!size
) /* size request, no buffer is needed */
39 ptr
= kmalloc((unsigned long) size
, GFP_KERNEL
);
41 return ERR_PTR(-ENOMEM
);
46 xattr_free(void *ptr
, size_t size
)
48 if (size
) /* for a size request, no buffer was needed */
53 * Extended attribute SET operations
56 setxattr(struct dentry
*d
, char __user
*name
, void __user
*value
,
57 size_t size
, int flags
)
61 char kname
[XATTR_NAME_MAX
+ 1];
63 if (flags
& ~(XATTR_CREATE
|XATTR_REPLACE
))
66 error
= strncpy_from_user(kname
, name
, sizeof(kname
));
67 if (error
== 0 || error
== sizeof(kname
))
72 kvalue
= xattr_alloc(size
, XATTR_SIZE_MAX
);
74 return PTR_ERR(kvalue
);
76 if (size
> 0 && copy_from_user(kvalue
, value
, size
)) {
77 xattr_free(kvalue
, size
);
82 if (d
->d_inode
->i_op
&& d
->d_inode
->i_op
->setxattr
) {
83 down(&d
->d_inode
->i_sem
);
84 error
= security_inode_setxattr(d
, kname
, kvalue
, size
, flags
);
87 error
= d
->d_inode
->i_op
->setxattr(d
, kname
, kvalue
, size
, flags
);
89 security_inode_post_setxattr(d
, kname
, kvalue
, size
, flags
);
91 up(&d
->d_inode
->i_sem
);
93 xattr_free(kvalue
, size
);
98 sys_setxattr(char __user
*path
, char __user
*name
, void __user
*value
,
99 size_t size
, int flags
)
104 error
= user_path_walk(path
, &nd
);
107 error
= setxattr(nd
.dentry
, name
, value
, size
, flags
);
113 sys_lsetxattr(char __user
*path
, char __user
*name
, void __user
*value
,
114 size_t size
, int flags
)
119 error
= user_path_walk_link(path
, &nd
);
122 error
= setxattr(nd
.dentry
, name
, value
, size
, flags
);
128 sys_fsetxattr(int fd
, char __user
*name
, void __user
*value
,
129 size_t size
, int flags
)
137 error
= setxattr(f
->f_dentry
, name
, value
, size
, flags
);
143 * Extended attribute GET operations
146 getxattr(struct dentry
*d
, char __user
*name
, void __user
*value
, size_t size
)
150 char kname
[XATTR_NAME_MAX
+ 1];
152 error
= strncpy_from_user(kname
, name
, sizeof(kname
));
153 if (error
== 0 || error
== sizeof(kname
))
158 kvalue
= xattr_alloc(size
, XATTR_SIZE_MAX
);
160 return PTR_ERR(kvalue
);
163 if (d
->d_inode
->i_op
&& d
->d_inode
->i_op
->getxattr
) {
164 error
= security_inode_getxattr(d
, kname
);
167 error
= d
->d_inode
->i_op
->getxattr(d
, kname
, kvalue
, size
);
170 if (kvalue
&& error
> 0)
171 if (copy_to_user(value
, kvalue
, error
))
174 xattr_free(kvalue
, size
);
179 sys_getxattr(char __user
*path
, char __user
*name
, void __user
*value
,
185 error
= user_path_walk(path
, &nd
);
188 error
= getxattr(nd
.dentry
, name
, value
, size
);
194 sys_lgetxattr(char __user
*path
, char __user
*name
, void __user
*value
,
200 error
= user_path_walk_link(path
, &nd
);
203 error
= getxattr(nd
.dentry
, name
, value
, size
);
209 sys_fgetxattr(int fd
, char __user
*name
, void __user
*value
, size_t size
)
212 ssize_t error
= -EBADF
;
217 error
= getxattr(f
->f_dentry
, name
, value
, size
);
223 * Extended attribute LIST operations
226 listxattr(struct dentry
*d
, char __user
*list
, size_t size
)
231 klist
= (char *)xattr_alloc(size
, XATTR_LIST_MAX
);
233 return PTR_ERR(klist
);
236 if (d
->d_inode
->i_op
&& d
->d_inode
->i_op
->listxattr
) {
237 error
= security_inode_listxattr(d
);
240 error
= d
->d_inode
->i_op
->listxattr(d
, klist
, size
);
243 if (klist
&& error
> 0)
244 if (copy_to_user(list
, klist
, error
))
247 xattr_free(klist
, size
);
252 sys_listxattr(char __user
*path
, char __user
*list
, size_t size
)
257 error
= user_path_walk(path
, &nd
);
260 error
= listxattr(nd
.dentry
, list
, size
);
266 sys_llistxattr(char __user
*path
, char __user
*list
, size_t size
)
271 error
= user_path_walk_link(path
, &nd
);
274 error
= listxattr(nd
.dentry
, list
, size
);
280 sys_flistxattr(int fd
, char __user
*list
, size_t size
)
283 ssize_t error
= -EBADF
;
288 error
= listxattr(f
->f_dentry
, list
, size
);
294 * Extended attribute REMOVE operations
297 removexattr(struct dentry
*d
, char __user
*name
)
300 char kname
[XATTR_NAME_MAX
+ 1];
302 error
= strncpy_from_user(kname
, name
, sizeof(kname
));
303 if (error
== 0 || error
== sizeof(kname
))
309 if (d
->d_inode
->i_op
&& d
->d_inode
->i_op
->removexattr
) {
310 error
= security_inode_removexattr(d
, kname
);
313 down(&d
->d_inode
->i_sem
);
314 error
= d
->d_inode
->i_op
->removexattr(d
, kname
);
315 up(&d
->d_inode
->i_sem
);
322 sys_removexattr(char __user
*path
, char __user
*name
)
327 error
= user_path_walk(path
, &nd
);
330 error
= removexattr(nd
.dentry
, name
);
336 sys_lremovexattr(char __user
*path
, char __user
*name
)
341 error
= user_path_walk_link(path
, &nd
);
344 error
= removexattr(nd
.dentry
, name
);
350 sys_fremovexattr(int fd
, char __user
*name
)
358 error
= removexattr(f
->f_dentry
, name
);