xref: /openbmc/linux/fs/xattr.c (revision 1b1dcc1b)
1 /*
2   File: fs/xattr.c
3 
4   Extended attribute handling.
5 
6   Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
7   Copyright (C) 2001 SGI - Silicon Graphics, Inc <linux-xfs@oss.sgi.com>
8   Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
9  */
10 #include <linux/fs.h>
11 #include <linux/slab.h>
12 #include <linux/smp_lock.h>
13 #include <linux/file.h>
14 #include <linux/xattr.h>
15 #include <linux/namei.h>
16 #include <linux/security.h>
17 #include <linux/syscalls.h>
18 #include <linux/module.h>
19 #include <linux/fsnotify.h>
20 #include <asm/uaccess.h>
21 
22 /*
23  * Extended attribute SET operations
24  */
25 static long
26 setxattr(struct dentry *d, char __user *name, void __user *value,
27 	 size_t size, int flags)
28 {
29 	int error;
30 	void *kvalue = NULL;
31 	char kname[XATTR_NAME_MAX + 1];
32 
33 	if (flags & ~(XATTR_CREATE|XATTR_REPLACE))
34 		return -EINVAL;
35 
36 	error = strncpy_from_user(kname, name, sizeof(kname));
37 	if (error == 0 || error == sizeof(kname))
38 		error = -ERANGE;
39 	if (error < 0)
40 		return error;
41 
42 	if (size) {
43 		if (size > XATTR_SIZE_MAX)
44 			return -E2BIG;
45 		kvalue = kmalloc(size, GFP_KERNEL);
46 		if (!kvalue)
47 			return -ENOMEM;
48 		if (copy_from_user(kvalue, value, size)) {
49 			kfree(kvalue);
50 			return -EFAULT;
51 		}
52 	}
53 
54 	mutex_lock(&d->d_inode->i_mutex);
55 	error = security_inode_setxattr(d, kname, kvalue, size, flags);
56 	if (error)
57 		goto out;
58 	error = -EOPNOTSUPP;
59 	if (d->d_inode->i_op && d->d_inode->i_op->setxattr) {
60 		error = d->d_inode->i_op->setxattr(d, kname, kvalue,
61 						   size, flags);
62 		if (!error) {
63 			fsnotify_xattr(d);
64 			security_inode_post_setxattr(d, kname, kvalue,
65 						     size, flags);
66 		}
67 	} else if (!strncmp(kname, XATTR_SECURITY_PREFIX,
68 			    sizeof XATTR_SECURITY_PREFIX - 1)) {
69 		const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1;
70 		error = security_inode_setsecurity(d->d_inode, suffix, kvalue,
71 						   size, flags);
72 		if (!error)
73 			fsnotify_xattr(d);
74 	}
75 out:
76 	mutex_unlock(&d->d_inode->i_mutex);
77 	kfree(kvalue);
78 	return error;
79 }
80 
81 asmlinkage long
82 sys_setxattr(char __user *path, char __user *name, void __user *value,
83 	     size_t size, int flags)
84 {
85 	struct nameidata nd;
86 	int error;
87 
88 	error = user_path_walk(path, &nd);
89 	if (error)
90 		return error;
91 	error = setxattr(nd.dentry, name, value, size, flags);
92 	path_release(&nd);
93 	return error;
94 }
95 
96 asmlinkage long
97 sys_lsetxattr(char __user *path, char __user *name, void __user *value,
98 	      size_t size, int flags)
99 {
100 	struct nameidata nd;
101 	int error;
102 
103 	error = user_path_walk_link(path, &nd);
104 	if (error)
105 		return error;
106 	error = setxattr(nd.dentry, name, value, size, flags);
107 	path_release(&nd);
108 	return error;
109 }
110 
111 asmlinkage long
112 sys_fsetxattr(int fd, char __user *name, void __user *value,
113 	      size_t size, int flags)
114 {
115 	struct file *f;
116 	int error = -EBADF;
117 
118 	f = fget(fd);
119 	if (!f)
120 		return error;
121 	error = setxattr(f->f_dentry, name, value, size, flags);
122 	fput(f);
123 	return error;
124 }
125 
126 /*
127  * Extended attribute GET operations
128  */
129 static ssize_t
130 getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
131 {
132 	ssize_t error;
133 	void *kvalue = NULL;
134 	char kname[XATTR_NAME_MAX + 1];
135 
136 	error = strncpy_from_user(kname, name, sizeof(kname));
137 	if (error == 0 || error == sizeof(kname))
138 		error = -ERANGE;
139 	if (error < 0)
140 		return error;
141 
142 	if (size) {
143 		if (size > XATTR_SIZE_MAX)
144 			size = XATTR_SIZE_MAX;
145 		kvalue = kzalloc(size, GFP_KERNEL);
146 		if (!kvalue)
147 			return -ENOMEM;
148 	}
149 
150 	error = security_inode_getxattr(d, kname);
151 	if (error)
152 		goto out;
153 	error = -EOPNOTSUPP;
154 	if (d->d_inode->i_op && d->d_inode->i_op->getxattr)
155 		error = d->d_inode->i_op->getxattr(d, kname, kvalue, size);
156 
157 	if (!strncmp(kname, XATTR_SECURITY_PREFIX,
158 		     sizeof XATTR_SECURITY_PREFIX - 1)) {
159 		const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1;
160 		int rv = security_inode_getsecurity(d->d_inode, suffix, kvalue,
161 						    size, error);
162 		/* Security module active: overwrite error value */
163 		if (rv != -EOPNOTSUPP)
164 			error = rv;
165 	}
166 	if (error > 0) {
167 		if (size && copy_to_user(value, kvalue, error))
168 			error = -EFAULT;
169 	} else if (error == -ERANGE && size >= XATTR_SIZE_MAX) {
170 		/* The file system tried to returned a value bigger
171 		   than XATTR_SIZE_MAX bytes. Not possible. */
172 		error = -E2BIG;
173 	}
174 out:
175 	kfree(kvalue);
176 	return error;
177 }
178 
179 asmlinkage ssize_t
180 sys_getxattr(char __user *path, char __user *name, void __user *value,
181 	     size_t size)
182 {
183 	struct nameidata nd;
184 	ssize_t error;
185 
186 	error = user_path_walk(path, &nd);
187 	if (error)
188 		return error;
189 	error = getxattr(nd.dentry, name, value, size);
190 	path_release(&nd);
191 	return error;
192 }
193 
194 asmlinkage ssize_t
195 sys_lgetxattr(char __user *path, char __user *name, void __user *value,
196 	      size_t size)
197 {
198 	struct nameidata nd;
199 	ssize_t error;
200 
201 	error = user_path_walk_link(path, &nd);
202 	if (error)
203 		return error;
204 	error = getxattr(nd.dentry, name, value, size);
205 	path_release(&nd);
206 	return error;
207 }
208 
209 asmlinkage ssize_t
210 sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size)
211 {
212 	struct file *f;
213 	ssize_t error = -EBADF;
214 
215 	f = fget(fd);
216 	if (!f)
217 		return error;
218 	error = getxattr(f->f_dentry, name, value, size);
219 	fput(f);
220 	return error;
221 }
222 
223 /*
224  * Extended attribute LIST operations
225  */
226 static ssize_t
227 listxattr(struct dentry *d, char __user *list, size_t size)
228 {
229 	ssize_t error;
230 	char *klist = NULL;
231 
232 	if (size) {
233 		if (size > XATTR_LIST_MAX)
234 			size = XATTR_LIST_MAX;
235 		klist = kmalloc(size, GFP_KERNEL);
236 		if (!klist)
237 			return -ENOMEM;
238 	}
239 
240 	error = security_inode_listxattr(d);
241 	if (error)
242 		goto out;
243 	error = -EOPNOTSUPP;
244 	if (d->d_inode->i_op && d->d_inode->i_op->listxattr) {
245 		error = d->d_inode->i_op->listxattr(d, klist, size);
246 	} else {
247 		error = security_inode_listsecurity(d->d_inode, klist, size);
248 		if (size && error > size)
249 			error = -ERANGE;
250 	}
251 	if (error > 0) {
252 		if (size && copy_to_user(list, klist, error))
253 			error = -EFAULT;
254 	} else if (error == -ERANGE && size >= XATTR_LIST_MAX) {
255 		/* The file system tried to returned a list bigger
256 		   than XATTR_LIST_MAX bytes. Not possible. */
257 		error = -E2BIG;
258 	}
259 out:
260 	kfree(klist);
261 	return error;
262 }
263 
264 asmlinkage ssize_t
265 sys_listxattr(char __user *path, char __user *list, size_t size)
266 {
267 	struct nameidata nd;
268 	ssize_t error;
269 
270 	error = user_path_walk(path, &nd);
271 	if (error)
272 		return error;
273 	error = listxattr(nd.dentry, list, size);
274 	path_release(&nd);
275 	return error;
276 }
277 
278 asmlinkage ssize_t
279 sys_llistxattr(char __user *path, char __user *list, size_t size)
280 {
281 	struct nameidata nd;
282 	ssize_t error;
283 
284 	error = user_path_walk_link(path, &nd);
285 	if (error)
286 		return error;
287 	error = listxattr(nd.dentry, list, size);
288 	path_release(&nd);
289 	return error;
290 }
291 
292 asmlinkage ssize_t
293 sys_flistxattr(int fd, char __user *list, size_t size)
294 {
295 	struct file *f;
296 	ssize_t error = -EBADF;
297 
298 	f = fget(fd);
299 	if (!f)
300 		return error;
301 	error = listxattr(f->f_dentry, list, size);
302 	fput(f);
303 	return error;
304 }
305 
306 /*
307  * Extended attribute REMOVE operations
308  */
309 static long
310 removexattr(struct dentry *d, char __user *name)
311 {
312 	int error;
313 	char kname[XATTR_NAME_MAX + 1];
314 
315 	error = strncpy_from_user(kname, name, sizeof(kname));
316 	if (error == 0 || error == sizeof(kname))
317 		error = -ERANGE;
318 	if (error < 0)
319 		return error;
320 
321 	error = -EOPNOTSUPP;
322 	if (d->d_inode->i_op && d->d_inode->i_op->removexattr) {
323 		error = security_inode_removexattr(d, kname);
324 		if (error)
325 			goto out;
326 		mutex_lock(&d->d_inode->i_mutex);
327 		error = d->d_inode->i_op->removexattr(d, kname);
328 		mutex_unlock(&d->d_inode->i_mutex);
329 		if (!error)
330 			fsnotify_xattr(d);
331 	}
332 out:
333 	return error;
334 }
335 
336 asmlinkage long
337 sys_removexattr(char __user *path, char __user *name)
338 {
339 	struct nameidata nd;
340 	int error;
341 
342 	error = user_path_walk(path, &nd);
343 	if (error)
344 		return error;
345 	error = removexattr(nd.dentry, name);
346 	path_release(&nd);
347 	return error;
348 }
349 
350 asmlinkage long
351 sys_lremovexattr(char __user *path, char __user *name)
352 {
353 	struct nameidata nd;
354 	int error;
355 
356 	error = user_path_walk_link(path, &nd);
357 	if (error)
358 		return error;
359 	error = removexattr(nd.dentry, name);
360 	path_release(&nd);
361 	return error;
362 }
363 
364 asmlinkage long
365 sys_fremovexattr(int fd, char __user *name)
366 {
367 	struct file *f;
368 	int error = -EBADF;
369 
370 	f = fget(fd);
371 	if (!f)
372 		return error;
373 	error = removexattr(f->f_dentry, name);
374 	fput(f);
375 	return error;
376 }
377 
378 
379 static const char *
380 strcmp_prefix(const char *a, const char *a_prefix)
381 {
382 	while (*a_prefix && *a == *a_prefix) {
383 		a++;
384 		a_prefix++;
385 	}
386 	return *a_prefix ? NULL : a;
387 }
388 
389 /*
390  * In order to implement different sets of xattr operations for each xattr
391  * prefix with the generic xattr API, a filesystem should create a
392  * null-terminated array of struct xattr_handler (one for each prefix) and
393  * hang a pointer to it off of the s_xattr field of the superblock.
394  *
395  * The generic_fooxattr() functions will use this list to dispatch xattr
396  * operations to the correct xattr_handler.
397  */
398 #define for_each_xattr_handler(handlers, handler)		\
399 		for ((handler) = *(handlers)++;			\
400 			(handler) != NULL;			\
401 			(handler) = *(handlers)++)
402 
403 /*
404  * Find the xattr_handler with the matching prefix.
405  */
406 static struct xattr_handler *
407 xattr_resolve_name(struct xattr_handler **handlers, const char **name)
408 {
409 	struct xattr_handler *handler;
410 
411 	if (!*name)
412 		return NULL;
413 
414 	for_each_xattr_handler(handlers, handler) {
415 		const char *n = strcmp_prefix(*name, handler->prefix);
416 		if (n) {
417 			*name = n;
418 			break;
419 		}
420 	}
421 	return handler;
422 }
423 
424 /*
425  * Find the handler for the prefix and dispatch its get() operation.
426  */
427 ssize_t
428 generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size)
429 {
430 	struct xattr_handler *handler;
431 	struct inode *inode = dentry->d_inode;
432 
433 	handler = xattr_resolve_name(inode->i_sb->s_xattr, &name);
434 	if (!handler)
435 		return -EOPNOTSUPP;
436 	return handler->get(inode, name, buffer, size);
437 }
438 
439 /*
440  * Combine the results of the list() operation from every xattr_handler in the
441  * list.
442  */
443 ssize_t
444 generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
445 {
446 	struct inode *inode = dentry->d_inode;
447 	struct xattr_handler *handler, **handlers = inode->i_sb->s_xattr;
448 	unsigned int size = 0;
449 
450 	if (!buffer) {
451 		for_each_xattr_handler(handlers, handler)
452 			size += handler->list(inode, NULL, 0, NULL, 0);
453 	} else {
454 		char *buf = buffer;
455 
456 		for_each_xattr_handler(handlers, handler) {
457 			size = handler->list(inode, buf, buffer_size, NULL, 0);
458 			if (size > buffer_size)
459 				return -ERANGE;
460 			buf += size;
461 			buffer_size -= size;
462 		}
463 		size = buf - buffer;
464 	}
465 	return size;
466 }
467 
468 /*
469  * Find the handler for the prefix and dispatch its set() operation.
470  */
471 int
472 generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags)
473 {
474 	struct xattr_handler *handler;
475 	struct inode *inode = dentry->d_inode;
476 
477 	if (size == 0)
478 		value = "";  /* empty EA, do not remove */
479 	handler = xattr_resolve_name(inode->i_sb->s_xattr, &name);
480 	if (!handler)
481 		return -EOPNOTSUPP;
482 	return handler->set(inode, name, value, size, flags);
483 }
484 
485 /*
486  * Find the handler for the prefix and dispatch its set() operation to remove
487  * any associated extended attribute.
488  */
489 int
490 generic_removexattr(struct dentry *dentry, const char *name)
491 {
492 	struct xattr_handler *handler;
493 	struct inode *inode = dentry->d_inode;
494 
495 	handler = xattr_resolve_name(inode->i_sb->s_xattr, &name);
496 	if (!handler)
497 		return -EOPNOTSUPP;
498 	return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
499 }
500 
501 EXPORT_SYMBOL(generic_getxattr);
502 EXPORT_SYMBOL(generic_listxattr);
503 EXPORT_SYMBOL(generic_setxattr);
504 EXPORT_SYMBOL(generic_removexattr);
505