1bbb1e54dSMiklos Szeredi /* 2bbb1e54dSMiklos Szeredi * Copyright (C) 2011 Novell Inc. 3bbb1e54dSMiklos Szeredi * Copyright (C) 2016 Red Hat, Inc. 4bbb1e54dSMiklos Szeredi * 5bbb1e54dSMiklos Szeredi * This program is free software; you can redistribute it and/or modify it 6bbb1e54dSMiklos Szeredi * under the terms of the GNU General Public License version 2 as published by 7bbb1e54dSMiklos Szeredi * the Free Software Foundation. 8bbb1e54dSMiklos Szeredi */ 9bbb1e54dSMiklos Szeredi 10bbb1e54dSMiklos Szeredi #include <linux/fs.h> 11bbb1e54dSMiklos Szeredi #include <linux/namei.h> 12bbb1e54dSMiklos Szeredi #include <linux/xattr.h> 13bbb1e54dSMiklos Szeredi #include "overlayfs.h" 14bbb1e54dSMiklos Szeredi #include "ovl_entry.h" 15bbb1e54dSMiklos Szeredi 16*e28edc46SMiklos Szeredi struct ovl_lookup_data { 17*e28edc46SMiklos Szeredi struct qstr name; 18*e28edc46SMiklos Szeredi bool is_dir; 19*e28edc46SMiklos Szeredi bool opaque; 20*e28edc46SMiklos Szeredi bool stop; 21*e28edc46SMiklos Szeredi bool last; 22*e28edc46SMiklos Szeredi }; 23bbb1e54dSMiklos Szeredi 24bbb1e54dSMiklos Szeredi static bool ovl_is_opaquedir(struct dentry *dentry) 25bbb1e54dSMiklos Szeredi { 26bbb1e54dSMiklos Szeredi int res; 27bbb1e54dSMiklos Szeredi char val; 28bbb1e54dSMiklos Szeredi 29bbb1e54dSMiklos Szeredi if (!d_is_dir(dentry)) 30bbb1e54dSMiklos Szeredi return false; 31bbb1e54dSMiklos Szeredi 32bbb1e54dSMiklos Szeredi res = vfs_getxattr(dentry, OVL_XATTR_OPAQUE, &val, 1); 33bbb1e54dSMiklos Szeredi if (res == 1 && val == 'y') 34bbb1e54dSMiklos Szeredi return true; 35bbb1e54dSMiklos Szeredi 36bbb1e54dSMiklos Szeredi return false; 37bbb1e54dSMiklos Szeredi } 38bbb1e54dSMiklos Szeredi 39*e28edc46SMiklos Szeredi static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d, 40*e28edc46SMiklos Szeredi const char *name, unsigned int namelen, 41*e28edc46SMiklos Szeredi struct dentry **ret) 42*e28edc46SMiklos Szeredi { 43*e28edc46SMiklos Szeredi struct dentry *this; 44*e28edc46SMiklos Szeredi int err; 45*e28edc46SMiklos Szeredi 46*e28edc46SMiklos Szeredi this = lookup_one_len_unlocked(name, base, namelen); 47*e28edc46SMiklos Szeredi if (IS_ERR(this)) { 48*e28edc46SMiklos Szeredi err = PTR_ERR(this); 49*e28edc46SMiklos Szeredi this = NULL; 50*e28edc46SMiklos Szeredi if (err == -ENOENT || err == -ENAMETOOLONG) 51*e28edc46SMiklos Szeredi goto out; 52*e28edc46SMiklos Szeredi goto out_err; 53*e28edc46SMiklos Szeredi } 54*e28edc46SMiklos Szeredi if (!this->d_inode) 55*e28edc46SMiklos Szeredi goto put_and_out; 56*e28edc46SMiklos Szeredi 57*e28edc46SMiklos Szeredi if (ovl_dentry_weird(this)) { 58*e28edc46SMiklos Szeredi /* Don't support traversing automounts and other weirdness */ 59*e28edc46SMiklos Szeredi err = -EREMOTE; 60*e28edc46SMiklos Szeredi goto out_err; 61*e28edc46SMiklos Szeredi } 62*e28edc46SMiklos Szeredi if (ovl_is_whiteout(this)) { 63*e28edc46SMiklos Szeredi d->stop = d->opaque = true; 64*e28edc46SMiklos Szeredi goto put_and_out; 65*e28edc46SMiklos Szeredi } 66*e28edc46SMiklos Szeredi if (!d_can_lookup(this)) { 67*e28edc46SMiklos Szeredi d->stop = true; 68*e28edc46SMiklos Szeredi if (d->is_dir) 69*e28edc46SMiklos Szeredi goto put_and_out; 70*e28edc46SMiklos Szeredi goto out; 71*e28edc46SMiklos Szeredi } 72*e28edc46SMiklos Szeredi d->is_dir = true; 73*e28edc46SMiklos Szeredi if (!d->last && ovl_is_opaquedir(this)) { 74*e28edc46SMiklos Szeredi d->stop = d->opaque = true; 75*e28edc46SMiklos Szeredi goto out; 76*e28edc46SMiklos Szeredi } 77*e28edc46SMiklos Szeredi out: 78*e28edc46SMiklos Szeredi *ret = this; 79*e28edc46SMiklos Szeredi return 0; 80*e28edc46SMiklos Szeredi 81*e28edc46SMiklos Szeredi put_and_out: 82*e28edc46SMiklos Szeredi dput(this); 83*e28edc46SMiklos Szeredi this = NULL; 84*e28edc46SMiklos Szeredi goto out; 85*e28edc46SMiklos Szeredi 86*e28edc46SMiklos Szeredi out_err: 87*e28edc46SMiklos Szeredi dput(this); 88*e28edc46SMiklos Szeredi return err; 89*e28edc46SMiklos Szeredi } 90*e28edc46SMiklos Szeredi 91*e28edc46SMiklos Szeredi static int ovl_lookup_layer(struct dentry *base, struct ovl_lookup_data *d, 92*e28edc46SMiklos Szeredi struct dentry **ret) 93*e28edc46SMiklos Szeredi { 94*e28edc46SMiklos Szeredi return ovl_lookup_single(base, d, d->name.name, d->name.len, ret); 95*e28edc46SMiklos Szeredi } 96*e28edc46SMiklos Szeredi 97bbb1e54dSMiklos Szeredi /* 98bbb1e54dSMiklos Szeredi * Returns next layer in stack starting from top. 99bbb1e54dSMiklos Szeredi * Returns -1 if this is the last layer. 100bbb1e54dSMiklos Szeredi */ 101bbb1e54dSMiklos Szeredi int ovl_path_next(int idx, struct dentry *dentry, struct path *path) 102bbb1e54dSMiklos Szeredi { 103bbb1e54dSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 104bbb1e54dSMiklos Szeredi 105bbb1e54dSMiklos Szeredi BUG_ON(idx < 0); 106bbb1e54dSMiklos Szeredi if (idx == 0) { 107bbb1e54dSMiklos Szeredi ovl_path_upper(dentry, path); 108bbb1e54dSMiklos Szeredi if (path->dentry) 109bbb1e54dSMiklos Szeredi return oe->numlower ? 1 : -1; 110bbb1e54dSMiklos Szeredi idx++; 111bbb1e54dSMiklos Szeredi } 112bbb1e54dSMiklos Szeredi BUG_ON(idx > oe->numlower); 113bbb1e54dSMiklos Szeredi *path = oe->lowerstack[idx - 1]; 114bbb1e54dSMiklos Szeredi 115bbb1e54dSMiklos Szeredi return (idx < oe->numlower) ? idx + 1 : -1; 116bbb1e54dSMiklos Szeredi } 117bbb1e54dSMiklos Szeredi 118bbb1e54dSMiklos Szeredi struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, 119bbb1e54dSMiklos Szeredi unsigned int flags) 120bbb1e54dSMiklos Szeredi { 121bbb1e54dSMiklos Szeredi struct ovl_entry *oe; 122bbb1e54dSMiklos Szeredi const struct cred *old_cred; 1236b2d5fe4SMiklos Szeredi struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 124bbb1e54dSMiklos Szeredi struct ovl_entry *poe = dentry->d_parent->d_fsdata; 125bbb1e54dSMiklos Szeredi struct path *stack = NULL; 126bbb1e54dSMiklos Szeredi struct dentry *upperdir, *upperdentry = NULL; 127bbb1e54dSMiklos Szeredi unsigned int ctr = 0; 128bbb1e54dSMiklos Szeredi struct inode *inode = NULL; 129bbb1e54dSMiklos Szeredi bool upperopaque = false; 130bbb1e54dSMiklos Szeredi struct dentry *this; 131bbb1e54dSMiklos Szeredi unsigned int i; 132bbb1e54dSMiklos Szeredi int err; 133*e28edc46SMiklos Szeredi struct ovl_lookup_data d = { 134*e28edc46SMiklos Szeredi .name = dentry->d_name, 135*e28edc46SMiklos Szeredi .is_dir = false, 136*e28edc46SMiklos Szeredi .opaque = false, 137*e28edc46SMiklos Szeredi .stop = false, 138*e28edc46SMiklos Szeredi .last = !poe->numlower, 139*e28edc46SMiklos Szeredi }; 140bbb1e54dSMiklos Szeredi 1416b2d5fe4SMiklos Szeredi if (dentry->d_name.len > ofs->namelen) 1426b2d5fe4SMiklos Szeredi return ERR_PTR(-ENAMETOOLONG); 1436b2d5fe4SMiklos Szeredi 144bbb1e54dSMiklos Szeredi old_cred = ovl_override_creds(dentry->d_sb); 145bbb1e54dSMiklos Szeredi upperdir = ovl_upperdentry_dereference(poe); 146bbb1e54dSMiklos Szeredi if (upperdir) { 147*e28edc46SMiklos Szeredi err = ovl_lookup_layer(upperdir, &d, &upperdentry); 148*e28edc46SMiklos Szeredi if (err) 149bbb1e54dSMiklos Szeredi goto out; 150bbb1e54dSMiklos Szeredi 151*e28edc46SMiklos Szeredi if (upperdentry && unlikely(ovl_dentry_remote(upperdentry))) { 152*e28edc46SMiklos Szeredi dput(upperdentry); 153bbb1e54dSMiklos Szeredi err = -EREMOTE; 154bbb1e54dSMiklos Szeredi goto out; 155bbb1e54dSMiklos Szeredi } 156*e28edc46SMiklos Szeredi upperopaque = d.opaque; 157bbb1e54dSMiklos Szeredi } 158bbb1e54dSMiklos Szeredi 159*e28edc46SMiklos Szeredi if (!d.stop && poe->numlower) { 160bbb1e54dSMiklos Szeredi err = -ENOMEM; 161*e28edc46SMiklos Szeredi stack = kcalloc(poe->numlower, sizeof(struct path), 162*e28edc46SMiklos Szeredi GFP_TEMPORARY); 163bbb1e54dSMiklos Szeredi if (!stack) 164bbb1e54dSMiklos Szeredi goto out_put_upper; 165bbb1e54dSMiklos Szeredi } 166bbb1e54dSMiklos Szeredi 167*e28edc46SMiklos Szeredi for (i = 0; !d.stop && i < poe->numlower; i++) { 168bbb1e54dSMiklos Szeredi struct path lowerpath = poe->lowerstack[i]; 169bbb1e54dSMiklos Szeredi 170*e28edc46SMiklos Szeredi d.last = i == poe->numlower - 1; 171*e28edc46SMiklos Szeredi err = ovl_lookup_layer(lowerpath.dentry, &d, &this); 172*e28edc46SMiklos Szeredi if (err) 173bbb1e54dSMiklos Szeredi goto out_put; 1746b2d5fe4SMiklos Szeredi 175bbb1e54dSMiklos Szeredi if (!this) 176bbb1e54dSMiklos Szeredi continue; 177bbb1e54dSMiklos Szeredi 178bbb1e54dSMiklos Szeredi stack[ctr].dentry = this; 179bbb1e54dSMiklos Szeredi stack[ctr].mnt = lowerpath.mnt; 180bbb1e54dSMiklos Szeredi ctr++; 181bbb1e54dSMiklos Szeredi } 182bbb1e54dSMiklos Szeredi 183bbb1e54dSMiklos Szeredi oe = ovl_alloc_entry(ctr); 184bbb1e54dSMiklos Szeredi err = -ENOMEM; 185bbb1e54dSMiklos Szeredi if (!oe) 186bbb1e54dSMiklos Szeredi goto out_put; 187bbb1e54dSMiklos Szeredi 188bbb1e54dSMiklos Szeredi if (upperdentry || ctr) { 189bbb1e54dSMiklos Szeredi struct dentry *realdentry; 190bbb1e54dSMiklos Szeredi struct inode *realinode; 191bbb1e54dSMiklos Szeredi 192bbb1e54dSMiklos Szeredi realdentry = upperdentry ? upperdentry : stack[0].dentry; 193bbb1e54dSMiklos Szeredi realinode = d_inode(realdentry); 194bbb1e54dSMiklos Szeredi 195bbb1e54dSMiklos Szeredi err = -ENOMEM; 196bbb1e54dSMiklos Szeredi if (upperdentry && !d_is_dir(upperdentry)) { 197bbb1e54dSMiklos Szeredi inode = ovl_get_inode(dentry->d_sb, realinode); 198bbb1e54dSMiklos Szeredi } else { 199bbb1e54dSMiklos Szeredi inode = ovl_new_inode(dentry->d_sb, realinode->i_mode, 200bbb1e54dSMiklos Szeredi realinode->i_rdev); 201bbb1e54dSMiklos Szeredi if (inode) 202bbb1e54dSMiklos Szeredi ovl_inode_init(inode, realinode, !!upperdentry); 203bbb1e54dSMiklos Szeredi } 204bbb1e54dSMiklos Szeredi if (!inode) 205bbb1e54dSMiklos Szeredi goto out_free_oe; 206bbb1e54dSMiklos Szeredi ovl_copyattr(realdentry->d_inode, inode); 207bbb1e54dSMiklos Szeredi } 208bbb1e54dSMiklos Szeredi 209bbb1e54dSMiklos Szeredi revert_creds(old_cred); 210bbb1e54dSMiklos Szeredi oe->opaque = upperopaque; 211bbb1e54dSMiklos Szeredi oe->__upperdentry = upperdentry; 212bbb1e54dSMiklos Szeredi memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr); 213bbb1e54dSMiklos Szeredi kfree(stack); 214bbb1e54dSMiklos Szeredi dentry->d_fsdata = oe; 215bbb1e54dSMiklos Szeredi d_add(dentry, inode); 216bbb1e54dSMiklos Szeredi 217bbb1e54dSMiklos Szeredi return NULL; 218bbb1e54dSMiklos Szeredi 219bbb1e54dSMiklos Szeredi out_free_oe: 220bbb1e54dSMiklos Szeredi kfree(oe); 221bbb1e54dSMiklos Szeredi out_put: 222bbb1e54dSMiklos Szeredi for (i = 0; i < ctr; i++) 223bbb1e54dSMiklos Szeredi dput(stack[i].dentry); 224bbb1e54dSMiklos Szeredi kfree(stack); 225bbb1e54dSMiklos Szeredi out_put_upper: 226bbb1e54dSMiklos Szeredi dput(upperdentry); 227bbb1e54dSMiklos Szeredi out: 228bbb1e54dSMiklos Szeredi revert_creds(old_cred); 229bbb1e54dSMiklos Szeredi return ERR_PTR(err); 230bbb1e54dSMiklos Szeredi } 231bbb1e54dSMiklos Szeredi 232bbb1e54dSMiklos Szeredi bool ovl_lower_positive(struct dentry *dentry) 233bbb1e54dSMiklos Szeredi { 234bbb1e54dSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 235bbb1e54dSMiklos Szeredi struct ovl_entry *poe = dentry->d_parent->d_fsdata; 236bbb1e54dSMiklos Szeredi const struct qstr *name = &dentry->d_name; 237bbb1e54dSMiklos Szeredi unsigned int i; 238bbb1e54dSMiklos Szeredi bool positive = false; 239bbb1e54dSMiklos Szeredi bool done = false; 240bbb1e54dSMiklos Szeredi 241bbb1e54dSMiklos Szeredi /* 242bbb1e54dSMiklos Szeredi * If dentry is negative, then lower is positive iff this is a 243bbb1e54dSMiklos Szeredi * whiteout. 244bbb1e54dSMiklos Szeredi */ 245bbb1e54dSMiklos Szeredi if (!dentry->d_inode) 246bbb1e54dSMiklos Szeredi return oe->opaque; 247bbb1e54dSMiklos Szeredi 248bbb1e54dSMiklos Szeredi /* Negative upper -> positive lower */ 249bbb1e54dSMiklos Szeredi if (!oe->__upperdentry) 250bbb1e54dSMiklos Szeredi return true; 251bbb1e54dSMiklos Szeredi 252bbb1e54dSMiklos Szeredi /* Positive upper -> have to look up lower to see whether it exists */ 253bbb1e54dSMiklos Szeredi for (i = 0; !done && !positive && i < poe->numlower; i++) { 254bbb1e54dSMiklos Szeredi struct dentry *this; 255bbb1e54dSMiklos Szeredi struct dentry *lowerdir = poe->lowerstack[i].dentry; 256bbb1e54dSMiklos Szeredi 257bbb1e54dSMiklos Szeredi this = lookup_one_len_unlocked(name->name, lowerdir, 258bbb1e54dSMiklos Szeredi name->len); 259bbb1e54dSMiklos Szeredi if (IS_ERR(this)) { 260bbb1e54dSMiklos Szeredi switch (PTR_ERR(this)) { 261bbb1e54dSMiklos Szeredi case -ENOENT: 262bbb1e54dSMiklos Szeredi case -ENAMETOOLONG: 263bbb1e54dSMiklos Szeredi break; 264bbb1e54dSMiklos Szeredi 265bbb1e54dSMiklos Szeredi default: 266bbb1e54dSMiklos Szeredi /* 267bbb1e54dSMiklos Szeredi * Assume something is there, we just couldn't 268bbb1e54dSMiklos Szeredi * access it. 269bbb1e54dSMiklos Szeredi */ 270bbb1e54dSMiklos Szeredi positive = true; 271bbb1e54dSMiklos Szeredi break; 272bbb1e54dSMiklos Szeredi } 273bbb1e54dSMiklos Szeredi } else { 274bbb1e54dSMiklos Szeredi if (this->d_inode) { 275bbb1e54dSMiklos Szeredi positive = !ovl_is_whiteout(this); 276bbb1e54dSMiklos Szeredi done = true; 277bbb1e54dSMiklos Szeredi } 278bbb1e54dSMiklos Szeredi dput(this); 279bbb1e54dSMiklos Szeredi } 280bbb1e54dSMiklos Szeredi } 281bbb1e54dSMiklos Szeredi 282bbb1e54dSMiklos Szeredi return positive; 283bbb1e54dSMiklos Szeredi } 284