~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/xattr.c

Version: ~ [ linux-5.8-rc4 ] ~ [ linux-5.7.7 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.50 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.131 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.187 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.229 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.229 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3   File: fs/xattr.c
  4 
  5   Extended attribute handling.
  6 
  7   Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
  8   Copyright (C) 2001 SGI - Silicon Graphics, Inc <linux-xfs@oss.sgi.com>
  9   Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
 10  */
 11 #include <linux/fs.h>
 12 #include <linux/slab.h>
 13 #include <linux/file.h>
 14 #include <linux/xattr.h>
 15 #include <linux/mount.h>
 16 #include <linux/namei.h>
 17 #include <linux/security.h>
 18 #include <linux/evm.h>
 19 #include <linux/syscalls.h>
 20 #include <linux/export.h>
 21 #include <linux/fsnotify.h>
 22 #include <linux/audit.h>
 23 #include <linux/vmalloc.h>
 24 #include <linux/posix_acl_xattr.h>
 25 
 26 #include <linux/uaccess.h>
 27 
 28 static const char *
 29 strcmp_prefix(const char *a, const char *a_prefix)
 30 {
 31         while (*a_prefix && *a == *a_prefix) {
 32                 a++;
 33                 a_prefix++;
 34         }
 35         return *a_prefix ? NULL : a;
 36 }
 37 
 38 /*
 39  * In order to implement different sets of xattr operations for each xattr
 40  * prefix, a filesystem should create a null-terminated array of struct
 41  * xattr_handler (one for each prefix) and hang a pointer to it off of the
 42  * s_xattr field of the superblock.
 43  */
 44 #define for_each_xattr_handler(handlers, handler)               \
 45         if (handlers)                                           \
 46                 for ((handler) = *(handlers)++;                 \
 47                         (handler) != NULL;                      \
 48                         (handler) = *(handlers)++)
 49 
 50 /*
 51  * Find the xattr_handler with the matching prefix.
 52  */
 53 static const struct xattr_handler *
 54 xattr_resolve_name(struct inode *inode, const char **name)
 55 {
 56         const struct xattr_handler **handlers = inode->i_sb->s_xattr;
 57         const struct xattr_handler *handler;
 58 
 59         if (!(inode->i_opflags & IOP_XATTR)) {
 60                 if (unlikely(is_bad_inode(inode)))
 61                         return ERR_PTR(-EIO);
 62                 return ERR_PTR(-EOPNOTSUPP);
 63         }
 64         for_each_xattr_handler(handlers, handler) {
 65                 const char *n;
 66 
 67                 n = strcmp_prefix(*name, xattr_prefix(handler));
 68                 if (n) {
 69                         if (!handler->prefix ^ !*n) {
 70                                 if (*n)
 71                                         continue;
 72                                 return ERR_PTR(-EINVAL);
 73                         }
 74                         *name = n;
 75                         return handler;
 76                 }
 77         }
 78         return ERR_PTR(-EOPNOTSUPP);
 79 }
 80 
 81 /*
 82  * Check permissions for extended attribute access.  This is a bit complicated
 83  * because different namespaces have very different rules.
 84  */
 85 static int
 86 xattr_permission(struct inode *inode, const char *name, int mask)
 87 {
 88         /*
 89          * We can never set or remove an extended attribute on a read-only
 90          * filesystem  or on an immutable / append-only inode.
 91          */
 92         if (mask & MAY_WRITE) {
 93                 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 94                         return -EPERM;
 95                 /*
 96                  * Updating an xattr will likely cause i_uid and i_gid
 97                  * to be writen back improperly if their true value is
 98                  * unknown to the vfs.
 99                  */
100                 if (HAS_UNMAPPED_ID(inode))
101                         return -EPERM;
102         }
103 
104         /*
105          * No restriction for security.* and system.* from the VFS.  Decision
106          * on these is left to the underlying filesystem / security module.
107          */
108         if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) ||
109             !strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
110                 return 0;
111 
112         /*
113          * The trusted.* namespace can only be accessed by privileged users.
114          */
115         if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
116                 if (!capable(CAP_SYS_ADMIN))
117                         return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
118                 return 0;
119         }
120 
121         /*
122          * In the user.* namespace, only regular files and directories can have
123          * extended attributes. For sticky directories, only the owner and
124          * privileged users can write attributes.
125          */
126         if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
127                 if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
128                         return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
129                 if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) &&
130                     (mask & MAY_WRITE) && !inode_owner_or_capable(inode))
131                         return -EPERM;
132         }
133 
134         return inode_permission(inode, mask);
135 }
136 
137 int
138 __vfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name,
139                const void *value, size_t size, int flags)
140 {
141         const struct xattr_handler *handler;
142 
143         handler = xattr_resolve_name(inode, &name);
144         if (IS_ERR(handler))
145                 return PTR_ERR(handler);
146         if (!handler->set)
147                 return -EOPNOTSUPP;
148         if (size == 0)
149                 value = "";  /* empty EA, do not remove */
150         return handler->set(handler, dentry, inode, name, value, size, flags);
151 }
152 EXPORT_SYMBOL(__vfs_setxattr);
153 
154 /**
155  *  __vfs_setxattr_noperm - perform setxattr operation without performing
156  *  permission checks.
157  *
158  *  @dentry - object to perform setxattr on
159  *  @name - xattr name to set
160  *  @value - value to set @name to
161  *  @size - size of @value
162  *  @flags - flags to pass into filesystem operations
163  *
164  *  returns the result of the internal setxattr or setsecurity operations.
165  *
166  *  This function requires the caller to lock the inode's i_mutex before it
167  *  is executed. It also assumes that the caller will make the appropriate
168  *  permission checks.
169  */
170 int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
171                 const void *value, size_t size, int flags)
172 {
173         struct inode *inode = dentry->d_inode;
174         int error = -EAGAIN;
175         int issec = !strncmp(name, XATTR_SECURITY_PREFIX,
176                                    XATTR_SECURITY_PREFIX_LEN);
177 
178         if (issec)
179                 inode->i_flags &= ~S_NOSEC;
180         if (inode->i_opflags & IOP_XATTR) {
181                 error = __vfs_setxattr(dentry, inode, name, value, size, flags);
182                 if (!error) {
183                         fsnotify_xattr(dentry);
184                         security_inode_post_setxattr(dentry, name, value,
185                                                      size, flags);
186                 }
187         } else {
188                 if (unlikely(is_bad_inode(inode)))
189                         return -EIO;
190         }
191         if (error == -EAGAIN) {
192                 error = -EOPNOTSUPP;
193 
194                 if (issec) {
195                         const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
196 
197                         error = security_inode_setsecurity(inode, suffix, value,
198                                                            size, flags);
199                         if (!error)
200                                 fsnotify_xattr(dentry);
201                 }
202         }
203 
204         return error;
205 }
206 
207 
208 int
209 vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
210                 size_t size, int flags)
211 {
212         struct inode *inode = dentry->d_inode;
213         int error;
214 
215         error = xattr_permission(inode, name, MAY_WRITE);
216         if (error)
217                 return error;
218 
219         inode_lock(inode);
220         error = security_inode_setxattr(dentry, name, value, size, flags);
221         if (error)
222                 goto out;
223 
224         error = __vfs_setxattr_noperm(dentry, name, value, size, flags);
225 
226 out:
227         inode_unlock(inode);
228         return error;
229 }
230 EXPORT_SYMBOL_GPL(vfs_setxattr);
231 
232 static ssize_t
233 xattr_getsecurity(struct inode *inode, const char *name, void *value,
234                         size_t size)
235 {
236         void *buffer = NULL;
237         ssize_t len;
238 
239         if (!value || !size) {
240                 len = security_inode_getsecurity(inode, name, &buffer, false);
241                 goto out_noalloc;
242         }
243 
244         len = security_inode_getsecurity(inode, name, &buffer, true);
245         if (len < 0)
246                 return len;
247         if (size < len) {
248                 len = -ERANGE;
249                 goto out;
250         }
251         memcpy(value, buffer, len);
252 out:
253         kfree(buffer);
254 out_noalloc:
255         return len;
256 }
257 
258 /*
259  * vfs_getxattr_alloc - allocate memory, if necessary, before calling getxattr
260  *
261  * Allocate memory, if not already allocated, or re-allocate correct size,
262  * before retrieving the extended attribute.
263  *
264  * Returns the result of alloc, if failed, or the getxattr operation.
265  */
266 ssize_t
267 vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
268                    size_t xattr_size, gfp_t flags)
269 {
270         const struct xattr_handler *handler;
271         struct inode *inode = dentry->d_inode;
272         char *value = *xattr_value;
273         int error;
274 
275         error = xattr_permission(inode, name, MAY_READ);
276         if (error)
277                 return error;
278 
279         handler = xattr_resolve_name(inode, &name);
280         if (IS_ERR(handler))
281                 return PTR_ERR(handler);
282         if (!handler->get)
283                 return -EOPNOTSUPP;
284         error = handler->get(handler, dentry, inode, name, NULL, 0);
285         if (error < 0)
286                 return error;
287 
288         if (!value || (error > xattr_size)) {
289                 value = krealloc(*xattr_value, error + 1, flags);
290                 if (!value)
291                         return -ENOMEM;
292                 memset(value, 0, error + 1);
293         }
294 
295         error = handler->get(handler, dentry, inode, name, value, error);
296         *xattr_value = value;
297         return error;
298 }
299 
300 ssize_t
301 __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
302                void *value, size_t size)
303 {
304         const struct xattr_handler *handler;
305 
306         handler = xattr_resolve_name(inode, &name);
307         if (IS_ERR(handler))
308                 return PTR_ERR(handler);
309         if (!handler->get)
310                 return -EOPNOTSUPP;
311         return handler->get(handler, dentry, inode, name, value, size);
312 }
313 EXPORT_SYMBOL(__vfs_getxattr);
314 
315 ssize_t
316 vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
317 {
318         struct inode *inode = dentry->d_inode;
319         int error;
320 
321         error = xattr_permission(inode, name, MAY_READ);
322         if (error)
323                 return error;
324 
325         error = security_inode_getxattr(dentry, name);
326         if (error)
327                 return error;
328 
329         if (!strncmp(name, XATTR_SECURITY_PREFIX,
330                                 XATTR_SECURITY_PREFIX_LEN)) {
331                 const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
332                 int ret = xattr_getsecurity(inode, suffix, value, size);
333                 /*
334                  * Only overwrite the return value if a security module
335                  * is actually active.
336                  */
337                 if (ret == -EOPNOTSUPP)
338                         goto nolsm;
339                 return ret;
340         }
341 nolsm:
342         return __vfs_getxattr(dentry, inode, name, value, size);
343 }
344 EXPORT_SYMBOL_GPL(vfs_getxattr);
345 
346 ssize_t
347 vfs_listxattr(struct dentry *dentry, char *list, size_t size)
348 {
349         struct inode *inode = d_inode(dentry);
350         ssize_t error;
351 
352         error = security_inode_listxattr(dentry);
353         if (error)
354                 return error;
355         if (inode->i_op->listxattr && (inode->i_opflags & IOP_XATTR)) {
356                 error = inode->i_op->listxattr(dentry, list, size);
357         } else {
358                 error = security_inode_listsecurity(inode, list, size);
359                 if (size && error > size)
360                         error = -ERANGE;
361         }
362         return error;
363 }
364 EXPORT_SYMBOL_GPL(vfs_listxattr);
365 
366 int
367 __vfs_removexattr(struct dentry *dentry, const char *name)
368 {
369         struct inode *inode = d_inode(dentry);
370         const struct xattr_handler *handler;
371 
372         handler = xattr_resolve_name(inode, &name);
373         if (IS_ERR(handler))
374                 return PTR_ERR(handler);
375         if (!handler->set)
376                 return -EOPNOTSUPP;
377         return handler->set(handler, dentry, inode, name, NULL, 0, XATTR_REPLACE);
378 }
379 EXPORT_SYMBOL(__vfs_removexattr);
380 
381 int
382 vfs_removexattr(struct dentry *dentry, const char *name)
383 {
384         struct inode *inode = dentry->d_inode;
385         int error;
386 
387         error = xattr_permission(inode, name, MAY_WRITE);
388         if (error)
389                 return error;
390 
391         inode_lock(inode);
392         error = security_inode_removexattr(dentry, name);
393         if (error)
394                 goto out;
395 
396         error = __vfs_removexattr(dentry, name);
397 
398         if (!error) {
399                 fsnotify_xattr(dentry);
400                 evm_inode_post_removexattr(dentry, name);
401         }
402 
403 out:
404         inode_unlock(inode);
405         return error;
406 }
407 EXPORT_SYMBOL_GPL(vfs_removexattr);
408 
409 
410 /*
411  * Extended attribute SET operations
412  */
413 static long
414 setxattr(struct dentry *d, const char __user *name, const void __user *value,
415          size_t size, int flags)
416 {
417         int error;
418         void *kvalue = NULL;
419         char kname[XATTR_NAME_MAX + 1];
420 
421         if (flags & ~(XATTR_CREATE|XATTR_REPLACE))
422                 return -EINVAL;
423 
424         error = strncpy_from_user(kname, name, sizeof(kname));
425         if (error == 0 || error == sizeof(kname))
426                 error = -ERANGE;
427         if (error < 0)
428                 return error;
429 
430         if (size) {
431                 if (size > XATTR_SIZE_MAX)
432                         return -E2BIG;
433                 kvalue = kvmalloc(size, GFP_KERNEL);
434                 if (!kvalue)
435                         return -ENOMEM;
436                 if (copy_from_user(kvalue, value, size)) {
437                         error = -EFAULT;
438                         goto out;
439                 }
440                 if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
441                     (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
442                         posix_acl_fix_xattr_from_user(kvalue, size);
443                 else if (strcmp(kname, XATTR_NAME_CAPS) == 0) {
444                         error = cap_convert_nscap(d, &kvalue, size);
445                         if (error < 0)
446                                 goto out;
447                         size = error;
448                 }
449         }
450 
451         error = vfs_setxattr(d, kname, kvalue, size, flags);
452 out:
453         kvfree(kvalue);
454 
455         return error;
456 }
457 
458 static int path_setxattr(const char __user *pathname,
459                          const char __user *name, const void __user *value,
460                          size_t size, int flags, unsigned int lookup_flags)
461 {
462         struct path path;
463         int error;
464 retry:
465         error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
466         if (error)
467                 return error;
468         error = mnt_want_write(path.mnt);
469         if (!error) {
470                 error = setxattr(path.dentry, name, value, size, flags);
471                 mnt_drop_write(path.mnt);
472         }
473         path_put(&path);
474         if (retry_estale(error, lookup_flags)) {
475                 lookup_flags |= LOOKUP_REVAL;
476                 goto retry;
477         }
478         return error;
479 }
480 
481 SYSCALL_DEFINE5(setxattr, const char __user *, pathname,
482                 const char __user *, name, const void __user *, value,
483                 size_t, size, int, flags)
484 {
485         return path_setxattr(pathname, name, value, size, flags, LOOKUP_FOLLOW);
486 }
487 
488 SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname,
489                 const char __user *, name, const void __user *, value,
490                 size_t, size, int, flags)
491 {
492         return path_setxattr(pathname, name, value, size, flags, 0);
493 }
494 
495 SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
496                 const void __user *,value, size_t, size, int, flags)
497 {
498         struct fd f = fdget(fd);
499         int error = -EBADF;
500 
501         if (!f.file)
502                 return error;
503         audit_file(f.file);
504         error = mnt_want_write_file(f.file);
505         if (!error) {
506                 error = setxattr(f.file->f_path.dentry, name, value, size, flags);
507                 mnt_drop_write_file(f.file);
508         }
509         fdput(f);
510         return error;
511 }
512 
513 /*
514  * Extended attribute GET operations
515  */
516 static ssize_t
517 getxattr(struct dentry *d, const char __user *name, void __user *value,
518          size_t size)
519 {
520         ssize_t error;
521         void *kvalue = NULL;
522         char kname[XATTR_NAME_MAX + 1];
523 
524         error = strncpy_from_user(kname, name, sizeof(kname));
525         if (error == 0 || error == sizeof(kname))
526                 error = -ERANGE;
527         if (error < 0)
528                 return error;
529 
530         if (size) {
531                 if (size > XATTR_SIZE_MAX)
532                         size = XATTR_SIZE_MAX;
533                 kvalue = kvzalloc(size, GFP_KERNEL);
534                 if (!kvalue)
535                         return -ENOMEM;
536         }
537 
538         error = vfs_getxattr(d, kname, kvalue, size);
539         if (error > 0) {
540                 if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
541                     (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
542                         posix_acl_fix_xattr_to_user(kvalue, error);
543                 if (size && copy_to_user(value, kvalue, error))
544                         error = -EFAULT;
545         } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) {
546                 /* The file system tried to returned a value bigger
547                    than XATTR_SIZE_MAX bytes. Not possible. */
548                 error = -E2BIG;
549         }
550 
551         kvfree(kvalue);
552 
553         return error;
554 }
555 
556 static ssize_t path_getxattr(const char __user *pathname,
557                              const char __user *name, void __user *value,
558                              size_t size, unsigned int lookup_flags)
559 {
560         struct path path;
561         ssize_t error;
562 retry:
563         error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
564         if (error)
565                 return error;
566         error = getxattr(path.dentry, name, value, size);
567         path_put(&path);
568         if (retry_estale(error, lookup_flags)) {
569                 lookup_flags |= LOOKUP_REVAL;
570                 goto retry;
571         }
572         return error;
573 }
574 
575 SYSCALL_DEFINE4(getxattr, const char __user *, pathname,
576                 const char __user *, name, void __user *, value, size_t, size)
577 {
578         return path_getxattr(pathname, name, value, size, LOOKUP_FOLLOW);
579 }
580 
581 SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname,
582                 const char __user *, name, void __user *, value, size_t, size)
583 {
584         return path_getxattr(pathname, name, value, size, 0);
585 }
586 
587 SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name,
588                 void __user *, value, size_t, size)
589 {
590         struct fd f = fdget(fd);
591         ssize_t error = -EBADF;
592 
593         if (!f.file)
594                 return error;
595         audit_file(f.file);
596         error = getxattr(f.file->f_path.dentry, name, value, size);
597         fdput(f);
598         return error;
599 }
600 
601 /*
602  * Extended attribute LIST operations
603  */
604 static ssize_t
605 listxattr(struct dentry *d, char __user *list, size_t size)
606 {
607         ssize_t error;
608         char *klist = NULL;
609 
610         if (size) {
611                 if (size > XATTR_LIST_MAX)
612                         size = XATTR_LIST_MAX;
613                 klist = kvmalloc(size, GFP_KERNEL);
614                 if (!klist)
615                         return -ENOMEM;
616         }
617 
618         error = vfs_listxattr(d, klist, size);
619         if (error > 0) {
620                 if (size && copy_to_user(list, klist, error))
621                         error = -EFAULT;
622         } else if (error == -ERANGE && size >= XATTR_LIST_MAX) {
623                 /* The file system tried to returned a list bigger
624                    than XATTR_LIST_MAX bytes. Not possible. */
625                 error = -E2BIG;
626         }
627 
628         kvfree(klist);
629 
630         return error;
631 }
632 
633 static ssize_t path_listxattr(const char __user *pathname, char __user *list,
634                               size_t size, unsigned int lookup_flags)
635 {
636         struct path path;
637         ssize_t error;
638 retry:
639         error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
640         if (error)
641                 return error;
642         error = listxattr(path.dentry, list, size);
643         path_put(&path);
644         if (retry_estale(error, lookup_flags)) {
645                 lookup_flags |= LOOKUP_REVAL;
646                 goto retry;
647         }
648         return error;
649 }
650 
651 SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list,
652                 size_t, size)
653 {
654         return path_listxattr(pathname, list, size, LOOKUP_FOLLOW);
655 }
656 
657 SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list,
658                 size_t, size)
659 {
660         return path_listxattr(pathname, list, size, 0);
661 }
662 
663 SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size)
664 {
665         struct fd f = fdget(fd);
666         ssize_t error = -EBADF;
667 
668         if (!f.file)
669                 return error;
670         audit_file(f.file);
671         error = listxattr(f.file->f_path.dentry, list, size);
672         fdput(f);
673         return error;
674 }
675 
676 /*
677  * Extended attribute REMOVE operations
678  */
679 static long
680 removexattr(struct dentry *d, const char __user *name)
681 {
682         int error;
683         char kname[XATTR_NAME_MAX + 1];
684 
685         error = strncpy_from_user(kname, name, sizeof(kname));
686         if (error == 0 || error == sizeof(kname))
687                 error = -ERANGE;
688         if (error < 0)
689                 return error;
690 
691         return vfs_removexattr(d, kname);
692 }
693 
694 static int path_removexattr(const char __user *pathname,
695                             const char __user *name, unsigned int lookup_flags)
696 {
697         struct path path;
698         int error;
699 retry:
700         error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
701         if (error)
702                 return error;
703         error = mnt_want_write(path.mnt);
704         if (!error) {
705                 error = removexattr(path.dentry, name);
706                 mnt_drop_write(path.mnt);
707         }
708         path_put(&path);
709         if (retry_estale(error, lookup_flags)) {
710                 lookup_flags |= LOOKUP_REVAL;
711                 goto retry;
712         }
713         return error;
714 }
715 
716 SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
717                 const char __user *, name)
718 {
719         return path_removexattr(pathname, name, LOOKUP_FOLLOW);
720 }
721 
722 SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname,
723                 const char __user *, name)
724 {
725         return path_removexattr(pathname, name, 0);
726 }
727 
728 SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
729 {
730         struct fd f = fdget(fd);
731         int error = -EBADF;
732 
733         if (!f.file)
734                 return error;
735         audit_file(f.file);
736         error = mnt_want_write_file(f.file);
737         if (!error) {
738                 error = removexattr(f.file->f_path.dentry, name);
739                 mnt_drop_write_file(f.file);
740         }
741         fdput(f);
742         return error;
743 }
744 
745 /*
746  * Combine the results of the list() operation from every xattr_handler in the
747  * list.
748  */
749 ssize_t
750 generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
751 {
752         const struct xattr_handler *handler, **handlers = dentry->d_sb->s_xattr;
753         unsigned int size = 0;
754 
755         if (!buffer) {
756                 for_each_xattr_handler(handlers, handler) {
757                         if (!handler->name ||
758                             (handler->list && !handler->list(dentry)))
759                                 continue;
760                         size += strlen(handler->name) + 1;
761                 }
762         } else {
763                 char *buf = buffer;
764                 size_t len;
765 
766                 for_each_xattr_handler(handlers, handler) {
767                         if (!handler->name ||
768                             (handler->list && !handler->list(dentry)))
769                                 continue;
770                         len = strlen(handler->name);
771                         if (len + 1 > buffer_size)
772                                 return -ERANGE;
773                         memcpy(buf, handler->name, len + 1);
774                         buf += len + 1;
775                         buffer_size -= len + 1;
776                 }
777                 size = buf - buffer;
778         }
779         return size;
780 }
781 EXPORT_SYMBOL(generic_listxattr);
782 
783 /**
784  * xattr_full_name  -  Compute full attribute name from suffix
785  *
786  * @handler:    handler of the xattr_handler operation
787  * @name:       name passed to the xattr_handler operation
788  *
789  * The get and set xattr handler operations are called with the remainder of
790  * the attribute name after skipping the handler's prefix: for example, "foo"
791  * is passed to the get operation of a handler with prefix "user." to get
792  * attribute "user.foo".  The full name is still "there" in the name though.
793  *
794  * Note: the list xattr handler operation when called from the vfs is passed a
795  * NULL name; some file systems use this operation internally, with varying
796  * semantics.
797  */
798 const char *xattr_full_name(const struct xattr_handler *handler,
799                             const char *name)
800 {
801         size_t prefix_len = strlen(xattr_prefix(handler));
802 
803         return name - prefix_len;
804 }
805 EXPORT_SYMBOL(xattr_full_name);
806 
807 /*
808  * Allocate new xattr and copy in the value; but leave the name to callers.
809  */
810 struct simple_xattr *simple_xattr_alloc(const void *value, size_t size)
811 {
812         struct simple_xattr *new_xattr;
813         size_t len;
814 
815         /* wrap around? */
816         len = sizeof(*new_xattr) + size;
817         if (len < sizeof(*new_xattr))
818                 return NULL;
819 
820         new_xattr = kmalloc(len, GFP_KERNEL);
821         if (!new_xattr)
822                 return NULL;
823 
824         new_xattr->size = size;
825         memcpy(new_xattr->value, value, size);
826         return new_xattr;
827 }
828 
829 /*
830  * xattr GET operation for in-memory/pseudo filesystems
831  */
832 int simple_xattr_get(struct simple_xattrs *xattrs, const char *name,
833                      void *buffer, size_t size)
834 {
835         struct simple_xattr *xattr;
836         int ret = -ENODATA;
837 
838         spin_lock(&xattrs->lock);
839         list_for_each_entry(xattr, &xattrs->head, list) {
840                 if (strcmp(name, xattr->name))
841                         continue;
842 
843                 ret = xattr->size;
844                 if (buffer) {
845                         if (size < xattr->size)
846                                 ret = -ERANGE;
847                         else
848                                 memcpy(buffer, xattr->value, xattr->size);
849                 }
850                 break;
851         }
852         spin_unlock(&xattrs->lock);
853         return ret;
854 }
855 
856 /**
857  * simple_xattr_set - xattr SET operation for in-memory/pseudo filesystems
858  * @xattrs: target simple_xattr list
859  * @name: name of the extended attribute
860  * @value: value of the xattr. If %NULL, will remove the attribute.
861  * @size: size of the new xattr
862  * @flags: %XATTR_{CREATE|REPLACE}
863  *
864  * %XATTR_CREATE is set, the xattr shouldn't exist already; otherwise fails
865  * with -EEXIST.  If %XATTR_REPLACE is set, the xattr should exist;
866  * otherwise, fails with -ENODATA.
867  *
868  * Returns 0 on success, -errno on failure.
869  */
870 int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
871                      const void *value, size_t size, int flags)
872 {
873         struct simple_xattr *xattr;
874         struct simple_xattr *new_xattr = NULL;
875         int err = 0;
876 
877         /* value == NULL means remove */
878         if (value) {
879                 new_xattr = simple_xattr_alloc(value, size);
880                 if (!new_xattr)
881                         return -ENOMEM;
882 
883                 new_xattr->name = kstrdup(name, GFP_KERNEL);
884                 if (!new_xattr->name) {
885                         kfree(new_xattr);
886                         return -ENOMEM;
887                 }
888         }
889 
890         spin_lock(&xattrs->lock);
891         list_for_each_entry(xattr, &xattrs->head, list) {
892                 if (!strcmp(name, xattr->name)) {
893                         if (flags & XATTR_CREATE) {
894                                 xattr = new_xattr;
895                                 err = -EEXIST;
896                         } else if (new_xattr) {
897                                 list_replace(&xattr->list, &new_xattr->list);
898                         } else {
899                                 list_del(&xattr->list);
900                         }
901                         goto out;
902                 }
903         }
904         if (flags & XATTR_REPLACE) {
905                 xattr = new_xattr;
906                 err = -ENODATA;
907         } else {
908                 list_add(&new_xattr->list, &xattrs->head);
909                 xattr = NULL;
910         }
911 out:
912         spin_unlock(&xattrs->lock);
913         if (xattr) {
914                 kfree(xattr->name);
915                 kfree(xattr);
916         }
917         return err;
918 
919 }
920 
921 static bool xattr_is_trusted(const char *name)
922 {
923         return !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN);
924 }
925 
926 static int xattr_list_one(char **buffer, ssize_t *remaining_size,
927                           const char *name)
928 {
929         size_t len = strlen(name) + 1;
930         if (*buffer) {
931                 if (*remaining_size < len)
932                         return -ERANGE;
933                 memcpy(*buffer, name, len);
934                 *buffer += len;
935         }
936         *remaining_size -= len;
937         return 0;
938 }
939 
940 /*
941  * xattr LIST operation for in-memory/pseudo filesystems
942  */
943 ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
944                           char *buffer, size_t size)
945 {
946         bool trusted = capable(CAP_SYS_ADMIN);
947         struct simple_xattr *xattr;
948         ssize_t remaining_size = size;
949         int err = 0;
950 
951 #ifdef CONFIG_FS_POSIX_ACL
952         if (IS_POSIXACL(inode)) {
953                 if (inode->i_acl) {
954                         err = xattr_list_one(&buffer, &remaining_size,
955                                              XATTR_NAME_POSIX_ACL_ACCESS);
956                         if (err)
957                                 return err;
958                 }
959                 if (inode->i_default_acl) {
960                         err = xattr_list_one(&buffer, &remaining_size,
961                                              XATTR_NAME_POSIX_ACL_DEFAULT);
962                         if (err)
963                                 return err;
964                 }
965         }
966 #endif
967 
968         spin_lock(&xattrs->lock);
969         list_for_each_entry(xattr, &xattrs->head, list) {
970                 /* skip "trusted." attributes for unprivileged callers */
971                 if (!trusted && xattr_is_trusted(xattr->name))
972                         continue;
973 
974                 err = xattr_list_one(&buffer, &remaining_size, xattr->name);
975                 if (err)
976                         break;
977         }
978         spin_unlock(&xattrs->lock);
979 
980         return err ? err : size - remaining_size;
981 }
982 
983 /*
984  * Adds an extended attribute to the list
985  */
986 void simple_xattr_list_add(struct simple_xattrs *xattrs,
987                            struct simple_xattr *new_xattr)
988 {
989         spin_lock(&xattrs->lock);
990         list_add(&new_xattr->list, &xattrs->head);
991         spin_unlock(&xattrs->lock);
992 }
993 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp