linux/fs/overlayfs/inode.c
<<
>>
Prefs
   1/*
   2 *
   3 * Copyright (C) 2011 Novell Inc.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of the GNU General Public License version 2 as published by
   7 * the Free Software Foundation.
   8 */
   9
  10#include <linux/fs.h>
  11#include <linux/slab.h>
  12#include <linux/xattr.h>
  13#include <linux/posix_acl.h>
  14#include "overlayfs.h"
  15
  16static int ovl_copy_up_truncate(struct dentry *dentry)
  17{
  18        int err;
  19        struct dentry *parent;
  20        struct kstat stat;
  21        struct path lowerpath;
  22        const struct cred *old_cred;
  23
  24        parent = dget_parent(dentry);
  25        err = ovl_copy_up(parent);
  26        if (err)
  27                goto out_dput_parent;
  28
  29        ovl_path_lower(dentry, &lowerpath);
  30
  31        old_cred = ovl_override_creds(dentry->d_sb);
  32        err = vfs_getattr(&lowerpath, &stat);
  33        if (!err) {
  34                stat.size = 0;
  35                err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat);
  36        }
  37        revert_creds(old_cred);
  38
  39out_dput_parent:
  40        dput(parent);
  41        return err;
  42}
  43
  44int ovl_setattr(struct dentry *dentry, struct iattr *attr)
  45{
  46        int err;
  47        struct dentry *upperdentry;
  48        const struct cred *old_cred;
  49
  50        /*
  51         * Check for permissions before trying to copy-up.  This is redundant
  52         * since it will be rechecked later by ->setattr() on upper dentry.  But
  53         * without this, copy-up can be triggered by just about anybody.
  54         *
  55         * We don't initialize inode->size, which just means that
  56         * inode_newsize_ok() will always check against MAX_LFS_FILESIZE and not
  57         * check for a swapfile (which this won't be anyway).
  58         */
  59        err = setattr_prepare(dentry, attr);
  60        if (err)
  61                return err;
  62
  63        err = ovl_want_write(dentry);
  64        if (err)
  65                goto out;
  66
  67        if (attr->ia_valid & ATTR_SIZE) {
  68                struct inode *realinode = d_inode(ovl_dentry_real(dentry));
  69
  70                err = -ETXTBSY;
  71                if (atomic_read(&realinode->i_writecount) < 0)
  72                        goto out_drop_write;
  73        }
  74
  75        err = ovl_copy_up(dentry);
  76        if (!err) {
  77                struct inode *winode = NULL;
  78
  79                upperdentry = ovl_dentry_upper(dentry);
  80
  81                if (attr->ia_valid & ATTR_SIZE) {
  82                        winode = d_inode(upperdentry);
  83                        err = get_write_access(winode);
  84                        if (err)
  85                                goto out_drop_write;
  86                }
  87
  88                if (attr->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
  89                        attr->ia_valid &= ~ATTR_MODE;
  90
  91                inode_lock(upperdentry->d_inode);
  92                old_cred = ovl_override_creds(dentry->d_sb);
  93                err = notify_change(upperdentry, attr, NULL);
  94                revert_creds(old_cred);
  95                if (!err)
  96                        ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
  97                inode_unlock(upperdentry->d_inode);
  98
  99                if (winode)
 100                        put_write_access(winode);
 101        }
 102out_drop_write:
 103        ovl_drop_write(dentry);
 104out:
 105        return err;
 106}
 107
 108static int ovl_getattr(struct vfsmount *mnt, struct dentry *dentry,
 109                         struct kstat *stat)
 110{
 111        struct path realpath;
 112        const struct cred *old_cred;
 113        int err;
 114
 115        ovl_path_real(dentry, &realpath);
 116        old_cred = ovl_override_creds(dentry->d_sb);
 117        err = vfs_getattr(&realpath, stat);
 118        revert_creds(old_cred);
 119        return err;
 120}
 121
 122int ovl_permission(struct inode *inode, int mask)
 123{
 124        bool is_upper;
 125        struct inode *realinode = ovl_inode_real(inode, &is_upper);
 126        const struct cred *old_cred;
 127        int err;
 128
 129        /* Careful in RCU walk mode */
 130        if (!realinode) {
 131                WARN_ON(!(mask & MAY_NOT_BLOCK));
 132                return -ECHILD;
 133        }
 134
 135        /*
 136         * Check overlay inode with the creds of task and underlying inode
 137         * with creds of mounter
 138         */
 139        err = generic_permission(inode, mask);
 140        if (err)
 141                return err;
 142
 143        old_cred = ovl_override_creds(inode->i_sb);
 144        if (!is_upper && !special_file(realinode->i_mode) && mask & MAY_WRITE) {
 145                mask &= ~(MAY_WRITE | MAY_APPEND);
 146                /* Make sure mounter can read file for copy up later */
 147                mask |= MAY_READ;
 148        }
 149        err = inode_permission(realinode, mask);
 150        revert_creds(old_cred);
 151
 152        return err;
 153}
 154
 155static const char *ovl_get_link(struct dentry *dentry,
 156                                struct inode *inode,
 157                                struct delayed_call *done)
 158{
 159        const struct cred *old_cred;
 160        const char *p;
 161
 162        if (!dentry)
 163                return ERR_PTR(-ECHILD);
 164
 165        old_cred = ovl_override_creds(dentry->d_sb);
 166        p = vfs_get_link(ovl_dentry_real(dentry), done);
 167        revert_creds(old_cred);
 168        return p;
 169}
 170
 171bool ovl_is_private_xattr(const char *name)
 172{
 173        return strncmp(name, OVL_XATTR_PREFIX,
 174                       sizeof(OVL_XATTR_PREFIX) - 1) == 0;
 175}
 176
 177int ovl_xattr_set(struct dentry *dentry, const char *name, const void *value,
 178                  size_t size, int flags)
 179{
 180        int err;
 181        struct path realpath;
 182        enum ovl_path_type type = ovl_path_real(dentry, &realpath);
 183        const struct cred *old_cred;
 184
 185        err = ovl_want_write(dentry);
 186        if (err)
 187                goto out;
 188
 189        if (!value && !OVL_TYPE_UPPER(type)) {
 190                err = vfs_getxattr(realpath.dentry, name, NULL, 0);
 191                if (err < 0)
 192                        goto out_drop_write;
 193        }
 194
 195        err = ovl_copy_up(dentry);
 196        if (err)
 197                goto out_drop_write;
 198
 199        if (!OVL_TYPE_UPPER(type))
 200                ovl_path_upper(dentry, &realpath);
 201
 202        old_cred = ovl_override_creds(dentry->d_sb);
 203        if (value)
 204                err = vfs_setxattr(realpath.dentry, name, value, size, flags);
 205        else {
 206                WARN_ON(flags != XATTR_REPLACE);
 207                err = vfs_removexattr(realpath.dentry, name);
 208        }
 209        revert_creds(old_cred);
 210
 211out_drop_write:
 212        ovl_drop_write(dentry);
 213out:
 214        return err;
 215}
 216
 217int ovl_xattr_get(struct dentry *dentry, const char *name,
 218                  void *value, size_t size)
 219{
 220        struct dentry *realdentry = ovl_dentry_real(dentry);
 221        ssize_t res;
 222        const struct cred *old_cred;
 223
 224        old_cred = ovl_override_creds(dentry->d_sb);
 225        res = vfs_getxattr(realdentry, name, value, size);
 226        revert_creds(old_cred);
 227        return res;
 228}
 229
 230ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
 231{
 232        struct dentry *realdentry = ovl_dentry_real(dentry);
 233        ssize_t res;
 234        size_t len;
 235        char *s;
 236        const struct cred *old_cred;
 237
 238        old_cred = ovl_override_creds(dentry->d_sb);
 239        res = vfs_listxattr(realdentry, list, size);
 240        revert_creds(old_cred);
 241        if (res <= 0 || size == 0)
 242                return res;
 243
 244        /* filter out private xattrs */
 245        for (s = list, len = res; len;) {
 246                size_t slen = strnlen(s, len) + 1;
 247
 248                /* underlying fs providing us with an broken xattr list? */
 249                if (WARN_ON(slen > len))
 250                        return -EIO;
 251
 252                len -= slen;
 253                if (ovl_is_private_xattr(s)) {
 254                        res -= slen;
 255                        memmove(s, s + slen, len);
 256                } else {
 257                        s += slen;
 258                }
 259        }
 260
 261        return res;
 262}
 263
 264struct posix_acl *ovl_get_acl(struct inode *inode, int type)
 265{
 266        struct inode *realinode = ovl_inode_real(inode, NULL);
 267        const struct cred *old_cred;
 268        struct posix_acl *acl;
 269
 270        if (!IS_ENABLED(CONFIG_FS_POSIX_ACL) || !IS_POSIXACL(realinode))
 271                return NULL;
 272
 273        old_cred = ovl_override_creds(inode->i_sb);
 274        acl = get_acl(realinode, type);
 275        revert_creds(old_cred);
 276
 277        return acl;
 278}
 279
 280static bool ovl_open_need_copy_up(int flags, enum ovl_path_type type,
 281                                  struct dentry *realdentry)
 282{
 283        if (OVL_TYPE_UPPER(type))
 284                return false;
 285
 286        if (special_file(realdentry->d_inode->i_mode))
 287                return false;
 288
 289        if (!(OPEN_FMODE(flags) & FMODE_WRITE) && !(flags & O_TRUNC))
 290                return false;
 291
 292        return true;
 293}
 294
 295int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags)
 296{
 297        int err = 0;
 298        struct path realpath;
 299        enum ovl_path_type type;
 300
 301        type = ovl_path_real(dentry, &realpath);
 302        if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) {
 303                err = ovl_want_write(dentry);
 304                if (!err) {
 305                        if (file_flags & O_TRUNC)
 306                                err = ovl_copy_up_truncate(dentry);
 307                        else
 308                                err = ovl_copy_up(dentry);
 309                        ovl_drop_write(dentry);
 310                }
 311        }
 312
 313        return err;
 314}
 315
 316int ovl_update_time(struct inode *inode, struct timespec *ts, int flags)
 317{
 318        struct dentry *alias;
 319        struct path upperpath;
 320
 321        if (!(flags & S_ATIME))
 322                return 0;
 323
 324        alias = d_find_any_alias(inode);
 325        if (!alias)
 326                return 0;
 327
 328        ovl_path_upper(alias, &upperpath);
 329        if (upperpath.dentry) {
 330                touch_atime(&upperpath);
 331                inode->i_atime = d_inode(upperpath.dentry)->i_atime;
 332        }
 333
 334        dput(alias);
 335
 336        return 0;
 337}
 338
 339static const struct inode_operations ovl_file_inode_operations = {
 340        .setattr        = ovl_setattr,
 341        .permission     = ovl_permission,
 342        .getattr        = ovl_getattr,
 343        .listxattr      = ovl_listxattr,
 344        .get_acl        = ovl_get_acl,
 345        .update_time    = ovl_update_time,
 346};
 347
 348static const struct inode_operations ovl_symlink_inode_operations = {
 349        .setattr        = ovl_setattr,
 350        .get_link       = ovl_get_link,
 351        .readlink       = generic_readlink,
 352        .getattr        = ovl_getattr,
 353        .listxattr      = ovl_listxattr,
 354        .update_time    = ovl_update_time,
 355};
 356
 357static void ovl_fill_inode(struct inode *inode, umode_t mode)
 358{
 359        inode->i_ino = get_next_ino();
 360        inode->i_mode = mode;
 361        inode->i_flags |= S_NOCMTIME;
 362#ifdef CONFIG_FS_POSIX_ACL
 363        inode->i_acl = inode->i_default_acl = ACL_DONT_CACHE;
 364#endif
 365
 366        mode &= S_IFMT;
 367        switch (mode) {
 368        case S_IFDIR:
 369                inode->i_op = &ovl_dir_inode_operations;
 370                inode->i_fop = &ovl_dir_operations;
 371                break;
 372
 373        case S_IFLNK:
 374                inode->i_op = &ovl_symlink_inode_operations;
 375                break;
 376
 377        default:
 378                WARN(1, "illegal file type: %i\n", mode);
 379                /* Fall through */
 380
 381        case S_IFREG:
 382        case S_IFSOCK:
 383        case S_IFBLK:
 384        case S_IFCHR:
 385        case S_IFIFO:
 386                inode->i_op = &ovl_file_inode_operations;
 387                break;
 388        }
 389}
 390
 391struct inode *ovl_new_inode(struct super_block *sb, umode_t mode)
 392{
 393        struct inode *inode;
 394
 395        inode = new_inode(sb);
 396        if (inode)
 397                ovl_fill_inode(inode, mode);
 398
 399        return inode;
 400}
 401
 402static int ovl_inode_test(struct inode *inode, void *data)
 403{
 404        return ovl_inode_real(inode, NULL) == data;
 405}
 406
 407static int ovl_inode_set(struct inode *inode, void *data)
 408{
 409        inode->i_private = (void *) (((unsigned long) data) | OVL_ISUPPER_MASK);
 410        return 0;
 411}
 412
 413struct inode *ovl_get_inode(struct super_block *sb, struct inode *realinode)
 414
 415{
 416        struct inode *inode;
 417
 418        inode = iget5_locked(sb, (unsigned long) realinode,
 419                             ovl_inode_test, ovl_inode_set, realinode);
 420        if (inode && inode->i_state & I_NEW) {
 421                ovl_fill_inode(inode, realinode->i_mode);
 422                set_nlink(inode, realinode->i_nlink);
 423                unlock_new_inode(inode);
 424        }
 425
 426        return inode;
 427}
 428