Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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/file.h>
 13 #include <linux/xattr.h>
 14 #include <linux/namei.h>
 15 #include <linux/security.h>
 16 #include <linux/syscalls.h>
 17 #include <linux/module.h>
 18 #include <linux/fsnotify.h>
 19 #include <linux/audit.h>
 20 #include <asm/uaccess.h>
 21 
 22 
 23 /*
 24  * Check permissions for extended attribute access.  This is a bit complicated
 25  * because different namespaces have very different rules.
 26  */
 27 static int
 28 xattr_permission(struct inode *inode, const char *name, int mask)
 29 {
 30         /*
 31          * We can never set or remove an extended attribute on a read-only
 32          * filesystem  or on an immutable / append-only inode.
 33          */
 34         if (mask & MAY_WRITE) {
 35                 if (IS_RDONLY(inode))
 36                         return -EROFS;
 37                 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 38                         return -EPERM;
 39         }
 40 
 41         /*
 42          * No restriction for security.* and system.* from the VFS.  Decision
 43          * on these is left to the underlying filesystem / security module.
 44          */
 45         if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) ||
 46             !strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
 47                 return 0;
 48 
 49         /*
 50          * The trusted.* namespace can only be accessed by a privileged user.
 51          */
 52         if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
 53                 return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM);
 54 
 55         /* In user.* namespace, only regular files and directories can have
 56          * extended attributes. For sticky directories, only the owner and
 57          * privileged user can write attributes.
 58          */
 59         if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
 60                 if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
 61                         return -EPERM;
 62                 if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) &&
 63                     (mask & MAY_WRITE) && !is_owner_or_cap(inode))
 64                         return -EPERM;
 65         }
 66 
 67         return permission(inode, mask, NULL);
 68 }
 69 
 70 int
 71 vfs_setxattr(struct dentry *dentry, char *name, void *value,
 72                 size_t size, int flags)
 73 {
 74         struct inode *inode = dentry->d_inode;
 75         int error;
 76 
 77         error = xattr_permission(inode, name, MAY_WRITE);
 78         if (error)
 79                 return error;
 80 
 81         mutex_lock(&inode->i_mutex);
 82         error = security_inode_setxattr(dentry, name, value, size, flags);
 83         if (error)
 84                 goto out;
 85         error = -EOPNOTSUPP;
 86         if (inode->i_op->setxattr) {
 87                 error = inode->i_op->setxattr(dentry, name, value, size, flags);
 88                 if (!error) {
 89                         fsnotify_xattr(dentry);
 90                         security_inode_post_setxattr(dentry, name, value,
 91                                                      size, flags);
 92                 }
 93         } else if (!strncmp(name, XATTR_SECURITY_PREFIX,
 94                                 XATTR_SECURITY_PREFIX_LEN)) {
 95                 const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
 96                 error = security_inode_setsecurity(inode, suffix, value,
 97                                                    size, flags);
 98                 if (!error)
 99                         fsnotify_xattr(dentry);
100         }
101 out:
102         mutex_unlock(&inode->i_mutex);
103         return error;
104 }
105 EXPORT_SYMBOL_GPL(vfs_setxattr);
106 
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
135 vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size)
136 {
137         struct inode *inode = dentry->d_inode;
138         int error;
139 
140         error = xattr_permission(inode, name, MAY_READ);
141         if (error)
142                 return error;
143 
144         error = security_inode_getxattr(dentry, name);
145         if (error)
146                 return error;
147 
148         if (!strncmp(name, XATTR_SECURITY_PREFIX,
149                                 XATTR_SECURITY_PREFIX_LEN)) {
150                 const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
151                 int ret = xattr_getsecurity(inode, suffix, value, size);
152                 /*
153                  * Only overwrite the return value if a security module
154                  * is actually active.
155                  */
156                 if (ret == -EOPNOTSUPP)
157                         goto nolsm;
158                 return ret;
159         }
160 nolsm:
161         if (inode->i_op->getxattr)
162                 error = inode->i_op->getxattr(dentry, name, value, size);
163         else
164                 error = -EOPNOTSUPP;
165 
166         return error;
167 }
168 EXPORT_SYMBOL_GPL(vfs_getxattr);
169 
170 ssize_t
171 vfs_listxattr(struct dentry *d, char *list, size_t size)
172 {
173         ssize_t error;
174 
175         error = security_inode_listxattr(d);
176         if (error)
177                 return error;
178         error = -EOPNOTSUPP;
179         if (d->d_inode->i_op && d->d_inode->i_op->listxattr) {
180                 error = d->d_inode->i_op->listxattr(d, list, size);
181         } else {
182                 error = security_inode_listsecurity(d->d_inode, list, size);
183                 if (size && error > size)
184                         error = -ERANGE;
185         }
186         return error;
187 }
188 EXPORT_SYMBOL_GPL(vfs_listxattr);
189 
190 int
191 vfs_removexattr(struct dentry *dentry, char *name)
192 {
193         struct inode *inode = dentry->d_inode;
194         int error;
195 
196         if (!inode->i_op->removexattr)
197                 return -EOPNOTSUPP;
198 
199         error = xattr_permission(inode, name, MAY_WRITE);
200         if (error)
201                 return error;
202 
203         error = security_inode_removexattr(dentry, name);
204         if (error)
205                 return error;
206 
207         mutex_lock(&inode->i_mutex);
208         error = inode->i_op->removexattr(dentry, name);
209         mutex_unlock(&inode->i_mutex);
210 
211         if (!error)
212                 fsnotify_xattr(dentry);
213         return error;
214 }
215 EXPORT_SYMBOL_GPL(vfs_removexattr);
216 
217 
218 /*
219  * Extended attribute SET operations
220  */
221 static long
222 setxattr(struct dentry *d, char __user *name, void __user *value,
223          size_t size, int flags)
224 {
225         int error;
226         void *kvalue = NULL;
227         char kname[XATTR_NAME_MAX + 1];
228 
229         if (flags & ~(XATTR_CREATE|XATTR_REPLACE))
230                 return -EINVAL;
231 
232         error = strncpy_from_user(kname, name, sizeof(kname));
233         if (error == 0 || error == sizeof(kname))
234                 error = -ERANGE;
235         if (error < 0)
236                 return error;
237 
238         if (size) {
239                 if (size > XATTR_SIZE_MAX)
240                         return -E2BIG;
241                 kvalue = kmalloc(size, GFP_KERNEL);
242                 if (!kvalue)
243                         return -ENOMEM;
244                 if (copy_from_user(kvalue, value, size)) {
245                         kfree(kvalue);
246                         return -EFAULT;
247                 }
248         }
249 
250         error = vfs_setxattr(d, kname, kvalue, size, flags);
251         kfree(kvalue);
252         return error;
253 }
254 
255 asmlinkage long
256 sys_setxattr(char __user *path, char __user *name, void __user *value,
257              size_t size, int flags)
258 {
259         struct nameidata nd;
260         int error;
261 
262         error = user_path_walk(path, &nd);
263         if (error)
264                 return error;
265         error = setxattr(nd.path.dentry, name, value, size, flags);
266         path_put(&nd.path);
267         return error;
268 }
269 
270 asmlinkage long
271 sys_lsetxattr(char __user *path, char __user *name, void __user *value,
272               size_t size, int flags)
273 {
274         struct nameidata nd;
275         int error;
276 
277         error = user_path_walk_link(path, &nd);
278         if (error)
279                 return error;
280         error = setxattr(nd.path.dentry, name, value, size, flags);
281         path_put(&nd.path);
282         return error;
283 }
284 
285 asmlinkage long
286 sys_fsetxattr(int fd, char __user *name, void __user *value,
287               size_t size, int flags)
288 {
289         struct file *f;
290         struct dentry *dentry;
291         int error = -EBADF;
292 
293         f = fget(fd);
294         if (!f)
295                 return error;
296         dentry = f->f_path.dentry;
297         audit_inode(NULL, dentry);
298         error = setxattr(dentry, name, value, size, flags);
299         fput(f);
300         return error;
301 }
302 
303 /*
304  * Extended attribute GET operations
305  */
306 static ssize_t
307 getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
308 {
309         ssize_t error;
310         void *kvalue = NULL;
311         char kname[XATTR_NAME_MAX + 1];
312 
313         error = strncpy_from_user(kname, name, sizeof(kname));
314         if (error == 0 || error == sizeof(kname))
315                 error = -ERANGE;
316         if (error < 0)
317                 return error;
318 
319         if (size) {
320                 if (size > XATTR_SIZE_MAX)
321                         size = XATTR_SIZE_MAX;
322                 kvalue = kzalloc(size, GFP_KERNEL);
323                 if (!kvalue)
324                         return -ENOMEM;
325         }
326 
327         error = vfs_getxattr(d, kname, kvalue, size);
328         if (error > 0) {
329                 if (size && copy_to_user(value, kvalue, error))
330                         error = -EFAULT;
331         } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) {
332                 /* The file system tried to returned a value bigger
333                    than XATTR_SIZE_MAX bytes. Not possible. */
334                 error = -E2BIG;
335         }
336         kfree(kvalue);
337         return error;
338 }
339 
340 asmlinkage ssize_t
341 sys_getxattr(char __user *path, char __user *name, void __user *value,
342              size_t size)
343 {
344         struct nameidata nd;
345         ssize_t error;
346 
347         error = user_path_walk(path, &nd);
348         if (error)
349                 return error;
350         error = getxattr(nd.path.dentry, name, value, size);
351         path_put(&nd.path);
352         return error;
353 }
354 
355 asmlinkage ssize_t
356 sys_lgetxattr(char __user *path, char __user *name, void __user *value,
357               size_t size)
358 {
359         struct nameidata nd;
360         ssize_t error;
361 
362         error = user_path_walk_link(path, &nd);
363         if (error)
364                 return error;
365         error = getxattr(nd.path.dentry, name, value, size);
366         path_put(&nd.path);
367         return error;
368 }
369 
370 asmlinkage ssize_t
371 sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size)
372 {
373         struct file *f;
374         ssize_t error = -EBADF;
375 
376         f = fget(fd);
377         if (!f)
378                 return error;
379         audit_inode(NULL, f->f_path.dentry);
380         error = getxattr(f->f_path.dentry, name, value, size);
381         fput(f);
382         return error;
383 }
384 
385 /*
386  * Extended attribute LIST operations
387  */
388 static ssize_t
389 listxattr(struct dentry *d, char __user *list, size_t size)
390 {
391         ssize_t error;
392         char *klist = NULL;
393 
394         if (size) {
395                 if (size > XATTR_LIST_MAX)
396                         size = XATTR_LIST_MAX;
397                 klist = kmalloc(size, GFP_KERNEL);
398                 if (!klist)
399                         return -ENOMEM;
400         }
401 
402         error = vfs_listxattr(d, klist, size);
403         if (error > 0) {
404                 if (size && copy_to_user(list, klist, error))
405                         error = -EFAULT;
406         } else if (error == -ERANGE && size >= XATTR_LIST_MAX) {
407                 /* The file system tried to returned a list bigger
408                    than XATTR_LIST_MAX bytes. Not possible. */
409                 error = -E2BIG;
410         }
411         kfree(klist);
412         return error;
413 }
414 
415 asmlinkage ssize_t
416 sys_listxattr(char __user *path, char __user *list, size_t size)
417 {
418         struct nameidata nd;
419         ssize_t error;
420 
421         error = user_path_walk(path, &nd);
422         if (error)
423                 return error;
424         error = listxattr(nd.path.dentry, list, size);
425         path_put(&nd.path);
426         return error;
427 }
428 
429 asmlinkage ssize_t
430 sys_llistxattr(char __user *path, char __user *list, size_t size)
431 {
432         struct nameidata nd;
433         ssize_t error;
434 
435         error = user_path_walk_link(path, &nd);
436         if (error)
437                 return error;
438         error = listxattr(nd.path.dentry, list, size);
439         path_put(&nd.path);
440         return error;
441 }
442 
443 asmlinkage ssize_t
444 sys_flistxattr(int fd, char __user *list, size_t size)
445 {
446         struct file *f;
447         ssize_t error = -EBADF;
448 
449         f = fget(fd);
450         if (!f)
451                 return error;
452         audit_inode(NULL, f->f_path.dentry);
453         error = listxattr(f->f_path.dentry, list, size);
454         fput(f);
455         return error;
456 }
457 
458 /*
459  * Extended attribute REMOVE operations
460  */
461 static long
462 removexattr(struct dentry *d, char __user *name)
463 {
464         int error;
465         char kname[XATTR_NAME_MAX + 1];
466 
467         error = strncpy_from_user(kname, name, sizeof(kname));
468         if (error == 0 || error == sizeof(kname))
469                 error = -ERANGE;
470         if (error < 0)
471                 return error;
472 
473         return vfs_removexattr(d, kname);
474 }
475 
476 asmlinkage long
477 sys_removexattr(char __user *path, char __user *name)
478 {
479         struct nameidata nd;
480         int error;
481 
482         error = user_path_walk(path, &nd);
483         if (error)
484                 return error;
485         error = removexattr(nd.path.dentry, name);
486         path_put(&nd.path);
487         return error;
488 }
489 
490 asmlinkage long
491 sys_lremovexattr(char __user *path, char __user *name)
492 {
493         struct nameidata nd;
494         int error;
495 
496         error = user_path_walk_link(path, &nd);
497         if (error)
498                 return error;
499         error = removexattr(nd.path.dentry, name);
500         path_put(&nd.path);
501         return error;
502 }
503 
504 asmlinkage long
505 sys_fremovexattr(int fd, char __user *name)
506 {
507         struct file *f;
508         struct dentry *dentry;
509         int error = -EBADF;
510 
511         f = fget(fd);
512         if (!f)
513                 return error;
514         dentry = f->f_path.dentry;
515         audit_inode(NULL, dentry);
516         error = removexattr(dentry, name);
517         fput(f);
518         return error;
519 }
520 
521 
522 static const char *
523 strcmp_prefix(const char *a, const char *a_prefix)
524 {
525         while (*a_prefix && *a == *a_prefix) {
526                 a++;
527                 a_prefix++;
528         }
529         return *a_prefix ? NULL : a;
530 }
531 
532 /*
533  * In order to implement different sets of xattr operations for each xattr
534  * prefix with the generic xattr API, a filesystem should create a
535  * null-terminated array of struct xattr_handler (one for each prefix) and
536  * hang a pointer to it off of the s_xattr field of the superblock.
537  *
538  * The generic_fooxattr() functions will use this list to dispatch xattr
539  * operations to the correct xattr_handler.
540  */
541 #define for_each_xattr_handler(handlers, handler)               \
542                 for ((handler) = *(handlers)++;                 \
543                         (handler) != NULL;                      \
544                         (handler) = *(handlers)++)
545 
546 /*
547  * Find the xattr_handler with the matching prefix.
548  */
549 static struct xattr_handler *
550 xattr_resolve_name(struct xattr_handler **handlers, const char **name)
551 {
552         struct xattr_handler *handler;
553 
554         if (!*name)
555                 return NULL;
556 
557         for_each_xattr_handler(handlers, handler) {
558                 const char *n = strcmp_prefix(*name, handler->prefix);
559                 if (n) {
560                         *name = n;
561                         break;
562                 }
563         }
564         return handler;
565 }
566 
567 /*
568  * Find the handler for the prefix and dispatch its get() operation.
569  */
570 ssize_t
571 generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size)
572 {
573         struct xattr_handler *handler;
574         struct inode *inode = dentry->d_inode;
575 
576         handler = xattr_resolve_name(inode->i_sb->s_xattr, &name);
577         if (!handler)
578                 return -EOPNOTSUPP;
579         return handler->get(inode, name, buffer, size);
580 }
581 
582 /*
583  * Combine the results of the list() operation from every xattr_handler in the
584  * list.
585  */
586 ssize_t
587 generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
588 {
589         struct inode *inode = dentry->d_inode;
590         struct xattr_handler *handler, **handlers = inode->i_sb->s_xattr;
591         unsigned int size = 0;
592 
593         if (!buffer) {
594                 for_each_xattr_handler(handlers, handler)
595                         size += handler->list(inode, NULL, 0, NULL, 0);
596         } else {
597                 char *buf = buffer;
598 
599                 for_each_xattr_handler(handlers, handler) {
600                         size = handler->list(inode, buf, buffer_size, NULL, 0);
601                         if (size > buffer_size)
602                                 return -ERANGE;
603                         buf += size;
604                         buffer_size -= size;
605                 }
606                 size = buf - buffer;
607         }
608         return size;
609 }
610 
611 /*
612  * Find the handler for the prefix and dispatch its set() operation.
613  */
614 int
615 generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags)
616 {
617         struct xattr_handler *handler;
618         struct inode *inode = dentry->d_inode;
619 
620         if (size == 0)
621                 value = "";  /* empty EA, do not remove */
622         handler = xattr_resolve_name(inode->i_sb->s_xattr, &name);
623         if (!handler)
624                 return -EOPNOTSUPP;
625         return handler->set(inode, name, value, size, flags);
626 }
627 
628 /*
629  * Find the handler for the prefix and dispatch its set() operation to remove
630  * any associated extended attribute.
631  */
632 int
633 generic_removexattr(struct dentry *dentry, const char *name)
634 {
635         struct xattr_handler *handler;
636         struct inode *inode = dentry->d_inode;
637 
638         handler = xattr_resolve_name(inode->i_sb->s_xattr, &name);
639         if (!handler)
640                 return -EOPNOTSUPP;
641         return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
642 }
643 
644 EXPORT_SYMBOL(generic_getxattr);
645 EXPORT_SYMBOL(generic_listxattr);
646 EXPORT_SYMBOL(generic_setxattr);
647 EXPORT_SYMBOL(generic_removexattr);
648 
  This page was automatically generated by the LXR engine.