]> git.karo-electronics.de Git - karo-tx-linux.git/blob - fs/overlayfs/namei.c
Merge tag 'hwmon-for-linus-v4.11' of git://git.kernel.org/pub/scm/linux/kernel/git...
[karo-tx-linux.git] / fs / overlayfs / namei.c
1 /*
2  * Copyright (C) 2011 Novell Inc.
3  * Copyright (C) 2016 Red Hat, 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/namei.h>
12 #include <linux/xattr.h>
13 #include <linux/ratelimit.h>
14 #include "overlayfs.h"
15 #include "ovl_entry.h"
16
17 struct ovl_lookup_data {
18         struct qstr name;
19         bool is_dir;
20         bool opaque;
21         bool stop;
22         bool last;
23         char *redirect;
24 };
25
26 static int ovl_check_redirect(struct dentry *dentry, struct ovl_lookup_data *d,
27                               size_t prelen, const char *post)
28 {
29         int res;
30         char *s, *next, *buf = NULL;
31
32         res = vfs_getxattr(dentry, OVL_XATTR_REDIRECT, NULL, 0);
33         if (res < 0) {
34                 if (res == -ENODATA || res == -EOPNOTSUPP)
35                         return 0;
36                 goto fail;
37         }
38         buf = kzalloc(prelen + res + strlen(post) + 1, GFP_TEMPORARY);
39         if (!buf)
40                 return -ENOMEM;
41
42         if (res == 0)
43                 goto invalid;
44
45         res = vfs_getxattr(dentry, OVL_XATTR_REDIRECT, buf, res);
46         if (res < 0)
47                 goto fail;
48         if (res == 0)
49                 goto invalid;
50         if (buf[0] == '/') {
51                 for (s = buf; *s++ == '/'; s = next) {
52                         next = strchrnul(s, '/');
53                         if (s == next)
54                                 goto invalid;
55                 }
56         } else {
57                 if (strchr(buf, '/') != NULL)
58                         goto invalid;
59
60                 memmove(buf + prelen, buf, res);
61                 memcpy(buf, d->name.name, prelen);
62         }
63
64         strcat(buf, post);
65         kfree(d->redirect);
66         d->redirect = buf;
67         d->name.name = d->redirect;
68         d->name.len = strlen(d->redirect);
69
70         return 0;
71
72 err_free:
73         kfree(buf);
74         return 0;
75 fail:
76         pr_warn_ratelimited("overlayfs: failed to get redirect (%i)\n", res);
77         goto err_free;
78 invalid:
79         pr_warn_ratelimited("overlayfs: invalid redirect (%s)\n", buf);
80         goto err_free;
81 }
82
83 static bool ovl_is_opaquedir(struct dentry *dentry)
84 {
85         int res;
86         char val;
87
88         if (!d_is_dir(dentry))
89                 return false;
90
91         res = vfs_getxattr(dentry, OVL_XATTR_OPAQUE, &val, 1);
92         if (res == 1 && val == 'y')
93                 return true;
94
95         return false;
96 }
97
98 static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
99                              const char *name, unsigned int namelen,
100                              size_t prelen, const char *post,
101                              struct dentry **ret)
102 {
103         struct dentry *this;
104         int err;
105
106         this = lookup_one_len_unlocked(name, base, namelen);
107         if (IS_ERR(this)) {
108                 err = PTR_ERR(this);
109                 this = NULL;
110                 if (err == -ENOENT || err == -ENAMETOOLONG)
111                         goto out;
112                 goto out_err;
113         }
114         if (!this->d_inode)
115                 goto put_and_out;
116
117         if (ovl_dentry_weird(this)) {
118                 /* Don't support traversing automounts and other weirdness */
119                 err = -EREMOTE;
120                 goto out_err;
121         }
122         if (ovl_is_whiteout(this)) {
123                 d->stop = d->opaque = true;
124                 goto put_and_out;
125         }
126         if (!d_can_lookup(this)) {
127                 d->stop = true;
128                 if (d->is_dir)
129                         goto put_and_out;
130                 goto out;
131         }
132         d->is_dir = true;
133         if (!d->last && ovl_is_opaquedir(this)) {
134                 d->stop = d->opaque = true;
135                 goto out;
136         }
137         err = ovl_check_redirect(this, d, prelen, post);
138         if (err)
139                 goto out_err;
140 out:
141         *ret = this;
142         return 0;
143
144 put_and_out:
145         dput(this);
146         this = NULL;
147         goto out;
148
149 out_err:
150         dput(this);
151         return err;
152 }
153
154 static int ovl_lookup_layer(struct dentry *base, struct ovl_lookup_data *d,
155                             struct dentry **ret)
156 {
157         /* Counting down from the end, since the prefix can change */
158         size_t rem = d->name.len - 1;
159         struct dentry *dentry = NULL;
160         int err;
161
162         if (d->name.name[0] != '/')
163                 return ovl_lookup_single(base, d, d->name.name, d->name.len,
164                                          0, "", ret);
165
166         while (!IS_ERR_OR_NULL(base) && d_can_lookup(base)) {
167                 const char *s = d->name.name + d->name.len - rem;
168                 const char *next = strchrnul(s, '/');
169                 size_t thislen = next - s;
170                 bool end = !next[0];
171
172                 /* Verify we did not go off the rails */
173                 if (WARN_ON(s[-1] != '/'))
174                         return -EIO;
175
176                 err = ovl_lookup_single(base, d, s, thislen,
177                                         d->name.len - rem, next, &base);
178                 dput(dentry);
179                 if (err)
180                         return err;
181                 dentry = base;
182                 if (end)
183                         break;
184
185                 rem -= thislen + 1;
186
187                 if (WARN_ON(rem >= d->name.len))
188                         return -EIO;
189         }
190         *ret = dentry;
191         return 0;
192 }
193
194 /*
195  * Returns next layer in stack starting from top.
196  * Returns -1 if this is the last layer.
197  */
198 int ovl_path_next(int idx, struct dentry *dentry, struct path *path)
199 {
200         struct ovl_entry *oe = dentry->d_fsdata;
201
202         BUG_ON(idx < 0);
203         if (idx == 0) {
204                 ovl_path_upper(dentry, path);
205                 if (path->dentry)
206                         return oe->numlower ? 1 : -1;
207                 idx++;
208         }
209         BUG_ON(idx > oe->numlower);
210         *path = oe->lowerstack[idx - 1];
211
212         return (idx < oe->numlower) ? idx + 1 : -1;
213 }
214
215 struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
216                           unsigned int flags)
217 {
218         struct ovl_entry *oe;
219         const struct cred *old_cred;
220         struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
221         struct ovl_entry *poe = dentry->d_parent->d_fsdata;
222         struct path *stack = NULL;
223         struct dentry *upperdir, *upperdentry = NULL;
224         unsigned int ctr = 0;
225         struct inode *inode = NULL;
226         bool upperopaque = false;
227         char *upperredirect = NULL;
228         struct dentry *this;
229         unsigned int i;
230         int err;
231         struct ovl_lookup_data d = {
232                 .name = dentry->d_name,
233                 .is_dir = false,
234                 .opaque = false,
235                 .stop = false,
236                 .last = !poe->numlower,
237                 .redirect = NULL,
238         };
239
240         if (dentry->d_name.len > ofs->namelen)
241                 return ERR_PTR(-ENAMETOOLONG);
242
243         old_cred = ovl_override_creds(dentry->d_sb);
244         upperdir = ovl_upperdentry_dereference(poe);
245         if (upperdir) {
246                 err = ovl_lookup_layer(upperdir, &d, &upperdentry);
247                 if (err)
248                         goto out;
249
250                 if (upperdentry && unlikely(ovl_dentry_remote(upperdentry))) {
251                         dput(upperdentry);
252                         err = -EREMOTE;
253                         goto out;
254                 }
255
256                 if (d.redirect) {
257                         upperredirect = kstrdup(d.redirect, GFP_KERNEL);
258                         if (!upperredirect)
259                                 goto out_put_upper;
260                         if (d.redirect[0] == '/')
261                                 poe = dentry->d_sb->s_root->d_fsdata;
262                 }
263                 upperopaque = d.opaque;
264         }
265
266         if (!d.stop && poe->numlower) {
267                 err = -ENOMEM;
268                 stack = kcalloc(ofs->numlower, sizeof(struct path),
269                                 GFP_TEMPORARY);
270                 if (!stack)
271                         goto out_put_upper;
272         }
273
274         for (i = 0; !d.stop && i < poe->numlower; i++) {
275                 struct path lowerpath = poe->lowerstack[i];
276
277                 d.last = i == poe->numlower - 1;
278                 err = ovl_lookup_layer(lowerpath.dentry, &d, &this);
279                 if (err)
280                         goto out_put;
281
282                 if (!this)
283                         continue;
284
285                 stack[ctr].dentry = this;
286                 stack[ctr].mnt = lowerpath.mnt;
287                 ctr++;
288
289                 if (d.stop)
290                         break;
291
292                 if (d.redirect &&
293                     d.redirect[0] == '/' &&
294                     poe != dentry->d_sb->s_root->d_fsdata) {
295                         poe = dentry->d_sb->s_root->d_fsdata;
296
297                         /* Find the current layer on the root dentry */
298                         for (i = 0; i < poe->numlower; i++)
299                                 if (poe->lowerstack[i].mnt == lowerpath.mnt)
300                                         break;
301                         if (WARN_ON(i == poe->numlower))
302                                 break;
303                 }
304         }
305
306         oe = ovl_alloc_entry(ctr);
307         err = -ENOMEM;
308         if (!oe)
309                 goto out_put;
310
311         if (upperdentry || ctr) {
312                 struct dentry *realdentry;
313                 struct inode *realinode;
314
315                 realdentry = upperdentry ? upperdentry : stack[0].dentry;
316                 realinode = d_inode(realdentry);
317
318                 err = -ENOMEM;
319                 if (upperdentry && !d_is_dir(upperdentry)) {
320                         inode = ovl_get_inode(dentry->d_sb, realinode);
321                 } else {
322                         inode = ovl_new_inode(dentry->d_sb, realinode->i_mode,
323                                               realinode->i_rdev);
324                         if (inode)
325                                 ovl_inode_init(inode, realinode, !!upperdentry);
326                 }
327                 if (!inode)
328                         goto out_free_oe;
329                 ovl_copyattr(realdentry->d_inode, inode);
330         }
331
332         revert_creds(old_cred);
333         oe->opaque = upperopaque;
334         oe->redirect = upperredirect;
335         oe->__upperdentry = upperdentry;
336         memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr);
337         kfree(stack);
338         kfree(d.redirect);
339         dentry->d_fsdata = oe;
340         d_add(dentry, inode);
341
342         return NULL;
343
344 out_free_oe:
345         kfree(oe);
346 out_put:
347         for (i = 0; i < ctr; i++)
348                 dput(stack[i].dentry);
349         kfree(stack);
350 out_put_upper:
351         dput(upperdentry);
352         kfree(upperredirect);
353 out:
354         kfree(d.redirect);
355         revert_creds(old_cred);
356         return ERR_PTR(err);
357 }
358
359 bool ovl_lower_positive(struct dentry *dentry)
360 {
361         struct ovl_entry *oe = dentry->d_fsdata;
362         struct ovl_entry *poe = dentry->d_parent->d_fsdata;
363         const struct qstr *name = &dentry->d_name;
364         unsigned int i;
365         bool positive = false;
366         bool done = false;
367
368         /*
369          * If dentry is negative, then lower is positive iff this is a
370          * whiteout.
371          */
372         if (!dentry->d_inode)
373                 return oe->opaque;
374
375         /* Negative upper -> positive lower */
376         if (!oe->__upperdentry)
377                 return true;
378
379         /* Positive upper -> have to look up lower to see whether it exists */
380         for (i = 0; !done && !positive && i < poe->numlower; i++) {
381                 struct dentry *this;
382                 struct dentry *lowerdir = poe->lowerstack[i].dentry;
383
384                 this = lookup_one_len_unlocked(name->name, lowerdir,
385                                                name->len);
386                 if (IS_ERR(this)) {
387                         switch (PTR_ERR(this)) {
388                         case -ENOENT:
389                         case -ENAMETOOLONG:
390                                 break;
391
392                         default:
393                                 /*
394                                  * Assume something is there, we just couldn't
395                                  * access it.
396                                  */
397                                 positive = true;
398                                 break;
399                         }
400                 } else {
401                         if (this->d_inode) {
402                                 positive = !ovl_is_whiteout(this);
403                                 done = true;
404                         }
405                         dput(this);
406                 }
407         }
408
409         return positive;
410 }