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