ovl: modify layer parameter parsing
[linux-2.6-microblaze.git] / fs / overlayfs / params.c
1 // SPDX-License-Identifier: GPL-2.0-only
2
3 #include <linux/fs.h>
4 #include <linux/namei.h>
5 #include <linux/fs_context.h>
6 #include <linux/fs_parser.h>
7 #include <linux/posix_acl_xattr.h>
8 #include <linux/xattr.h>
9 #include "overlayfs.h"
10
11 static ssize_t ovl_parse_param_split_lowerdirs(char *str)
12 {
13         ssize_t nr_layers = 1, nr_colons = 0;
14         char *s, *d;
15
16         for (s = d = str;; s++, d++) {
17                 if (*s == '\\') {
18                         s++;
19                 } else if (*s == ':') {
20                         bool next_colon = (*(s + 1) == ':');
21
22                         nr_colons++;
23                         if (nr_colons == 2 && next_colon) {
24                                 pr_err("only single ':' or double '::' sequences of unescaped colons in lowerdir mount option allowed.\n");
25                                 return -EINVAL;
26                         }
27                         /* count layers, not colons */
28                         if (!next_colon)
29                                 nr_layers++;
30
31                         *d = '\0';
32                         continue;
33                 }
34
35                 *d = *s;
36                 if (!*s) {
37                         /* trailing colons */
38                         if (nr_colons) {
39                                 pr_err("unescaped trailing colons in lowerdir mount option.\n");
40                                 return -EINVAL;
41                         }
42                         break;
43                 }
44                 nr_colons = 0;
45         }
46
47         return nr_layers;
48 }
49
50 static int ovl_mount_dir_noesc(const char *name, struct path *path)
51 {
52         int err = -EINVAL;
53
54         if (!*name) {
55                 pr_err("empty lowerdir\n");
56                 goto out;
57         }
58         err = kern_path(name, LOOKUP_FOLLOW, path);
59         if (err) {
60                 pr_err("failed to resolve '%s': %i\n", name, err);
61                 goto out;
62         }
63         err = -EINVAL;
64         if (ovl_dentry_weird(path->dentry)) {
65                 pr_err("filesystem on '%s' not supported\n", name);
66                 goto out_put;
67         }
68         if (!d_is_dir(path->dentry)) {
69                 pr_err("'%s' not a directory\n", name);
70                 goto out_put;
71         }
72         return 0;
73
74 out_put:
75         path_put_init(path);
76 out:
77         return err;
78 }
79
80 static void ovl_unescape(char *s)
81 {
82         char *d = s;
83
84         for (;; s++, d++) {
85                 if (*s == '\\')
86                         s++;
87                 *d = *s;
88                 if (!*s)
89                         break;
90         }
91 }
92
93 static int ovl_mount_dir(const char *name, struct path *path)
94 {
95         int err = -ENOMEM;
96         char *tmp = kstrdup(name, GFP_KERNEL);
97
98         if (tmp) {
99                 ovl_unescape(tmp);
100                 err = ovl_mount_dir_noesc(tmp, path);
101
102                 if (!err && path->dentry->d_flags & DCACHE_OP_REAL) {
103                         pr_err("filesystem on '%s' not supported as upperdir\n",
104                                tmp);
105                         path_put_init(path);
106                         err = -EINVAL;
107                 }
108                 kfree(tmp);
109         }
110         return err;
111 }
112
113 int ovl_parse_param_upperdir(const char *name, struct fs_context *fc,
114                              bool workdir)
115 {
116         int err;
117         struct ovl_fs *ofs = fc->s_fs_info;
118         struct ovl_config *config = &ofs->config;
119         struct ovl_fs_context *ctx = fc->fs_private;
120         struct path path;
121         char *dup;
122
123         err = ovl_mount_dir(name, &path);
124         if (err)
125                 return err;
126
127         /*
128          * Check whether upper path is read-only here to report failures
129          * early. Don't forget to recheck when the superblock is created
130          * as the mount attributes could change.
131          */
132         if (__mnt_is_readonly(path.mnt)) {
133                 path_put(&path);
134                 return -EINVAL;
135         }
136
137         dup = kstrdup(name, GFP_KERNEL);
138         if (!dup) {
139                 path_put(&path);
140                 return -ENOMEM;
141         }
142
143         if (workdir) {
144                 kfree(config->workdir);
145                 config->workdir = dup;
146                 path_put(&ctx->work);
147                 ctx->work = path;
148         } else {
149                 kfree(config->upperdir);
150                 config->upperdir = dup;
151                 path_put(&ctx->upper);
152                 ctx->upper = path;
153         }
154         return 0;
155 }
156
157 void ovl_parse_param_drop_lowerdir(struct ovl_fs_context *ctx)
158 {
159         for (size_t nr = 0; nr < ctx->nr; nr++) {
160                 path_put(&ctx->lower[nr].path);
161                 kfree(ctx->lower[nr].name);
162                 ctx->lower[nr].name = NULL;
163         }
164         ctx->nr = 0;
165         ctx->nr_data = 0;
166 }
167
168 /*
169  * Parse lowerdir= mount option:
170  *
171  * (1) lowerdir=/lower1:/lower2:/lower3::/data1::/data2
172  *     Set "/lower1", "/lower2", and "/lower3" as lower layers and
173  *     "/data1" and "/data2" as data lower layers. Any existing lower
174  *     layers are replaced.
175  * (2) lowerdir=:/lower4
176  *     Append "/lower4" to current stack of lower layers. This requires
177  *     that there already is at least one lower layer configured.
178  * (3) lowerdir=::/lower5
179  *     Append data "/lower5" as data lower layer. This requires that
180  *     there's at least one regular lower layer present.
181  */
182 int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc)
183 {
184         int err;
185         struct ovl_fs_context *ctx = fc->fs_private;
186         struct ovl_fs_context_layer *l;
187         char *dup = NULL, *dup_iter;
188         ssize_t nr_lower = 0, nr = 0, nr_data = 0;
189         bool append = false, data_layer = false;
190
191         /*
192          * Ensure we're backwards compatible with mount(2)
193          * by allowing relative paths.
194          */
195
196         /* drop all existing lower layers */
197         if (!*name) {
198                 ovl_parse_param_drop_lowerdir(ctx);
199                 return 0;
200         }
201
202         if (strncmp(name, "::", 2) == 0) {
203                 /*
204                  * This is a data layer.
205                  * There must be at least one regular lower layer
206                  * specified.
207                  */
208                 if (ctx->nr == 0) {
209                         pr_err("data lower layers without regular lower layers not allowed");
210                         return -EINVAL;
211                 }
212
213                 /* Skip the leading "::". */
214                 name += 2;
215                 data_layer = true;
216                 /*
217                  * A data layer is automatically an append as there
218                  * must've been at least one regular lower layer.
219                  */
220                 append = true;
221         } else if (*name == ':') {
222                 /*
223                  * This is a regular lower layer.
224                  * If users want to append a layer enforce that they
225                  * have already specified a first layer before. It's
226                  * better to be strict.
227                  */
228                 if (ctx->nr == 0) {
229                         pr_err("cannot append layer if no previous layer has been specified");
230                         return -EINVAL;
231                 }
232
233                 /*
234                  * Once a sequence of data layers has started regular
235                  * lower layers are forbidden.
236                  */
237                 if (ctx->nr_data > 0) {
238                         pr_err("regular lower layers cannot follow data lower layers");
239                         return -EINVAL;
240                 }
241
242                 /* Skip the leading ":". */
243                 name++;
244                 append = true;
245         }
246
247         dup = kstrdup(name, GFP_KERNEL);
248         if (!dup)
249                 return -ENOMEM;
250
251         err = -EINVAL;
252         nr_lower = ovl_parse_param_split_lowerdirs(dup);
253         if (nr_lower < 0)
254                 goto out_err;
255
256         if ((nr_lower > OVL_MAX_STACK) ||
257             (append && (size_add(ctx->nr, nr_lower) > OVL_MAX_STACK))) {
258                 pr_err("too many lower directories, limit is %d\n", OVL_MAX_STACK);
259                 goto out_err;
260         }
261
262         if (!append)
263                 ovl_parse_param_drop_lowerdir(ctx);
264
265         /*
266          * (1) append
267          *
268          * We want nr <= nr_lower <= capacity We know nr > 0 and nr <=
269          * capacity. If nr == 0 this wouldn't be append. If nr +
270          * nr_lower is <= capacity then nr <= nr_lower <= capacity
271          * already holds. If nr + nr_lower exceeds capacity, we realloc.
272          *
273          * (2) replace
274          *
275          * Ensure we're backwards compatible with mount(2) which allows
276          * "lowerdir=/a:/b:/c,lowerdir=/d:/e:/f" causing the last
277          * specified lowerdir mount option to win.
278          *
279          * We want nr <= nr_lower <= capacity We know either (i) nr == 0
280          * or (ii) nr > 0. We also know nr_lower > 0. The capacity
281          * could've been changed multiple times already so we only know
282          * nr <= capacity. If nr + nr_lower > capacity we realloc,
283          * otherwise nr <= nr_lower <= capacity holds already.
284          */
285         nr_lower += ctx->nr;
286         if (nr_lower > ctx->capacity) {
287                 err = -ENOMEM;
288                 l = krealloc_array(ctx->lower, nr_lower, sizeof(*ctx->lower),
289                                    GFP_KERNEL_ACCOUNT);
290                 if (!l)
291                         goto out_err;
292
293                 ctx->lower = l;
294                 ctx->capacity = nr_lower;
295         }
296
297         /*
298          *   (3) By (1) and (2) we know nr <= nr_lower <= capacity.
299          *   (4) If ctx->nr == 0 => replace
300          *       We have verified above that the lowerdir mount option
301          *       isn't an append, i.e., the lowerdir mount option
302          *       doesn't start with ":" or "::".
303          * (4.1) The lowerdir mount options only contains regular lower
304          *       layers ":".
305          *       => Nothing to verify.
306          * (4.2) The lowerdir mount options contains regular ":" and
307          *       data "::" layers.
308          *       => We need to verify that data lower layers "::" aren't
309          *          followed by regular ":" lower layers
310          *   (5) If ctx->nr > 0 => append
311          *       We know that there's at least one regular layer
312          *       otherwise we would've failed when parsing the previous
313          *       lowerdir mount option.
314          * (5.1) The lowerdir mount option is a regular layer ":" append
315          *       => We need to verify that no data layers have been
316          *          specified before.
317          * (5.2) The lowerdir mount option is a data layer "::" append
318          *       We know that there's at least one regular layer or
319          *       other data layers. => There's nothing to verify.
320          */
321         dup_iter = dup;
322         for (nr = ctx->nr; nr < nr_lower; nr++) {
323                 l = &ctx->lower[nr];
324                 memset(l, 0, sizeof(*l));
325
326                 err = ovl_mount_dir_noesc(dup_iter, &l->path);
327                 if (err)
328                         goto out_put;
329
330                 err = -ENOMEM;
331                 l->name = kstrdup(dup_iter, GFP_KERNEL_ACCOUNT);
332                 if (!l->name)
333                         goto out_put;
334
335                 if (data_layer)
336                         nr_data++;
337
338                 /* Calling strchr() again would overrun. */
339                 if ((nr + 1) == nr_lower)
340                         break;
341
342                 err = -EINVAL;
343                 dup_iter = strchr(dup_iter, '\0') + 1;
344                 if (*dup_iter) {
345                         /*
346                          * This is a regular layer so we require that
347                          * there are no data layers.
348                          */
349                         if ((ctx->nr_data + nr_data) > 0) {
350                                 pr_err("regular lower layers cannot follow data lower layers");
351                                 goto out_put;
352                         }
353
354                         data_layer = false;
355                         continue;
356                 }
357
358                 /* This is a data lower layer. */
359                 data_layer = true;
360                 dup_iter++;
361         }
362         ctx->nr = nr_lower;
363         ctx->nr_data += nr_data;
364         kfree(dup);
365         return 0;
366
367 out_put:
368         /*
369          * We know nr >= ctx->nr < nr_lower. If we failed somewhere
370          * we want to undo until nr == ctx->nr. This is correct for
371          * both ctx->nr == 0 and ctx->nr > 0.
372          */
373         for (; nr >= ctx->nr; nr--) {
374                 l = &ctx->lower[nr];
375                 kfree(l->name);
376                 l->name = NULL;
377                 path_put(&l->path);
378
379                 /* don't overflow */
380                 if (nr == 0)
381                         break;
382         }
383
384 out_err:
385         kfree(dup);
386
387         /* Intentionally don't realloc to a smaller size. */
388         return err;
389 }