1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | |
3 | #include <linux/fs.h> |
4 | #include <linux/module.h> |
5 | #include <linux/namei.h> |
6 | #include <linux/fs_context.h> |
7 | #include <linux/fs_parser.h> |
8 | #include <linux/posix_acl_xattr.h> |
9 | #include <linux/seq_file.h> |
10 | #include <linux/xattr.h> |
11 | #include "overlayfs.h" |
12 | #include "params.h" |
13 | |
14 | static bool ovl_redirect_dir_def = IS_ENABLED(CONFIG_OVERLAY_FS_REDIRECT_DIR); |
15 | module_param_named(redirect_dir, ovl_redirect_dir_def, bool, 0644); |
16 | MODULE_PARM_DESC(redirect_dir, |
17 | "Default to on or off for the redirect_dir feature" ); |
18 | |
19 | static bool ovl_redirect_always_follow = |
20 | IS_ENABLED(CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW); |
21 | module_param_named(redirect_always_follow, ovl_redirect_always_follow, |
22 | bool, 0644); |
23 | MODULE_PARM_DESC(redirect_always_follow, |
24 | "Follow redirects even if redirect_dir feature is turned off" ); |
25 | |
26 | static bool ovl_xino_auto_def = IS_ENABLED(CONFIG_OVERLAY_FS_XINO_AUTO); |
27 | module_param_named(xino_auto, ovl_xino_auto_def, bool, 0644); |
28 | MODULE_PARM_DESC(xino_auto, |
29 | "Auto enable xino feature" ); |
30 | |
31 | static bool ovl_index_def = IS_ENABLED(CONFIG_OVERLAY_FS_INDEX); |
32 | module_param_named(index, ovl_index_def, bool, 0644); |
33 | MODULE_PARM_DESC(index, |
34 | "Default to on or off for the inodes index feature" ); |
35 | |
36 | static bool ovl_nfs_export_def = IS_ENABLED(CONFIG_OVERLAY_FS_NFS_EXPORT); |
37 | module_param_named(nfs_export, ovl_nfs_export_def, bool, 0644); |
38 | MODULE_PARM_DESC(nfs_export, |
39 | "Default to on or off for the NFS export feature" ); |
40 | |
41 | static bool ovl_metacopy_def = IS_ENABLED(CONFIG_OVERLAY_FS_METACOPY); |
42 | module_param_named(metacopy, ovl_metacopy_def, bool, 0644); |
43 | MODULE_PARM_DESC(metacopy, |
44 | "Default to on or off for the metadata only copy up feature" ); |
45 | |
46 | enum ovl_opt { |
47 | Opt_lowerdir, |
48 | Opt_lowerdir_add, |
49 | Opt_datadir_add, |
50 | Opt_upperdir, |
51 | Opt_workdir, |
52 | Opt_default_permissions, |
53 | Opt_redirect_dir, |
54 | Opt_index, |
55 | Opt_uuid, |
56 | Opt_nfs_export, |
57 | Opt_userxattr, |
58 | Opt_xino, |
59 | Opt_metacopy, |
60 | Opt_verity, |
61 | Opt_volatile, |
62 | }; |
63 | |
64 | static const struct constant_table ovl_parameter_bool[] = { |
65 | { "on" , true }, |
66 | { "off" , false }, |
67 | {} |
68 | }; |
69 | |
70 | static const struct constant_table ovl_parameter_uuid[] = { |
71 | { "off" , OVL_UUID_OFF }, |
72 | { "null" , OVL_UUID_NULL }, |
73 | { "auto" , OVL_UUID_AUTO }, |
74 | { "on" , OVL_UUID_ON }, |
75 | {} |
76 | }; |
77 | |
78 | static const char *ovl_uuid_mode(struct ovl_config *config) |
79 | { |
80 | return ovl_parameter_uuid[config->uuid].name; |
81 | } |
82 | |
83 | static int ovl_uuid_def(void) |
84 | { |
85 | return OVL_UUID_AUTO; |
86 | } |
87 | |
88 | static const struct constant_table ovl_parameter_xino[] = { |
89 | { "off" , OVL_XINO_OFF }, |
90 | { "auto" , OVL_XINO_AUTO }, |
91 | { "on" , OVL_XINO_ON }, |
92 | {} |
93 | }; |
94 | |
95 | const char *ovl_xino_mode(struct ovl_config *config) |
96 | { |
97 | return ovl_parameter_xino[config->xino].name; |
98 | } |
99 | |
100 | static int ovl_xino_def(void) |
101 | { |
102 | return ovl_xino_auto_def ? OVL_XINO_AUTO : OVL_XINO_OFF; |
103 | } |
104 | |
105 | const struct constant_table ovl_parameter_redirect_dir[] = { |
106 | { "off" , OVL_REDIRECT_OFF }, |
107 | { "follow" , OVL_REDIRECT_FOLLOW }, |
108 | { "nofollow" , OVL_REDIRECT_NOFOLLOW }, |
109 | { "on" , OVL_REDIRECT_ON }, |
110 | {} |
111 | }; |
112 | |
113 | static const char *ovl_redirect_mode(struct ovl_config *config) |
114 | { |
115 | return ovl_parameter_redirect_dir[config->redirect_mode].name; |
116 | } |
117 | |
118 | static int ovl_redirect_mode_def(void) |
119 | { |
120 | return ovl_redirect_dir_def ? OVL_REDIRECT_ON : |
121 | ovl_redirect_always_follow ? OVL_REDIRECT_FOLLOW : |
122 | OVL_REDIRECT_NOFOLLOW; |
123 | } |
124 | |
125 | static const struct constant_table ovl_parameter_verity[] = { |
126 | { "off" , OVL_VERITY_OFF }, |
127 | { "on" , OVL_VERITY_ON }, |
128 | { "require" , OVL_VERITY_REQUIRE }, |
129 | {} |
130 | }; |
131 | |
132 | static const char *ovl_verity_mode(struct ovl_config *config) |
133 | { |
134 | return ovl_parameter_verity[config->verity_mode].name; |
135 | } |
136 | |
137 | static int ovl_verity_mode_def(void) |
138 | { |
139 | return OVL_VERITY_OFF; |
140 | } |
141 | |
142 | #define fsparam_string_empty(NAME, OPT) \ |
143 | __fsparam(fs_param_is_string, NAME, OPT, fs_param_can_be_empty, NULL) |
144 | |
145 | |
146 | const struct fs_parameter_spec ovl_parameter_spec[] = { |
147 | fsparam_string_empty("lowerdir" , Opt_lowerdir), |
148 | fsparam_string("lowerdir+" , Opt_lowerdir_add), |
149 | fsparam_string("datadir+" , Opt_datadir_add), |
150 | fsparam_string("upperdir" , Opt_upperdir), |
151 | fsparam_string("workdir" , Opt_workdir), |
152 | fsparam_flag("default_permissions" , Opt_default_permissions), |
153 | fsparam_enum("redirect_dir" , Opt_redirect_dir, ovl_parameter_redirect_dir), |
154 | fsparam_enum("index" , Opt_index, ovl_parameter_bool), |
155 | fsparam_enum("uuid" , Opt_uuid, ovl_parameter_uuid), |
156 | fsparam_enum("nfs_export" , Opt_nfs_export, ovl_parameter_bool), |
157 | fsparam_flag("userxattr" , Opt_userxattr), |
158 | fsparam_enum("xino" , Opt_xino, ovl_parameter_xino), |
159 | fsparam_enum("metacopy" , Opt_metacopy, ovl_parameter_bool), |
160 | fsparam_enum("verity" , Opt_verity, ovl_parameter_verity), |
161 | fsparam_flag("volatile" , Opt_volatile), |
162 | {} |
163 | }; |
164 | |
165 | static char *ovl_next_opt(char **s) |
166 | { |
167 | char *sbegin = *s; |
168 | char *p; |
169 | |
170 | if (sbegin == NULL) |
171 | return NULL; |
172 | |
173 | for (p = sbegin; *p; p++) { |
174 | if (*p == '\\') { |
175 | p++; |
176 | if (!*p) |
177 | break; |
178 | } else if (*p == ',') { |
179 | *p = '\0'; |
180 | *s = p + 1; |
181 | return sbegin; |
182 | } |
183 | } |
184 | *s = NULL; |
185 | return sbegin; |
186 | } |
187 | |
188 | static int ovl_parse_monolithic(struct fs_context *fc, void *data) |
189 | { |
190 | return vfs_parse_monolithic_sep(fc, data, sep: ovl_next_opt); |
191 | } |
192 | |
193 | static ssize_t ovl_parse_param_split_lowerdirs(char *str) |
194 | { |
195 | ssize_t nr_layers = 1, nr_colons = 0; |
196 | char *s, *d; |
197 | |
198 | for (s = d = str;; s++, d++) { |
199 | if (*s == '\\') { |
200 | /* keep esc chars in split lowerdir */ |
201 | *d++ = *s++; |
202 | } else if (*s == ':') { |
203 | bool next_colon = (*(s + 1) == ':'); |
204 | |
205 | nr_colons++; |
206 | if (nr_colons == 2 && next_colon) { |
207 | pr_err("only single ':' or double '::' sequences of unescaped colons in lowerdir mount option allowed.\n" ); |
208 | return -EINVAL; |
209 | } |
210 | /* count layers, not colons */ |
211 | if (!next_colon) |
212 | nr_layers++; |
213 | |
214 | *d = '\0'; |
215 | continue; |
216 | } |
217 | |
218 | *d = *s; |
219 | if (!*s) { |
220 | /* trailing colons */ |
221 | if (nr_colons) { |
222 | pr_err("unescaped trailing colons in lowerdir mount option.\n" ); |
223 | return -EINVAL; |
224 | } |
225 | break; |
226 | } |
227 | nr_colons = 0; |
228 | } |
229 | |
230 | return nr_layers; |
231 | } |
232 | |
233 | static int ovl_mount_dir_noesc(const char *name, struct path *path) |
234 | { |
235 | int err = -EINVAL; |
236 | |
237 | if (!*name) { |
238 | pr_err("empty lowerdir\n" ); |
239 | goto out; |
240 | } |
241 | err = kern_path(name, LOOKUP_FOLLOW, path); |
242 | if (err) { |
243 | pr_err("failed to resolve '%s': %i\n" , name, err); |
244 | goto out; |
245 | } |
246 | return 0; |
247 | |
248 | out: |
249 | return err; |
250 | } |
251 | |
252 | static void ovl_unescape(char *s) |
253 | { |
254 | char *d = s; |
255 | |
256 | for (;; s++, d++) { |
257 | if (*s == '\\') |
258 | s++; |
259 | *d = *s; |
260 | if (!*s) |
261 | break; |
262 | } |
263 | } |
264 | |
265 | static int ovl_mount_dir(const char *name, struct path *path) |
266 | { |
267 | int err = -ENOMEM; |
268 | char *tmp = kstrdup(s: name, GFP_KERNEL); |
269 | |
270 | if (tmp) { |
271 | ovl_unescape(s: tmp); |
272 | err = ovl_mount_dir_noesc(name: tmp, path); |
273 | kfree(objp: tmp); |
274 | } |
275 | return err; |
276 | } |
277 | |
278 | static int ovl_mount_dir_check(struct fs_context *fc, const struct path *path, |
279 | enum ovl_opt layer, const char *name, bool upper) |
280 | { |
281 | struct ovl_fs_context *ctx = fc->fs_private; |
282 | |
283 | if (!d_is_dir(dentry: path->dentry)) |
284 | return invalfc(fc, "%s is not a directory" , name); |
285 | |
286 | /* |
287 | * Root dentries of case-insensitive capable filesystems might |
288 | * not have the dentry operations set, but still be incompatible |
289 | * with overlayfs. Check explicitly to prevent post-mount |
290 | * failures. |
291 | */ |
292 | if (sb_has_encoding(sb: path->mnt->mnt_sb)) |
293 | return invalfc(fc, "case-insensitive capable filesystem on %s not supported" , name); |
294 | |
295 | if (ovl_dentry_weird(dentry: path->dentry)) |
296 | return invalfc(fc, "filesystem on %s not supported" , name); |
297 | |
298 | /* |
299 | * Check whether upper path is read-only here to report failures |
300 | * early. Don't forget to recheck when the superblock is created |
301 | * as the mount attributes could change. |
302 | */ |
303 | if (upper) { |
304 | if (path->dentry->d_flags & DCACHE_OP_REAL) |
305 | return invalfc(fc, "filesystem on %s not supported as upperdir" , name); |
306 | if (__mnt_is_readonly(mnt: path->mnt)) |
307 | return invalfc(fc, "filesystem on %s is read-only" , name); |
308 | } else { |
309 | if (ctx->lowerdir_all && layer != Opt_lowerdir) |
310 | return invalfc(fc, "lowerdir+ and datadir+ cannot follow lowerdir" ); |
311 | if (ctx->nr_data && layer == Opt_lowerdir_add) |
312 | return invalfc(fc, "regular lower layers cannot follow data layers" ); |
313 | if (ctx->nr == OVL_MAX_STACK) |
314 | return invalfc(fc, "too many lower directories, limit is %d" , |
315 | OVL_MAX_STACK); |
316 | } |
317 | return 0; |
318 | } |
319 | |
320 | static int ovl_ctx_realloc_lower(struct fs_context *fc) |
321 | { |
322 | struct ovl_fs_context *ctx = fc->fs_private; |
323 | struct ovl_fs_context_layer *l; |
324 | size_t nr; |
325 | |
326 | if (ctx->nr < ctx->capacity) |
327 | return 0; |
328 | |
329 | nr = min_t(size_t, max(4096 / sizeof(*l), ctx->capacity * 2), |
330 | OVL_MAX_STACK); |
331 | l = krealloc_array(p: ctx->lower, new_n: nr, new_size: sizeof(*l), GFP_KERNEL_ACCOUNT); |
332 | if (!l) |
333 | return -ENOMEM; |
334 | |
335 | ctx->lower = l; |
336 | ctx->capacity = nr; |
337 | return 0; |
338 | } |
339 | |
340 | static void ovl_add_layer(struct fs_context *fc, enum ovl_opt layer, |
341 | struct path *path, char **pname) |
342 | { |
343 | struct ovl_fs *ofs = fc->s_fs_info; |
344 | struct ovl_config *config = &ofs->config; |
345 | struct ovl_fs_context *ctx = fc->fs_private; |
346 | struct ovl_fs_context_layer *l; |
347 | |
348 | switch (layer) { |
349 | case Opt_workdir: |
350 | swap(config->workdir, *pname); |
351 | swap(ctx->work, *path); |
352 | break; |
353 | case Opt_upperdir: |
354 | swap(config->upperdir, *pname); |
355 | swap(ctx->upper, *path); |
356 | break; |
357 | case Opt_datadir_add: |
358 | ctx->nr_data++; |
359 | fallthrough; |
360 | case Opt_lowerdir_add: |
361 | WARN_ON(ctx->nr >= ctx->capacity); |
362 | l = &ctx->lower[ctx->nr++]; |
363 | memset(l, 0, sizeof(*l)); |
364 | swap(l->name, *pname); |
365 | swap(l->path, *path); |
366 | break; |
367 | default: |
368 | WARN_ON(1); |
369 | } |
370 | } |
371 | |
372 | static int ovl_parse_layer(struct fs_context *fc, struct fs_parameter *param, |
373 | enum ovl_opt layer) |
374 | { |
375 | char *name = kstrdup(s: param->string, GFP_KERNEL); |
376 | bool upper = (layer == Opt_upperdir || layer == Opt_workdir); |
377 | struct path path; |
378 | int err; |
379 | |
380 | if (!name) |
381 | return -ENOMEM; |
382 | |
383 | if (upper) |
384 | err = ovl_mount_dir(name, path: &path); |
385 | else |
386 | err = ovl_mount_dir_noesc(name, path: &path); |
387 | if (err) |
388 | goto out_free; |
389 | |
390 | err = ovl_mount_dir_check(fc, path: &path, layer, name, upper); |
391 | if (err) |
392 | goto out_put; |
393 | |
394 | if (!upper) { |
395 | err = ovl_ctx_realloc_lower(fc); |
396 | if (err) |
397 | goto out_put; |
398 | } |
399 | |
400 | /* Store the user provided path string in ctx to show in mountinfo */ |
401 | ovl_add_layer(fc, layer, path: &path, pname: &name); |
402 | |
403 | out_put: |
404 | path_put(&path); |
405 | out_free: |
406 | kfree(objp: name); |
407 | return err; |
408 | } |
409 | |
410 | static void ovl_reset_lowerdirs(struct ovl_fs_context *ctx) |
411 | { |
412 | struct ovl_fs_context_layer *l = ctx->lower; |
413 | |
414 | // Reset old user provided lowerdir string |
415 | kfree(objp: ctx->lowerdir_all); |
416 | ctx->lowerdir_all = NULL; |
417 | |
418 | for (size_t nr = 0; nr < ctx->nr; nr++, l++) { |
419 | path_put(&l->path); |
420 | kfree(objp: l->name); |
421 | l->name = NULL; |
422 | } |
423 | ctx->nr = 0; |
424 | ctx->nr_data = 0; |
425 | } |
426 | |
427 | /* |
428 | * Parse lowerdir= mount option: |
429 | * |
430 | * e.g.: lowerdir=/lower1:/lower2:/lower3::/data1::/data2 |
431 | * Set "/lower1", "/lower2", and "/lower3" as lower layers and |
432 | * "/data1" and "/data2" as data lower layers. Any existing lower |
433 | * layers are replaced. |
434 | */ |
435 | static int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc) |
436 | { |
437 | int err; |
438 | struct ovl_fs_context *ctx = fc->fs_private; |
439 | struct ovl_fs_context_layer *l; |
440 | char *dup = NULL, *iter; |
441 | ssize_t nr_lower, nr; |
442 | bool data_layer = false; |
443 | |
444 | /* |
445 | * Ensure we're backwards compatible with mount(2) |
446 | * by allowing relative paths. |
447 | */ |
448 | |
449 | /* drop all existing lower layers */ |
450 | ovl_reset_lowerdirs(ctx); |
451 | |
452 | if (!*name) |
453 | return 0; |
454 | |
455 | if (*name == ':') { |
456 | pr_err("cannot append lower layer" ); |
457 | return -EINVAL; |
458 | } |
459 | |
460 | // Store user provided lowerdir string to show in mount options |
461 | ctx->lowerdir_all = kstrdup(s: name, GFP_KERNEL); |
462 | if (!ctx->lowerdir_all) |
463 | return -ENOMEM; |
464 | |
465 | dup = kstrdup(s: name, GFP_KERNEL); |
466 | if (!dup) |
467 | return -ENOMEM; |
468 | |
469 | err = -EINVAL; |
470 | nr_lower = ovl_parse_param_split_lowerdirs(str: dup); |
471 | if (nr_lower < 0) |
472 | goto out_err; |
473 | |
474 | if (nr_lower > OVL_MAX_STACK) { |
475 | pr_err("too many lower directories, limit is %d\n" , OVL_MAX_STACK); |
476 | goto out_err; |
477 | } |
478 | |
479 | if (nr_lower > ctx->capacity) { |
480 | err = -ENOMEM; |
481 | l = krealloc_array(p: ctx->lower, new_n: nr_lower, new_size: sizeof(*ctx->lower), |
482 | GFP_KERNEL_ACCOUNT); |
483 | if (!l) |
484 | goto out_err; |
485 | |
486 | ctx->lower = l; |
487 | ctx->capacity = nr_lower; |
488 | } |
489 | |
490 | iter = dup; |
491 | l = ctx->lower; |
492 | for (nr = 0; nr < nr_lower; nr++, l++) { |
493 | ctx->nr++; |
494 | memset(l, 0, sizeof(*l)); |
495 | |
496 | err = ovl_mount_dir(name: iter, path: &l->path); |
497 | if (err) |
498 | goto out_put; |
499 | |
500 | err = ovl_mount_dir_check(fc, path: &l->path, layer: Opt_lowerdir, name: iter, upper: false); |
501 | if (err) |
502 | goto out_put; |
503 | |
504 | err = -ENOMEM; |
505 | l->name = kstrdup(s: iter, GFP_KERNEL_ACCOUNT); |
506 | if (!l->name) |
507 | goto out_put; |
508 | |
509 | if (data_layer) |
510 | ctx->nr_data++; |
511 | |
512 | /* Calling strchr() again would overrun. */ |
513 | if (ctx->nr == nr_lower) |
514 | break; |
515 | |
516 | err = -EINVAL; |
517 | iter = strchr(iter, '\0') + 1; |
518 | if (*iter) { |
519 | /* |
520 | * This is a regular layer so we require that |
521 | * there are no data layers. |
522 | */ |
523 | if (ctx->nr_data > 0) { |
524 | pr_err("regular lower layers cannot follow data lower layers" ); |
525 | goto out_put; |
526 | } |
527 | |
528 | data_layer = false; |
529 | continue; |
530 | } |
531 | |
532 | /* This is a data lower layer. */ |
533 | data_layer = true; |
534 | iter++; |
535 | } |
536 | kfree(objp: dup); |
537 | return 0; |
538 | |
539 | out_put: |
540 | ovl_reset_lowerdirs(ctx); |
541 | |
542 | out_err: |
543 | kfree(objp: dup); |
544 | |
545 | /* Intentionally don't realloc to a smaller size. */ |
546 | return err; |
547 | } |
548 | |
549 | static int ovl_parse_param(struct fs_context *fc, struct fs_parameter *param) |
550 | { |
551 | int err = 0; |
552 | struct fs_parse_result result; |
553 | struct ovl_fs *ofs = fc->s_fs_info; |
554 | struct ovl_config *config = &ofs->config; |
555 | struct ovl_fs_context *ctx = fc->fs_private; |
556 | int opt; |
557 | |
558 | if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) { |
559 | /* |
560 | * On remount overlayfs has always ignored all mount |
561 | * options no matter if malformed or not so for |
562 | * backwards compatibility we do the same here. |
563 | */ |
564 | if (fc->oldapi) |
565 | return 0; |
566 | |
567 | /* |
568 | * Give us the freedom to allow changing mount options |
569 | * with the new mount api in the future. So instead of |
570 | * silently ignoring everything we report a proper |
571 | * error. This is only visible for users of the new |
572 | * mount api. |
573 | */ |
574 | return invalfc(fc, "No changes allowed in reconfigure" ); |
575 | } |
576 | |
577 | opt = fs_parse(fc, desc: ovl_parameter_spec, param, result: &result); |
578 | if (opt < 0) |
579 | return opt; |
580 | |
581 | switch (opt) { |
582 | case Opt_lowerdir: |
583 | err = ovl_parse_param_lowerdir(name: param->string, fc); |
584 | break; |
585 | case Opt_lowerdir_add: |
586 | case Opt_datadir_add: |
587 | case Opt_upperdir: |
588 | case Opt_workdir: |
589 | err = ovl_parse_layer(fc, param, layer: opt); |
590 | break; |
591 | case Opt_default_permissions: |
592 | config->default_permissions = true; |
593 | break; |
594 | case Opt_redirect_dir: |
595 | config->redirect_mode = result.uint_32; |
596 | if (config->redirect_mode == OVL_REDIRECT_OFF) { |
597 | config->redirect_mode = ovl_redirect_always_follow ? |
598 | OVL_REDIRECT_FOLLOW : |
599 | OVL_REDIRECT_NOFOLLOW; |
600 | } |
601 | ctx->set.redirect = true; |
602 | break; |
603 | case Opt_index: |
604 | config->index = result.uint_32; |
605 | ctx->set.index = true; |
606 | break; |
607 | case Opt_uuid: |
608 | config->uuid = result.uint_32; |
609 | break; |
610 | case Opt_nfs_export: |
611 | config->nfs_export = result.uint_32; |
612 | ctx->set.nfs_export = true; |
613 | break; |
614 | case Opt_xino: |
615 | config->xino = result.uint_32; |
616 | break; |
617 | case Opt_metacopy: |
618 | config->metacopy = result.uint_32; |
619 | ctx->set.metacopy = true; |
620 | break; |
621 | case Opt_verity: |
622 | config->verity_mode = result.uint_32; |
623 | break; |
624 | case Opt_volatile: |
625 | config->ovl_volatile = true; |
626 | break; |
627 | case Opt_userxattr: |
628 | config->userxattr = true; |
629 | break; |
630 | default: |
631 | pr_err("unrecognized mount option \"%s\" or missing value\n" , |
632 | param->key); |
633 | return -EINVAL; |
634 | } |
635 | |
636 | return err; |
637 | } |
638 | |
639 | static int ovl_get_tree(struct fs_context *fc) |
640 | { |
641 | return get_tree_nodev(fc, fill_super: ovl_fill_super); |
642 | } |
643 | |
644 | static inline void ovl_fs_context_free(struct ovl_fs_context *ctx) |
645 | { |
646 | ovl_reset_lowerdirs(ctx); |
647 | path_put(&ctx->upper); |
648 | path_put(&ctx->work); |
649 | kfree(objp: ctx->lower); |
650 | kfree(objp: ctx); |
651 | } |
652 | |
653 | static void ovl_free(struct fs_context *fc) |
654 | { |
655 | struct ovl_fs *ofs = fc->s_fs_info; |
656 | struct ovl_fs_context *ctx = fc->fs_private; |
657 | |
658 | /* |
659 | * ofs is stored in the fs_context when it is initialized. |
660 | * ofs is transferred to the superblock on a successful mount, |
661 | * but if an error occurs before the transfer we have to free |
662 | * it here. |
663 | */ |
664 | if (ofs) |
665 | ovl_free_fs(ofs); |
666 | |
667 | if (ctx) |
668 | ovl_fs_context_free(ctx); |
669 | } |
670 | |
671 | static int ovl_reconfigure(struct fs_context *fc) |
672 | { |
673 | struct super_block *sb = fc->root->d_sb; |
674 | struct ovl_fs *ofs = OVL_FS(sb); |
675 | struct super_block *upper_sb; |
676 | int ret = 0; |
677 | |
678 | if (!(fc->sb_flags & SB_RDONLY) && ovl_force_readonly(ofs)) |
679 | return -EROFS; |
680 | |
681 | if (fc->sb_flags & SB_RDONLY && !sb_rdonly(sb)) { |
682 | upper_sb = ovl_upper_mnt(ofs)->mnt_sb; |
683 | if (ovl_should_sync(ofs)) { |
684 | down_read(sem: &upper_sb->s_umount); |
685 | ret = sync_filesystem(upper_sb); |
686 | up_read(sem: &upper_sb->s_umount); |
687 | } |
688 | } |
689 | |
690 | return ret; |
691 | } |
692 | |
693 | static const struct fs_context_operations ovl_context_ops = { |
694 | .parse_monolithic = ovl_parse_monolithic, |
695 | .parse_param = ovl_parse_param, |
696 | .get_tree = ovl_get_tree, |
697 | .reconfigure = ovl_reconfigure, |
698 | .free = ovl_free, |
699 | }; |
700 | |
701 | /* |
702 | * This is called during fsopen() and will record the user namespace of |
703 | * the caller in fc->user_ns since we've raised FS_USERNS_MOUNT. We'll |
704 | * need it when we actually create the superblock to verify that the |
705 | * process creating the superblock is in the same user namespace as |
706 | * process that called fsopen(). |
707 | */ |
708 | int ovl_init_fs_context(struct fs_context *fc) |
709 | { |
710 | struct ovl_fs_context *ctx; |
711 | struct ovl_fs *ofs; |
712 | |
713 | ctx = kzalloc(size: sizeof(*ctx), GFP_KERNEL_ACCOUNT); |
714 | if (!ctx) |
715 | return -ENOMEM; |
716 | |
717 | /* |
718 | * By default we allocate for three lower layers. It's likely |
719 | * that it'll cover most users. |
720 | */ |
721 | ctx->lower = kmalloc_array(n: 3, size: sizeof(*ctx->lower), GFP_KERNEL_ACCOUNT); |
722 | if (!ctx->lower) |
723 | goto out_err; |
724 | ctx->capacity = 3; |
725 | |
726 | ofs = kzalloc(size: sizeof(struct ovl_fs), GFP_KERNEL); |
727 | if (!ofs) |
728 | goto out_err; |
729 | |
730 | ofs->config.redirect_mode = ovl_redirect_mode_def(); |
731 | ofs->config.index = ovl_index_def; |
732 | ofs->config.uuid = ovl_uuid_def(); |
733 | ofs->config.nfs_export = ovl_nfs_export_def; |
734 | ofs->config.xino = ovl_xino_def(); |
735 | ofs->config.metacopy = ovl_metacopy_def; |
736 | |
737 | fc->s_fs_info = ofs; |
738 | fc->fs_private = ctx; |
739 | fc->ops = &ovl_context_ops; |
740 | return 0; |
741 | |
742 | out_err: |
743 | ovl_fs_context_free(ctx); |
744 | return -ENOMEM; |
745 | |
746 | } |
747 | |
748 | void ovl_free_fs(struct ovl_fs *ofs) |
749 | { |
750 | struct vfsmount **mounts; |
751 | unsigned i; |
752 | |
753 | iput(ofs->workbasedir_trap); |
754 | iput(ofs->workdir_trap); |
755 | dput(ofs->whiteout); |
756 | dput(ofs->workdir); |
757 | if (ofs->workdir_locked) |
758 | ovl_inuse_unlock(dentry: ofs->workbasedir); |
759 | dput(ofs->workbasedir); |
760 | if (ofs->upperdir_locked) |
761 | ovl_inuse_unlock(dentry: ovl_upper_mnt(ofs)->mnt_root); |
762 | |
763 | /* Reuse ofs->config.lowerdirs as a vfsmount array before freeing it */ |
764 | mounts = (struct vfsmount **) ofs->config.lowerdirs; |
765 | for (i = 0; i < ofs->numlayer; i++) { |
766 | iput(ofs->layers[i].trap); |
767 | kfree(objp: ofs->config.lowerdirs[i]); |
768 | mounts[i] = ofs->layers[i].mnt; |
769 | } |
770 | kern_unmount_array(mnt: mounts, num: ofs->numlayer); |
771 | kfree(objp: ofs->layers); |
772 | for (i = 0; i < ofs->numfs; i++) |
773 | free_anon_bdev(ofs->fs[i].pseudo_dev); |
774 | kfree(objp: ofs->fs); |
775 | |
776 | kfree(objp: ofs->config.lowerdirs); |
777 | kfree(objp: ofs->config.upperdir); |
778 | kfree(objp: ofs->config.workdir); |
779 | if (ofs->creator_cred) |
780 | put_cred(cred: ofs->creator_cred); |
781 | kfree(objp: ofs); |
782 | } |
783 | |
784 | int ovl_fs_params_verify(const struct ovl_fs_context *ctx, |
785 | struct ovl_config *config) |
786 | { |
787 | struct ovl_opt_set set = ctx->set; |
788 | |
789 | if (ctx->nr_data > 0 && !config->metacopy) { |
790 | pr_err("lower data-only dirs require metacopy support.\n" ); |
791 | return -EINVAL; |
792 | } |
793 | |
794 | /* Workdir/index are useless in non-upper mount */ |
795 | if (!config->upperdir) { |
796 | if (config->workdir) { |
797 | pr_info("option \"workdir=%s\" is useless in a non-upper mount, ignore\n" , |
798 | config->workdir); |
799 | kfree(objp: config->workdir); |
800 | config->workdir = NULL; |
801 | } |
802 | if (config->index && set.index) { |
803 | pr_info("option \"index=on\" is useless in a non-upper mount, ignore\n" ); |
804 | set.index = false; |
805 | } |
806 | config->index = false; |
807 | } |
808 | |
809 | if (!config->upperdir && config->ovl_volatile) { |
810 | pr_info("option \"volatile\" is meaningless in a non-upper mount, ignoring it.\n" ); |
811 | config->ovl_volatile = false; |
812 | } |
813 | |
814 | if (!config->upperdir && config->uuid == OVL_UUID_ON) { |
815 | pr_info("option \"uuid=on\" requires an upper fs, falling back to uuid=null.\n" ); |
816 | config->uuid = OVL_UUID_NULL; |
817 | } |
818 | |
819 | /* Resolve verity -> metacopy dependency */ |
820 | if (config->verity_mode && !config->metacopy) { |
821 | /* Don't allow explicit specified conflicting combinations */ |
822 | if (set.metacopy) { |
823 | pr_err("conflicting options: metacopy=off,verity=%s\n" , |
824 | ovl_verity_mode(config)); |
825 | return -EINVAL; |
826 | } |
827 | /* Otherwise automatically enable metacopy. */ |
828 | config->metacopy = true; |
829 | } |
830 | |
831 | /* |
832 | * This is to make the logic below simpler. It doesn't make any other |
833 | * difference, since redirect_dir=on is only used for upper. |
834 | */ |
835 | if (!config->upperdir && config->redirect_mode == OVL_REDIRECT_FOLLOW) |
836 | config->redirect_mode = OVL_REDIRECT_ON; |
837 | |
838 | /* Resolve verity -> metacopy -> redirect_dir dependency */ |
839 | if (config->metacopy && config->redirect_mode != OVL_REDIRECT_ON) { |
840 | if (set.metacopy && set.redirect) { |
841 | pr_err("conflicting options: metacopy=on,redirect_dir=%s\n" , |
842 | ovl_redirect_mode(config)); |
843 | return -EINVAL; |
844 | } |
845 | if (config->verity_mode && set.redirect) { |
846 | pr_err("conflicting options: verity=%s,redirect_dir=%s\n" , |
847 | ovl_verity_mode(config), ovl_redirect_mode(config)); |
848 | return -EINVAL; |
849 | } |
850 | if (set.redirect) { |
851 | /* |
852 | * There was an explicit redirect_dir=... that resulted |
853 | * in this conflict. |
854 | */ |
855 | pr_info("disabling metacopy due to redirect_dir=%s\n" , |
856 | ovl_redirect_mode(config)); |
857 | config->metacopy = false; |
858 | } else { |
859 | /* Automatically enable redirect otherwise. */ |
860 | config->redirect_mode = OVL_REDIRECT_ON; |
861 | } |
862 | } |
863 | |
864 | /* Resolve nfs_export -> index dependency */ |
865 | if (config->nfs_export && !config->index) { |
866 | if (!config->upperdir && |
867 | config->redirect_mode != OVL_REDIRECT_NOFOLLOW) { |
868 | pr_info("NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n" ); |
869 | config->nfs_export = false; |
870 | } else if (set.nfs_export && set.index) { |
871 | pr_err("conflicting options: nfs_export=on,index=off\n" ); |
872 | return -EINVAL; |
873 | } else if (set.index) { |
874 | /* |
875 | * There was an explicit index=off that resulted |
876 | * in this conflict. |
877 | */ |
878 | pr_info("disabling nfs_export due to index=off\n" ); |
879 | config->nfs_export = false; |
880 | } else { |
881 | /* Automatically enable index otherwise. */ |
882 | config->index = true; |
883 | } |
884 | } |
885 | |
886 | /* Resolve nfs_export -> !metacopy && !verity dependency */ |
887 | if (config->nfs_export && config->metacopy) { |
888 | if (set.nfs_export && set.metacopy) { |
889 | pr_err("conflicting options: nfs_export=on,metacopy=on\n" ); |
890 | return -EINVAL; |
891 | } |
892 | if (set.metacopy) { |
893 | /* |
894 | * There was an explicit metacopy=on that resulted |
895 | * in this conflict. |
896 | */ |
897 | pr_info("disabling nfs_export due to metacopy=on\n" ); |
898 | config->nfs_export = false; |
899 | } else if (config->verity_mode) { |
900 | /* |
901 | * There was an explicit verity=.. that resulted |
902 | * in this conflict. |
903 | */ |
904 | pr_info("disabling nfs_export due to verity=%s\n" , |
905 | ovl_verity_mode(config)); |
906 | config->nfs_export = false; |
907 | } else { |
908 | /* |
909 | * There was an explicit nfs_export=on that resulted |
910 | * in this conflict. |
911 | */ |
912 | pr_info("disabling metacopy due to nfs_export=on\n" ); |
913 | config->metacopy = false; |
914 | } |
915 | } |
916 | |
917 | |
918 | /* Resolve userxattr -> !redirect && !metacopy && !verity dependency */ |
919 | if (config->userxattr) { |
920 | if (set.redirect && |
921 | config->redirect_mode != OVL_REDIRECT_NOFOLLOW) { |
922 | pr_err("conflicting options: userxattr,redirect_dir=%s\n" , |
923 | ovl_redirect_mode(config)); |
924 | return -EINVAL; |
925 | } |
926 | if (config->metacopy && set.metacopy) { |
927 | pr_err("conflicting options: userxattr,metacopy=on\n" ); |
928 | return -EINVAL; |
929 | } |
930 | if (config->verity_mode) { |
931 | pr_err("conflicting options: userxattr,verity=%s\n" , |
932 | ovl_verity_mode(config)); |
933 | return -EINVAL; |
934 | } |
935 | /* |
936 | * Silently disable default setting of redirect and metacopy. |
937 | * This shall be the default in the future as well: these |
938 | * options must be explicitly enabled if used together with |
939 | * userxattr. |
940 | */ |
941 | config->redirect_mode = OVL_REDIRECT_NOFOLLOW; |
942 | config->metacopy = false; |
943 | } |
944 | |
945 | return 0; |
946 | } |
947 | |
948 | /** |
949 | * ovl_show_options |
950 | * @m: the seq_file handle |
951 | * @dentry: The dentry to query |
952 | * |
953 | * Prints the mount options for a given superblock. |
954 | * Returns zero; does not fail. |
955 | */ |
956 | int ovl_show_options(struct seq_file *m, struct dentry *dentry) |
957 | { |
958 | struct super_block *sb = dentry->d_sb; |
959 | struct ovl_fs *ofs = OVL_FS(sb); |
960 | size_t nr, nr_merged_lower, nr_lower = 0; |
961 | char **lowerdirs = ofs->config.lowerdirs; |
962 | |
963 | /* |
964 | * lowerdirs[0] holds the colon separated list that user provided |
965 | * with lowerdir mount option. |
966 | * lowerdirs[1..numlayer] hold the lowerdir paths that were added |
967 | * using the lowerdir+ and datadir+ mount options. |
968 | * For now, we do not allow mixing the legacy lowerdir mount option |
969 | * with the new lowerdir+ and datadir+ mount options. |
970 | */ |
971 | if (lowerdirs[0]) { |
972 | seq_show_option(m, name: "lowerdir" , value: lowerdirs[0]); |
973 | } else { |
974 | nr_lower = ofs->numlayer; |
975 | nr_merged_lower = nr_lower - ofs->numdatalayer; |
976 | } |
977 | for (nr = 1; nr < nr_lower; nr++) { |
978 | if (nr < nr_merged_lower) |
979 | seq_show_option(m, name: "lowerdir+" , value: lowerdirs[nr]); |
980 | else |
981 | seq_show_option(m, name: "datadir+" , value: lowerdirs[nr]); |
982 | } |
983 | if (ofs->config.upperdir) { |
984 | seq_show_option(m, name: "upperdir" , value: ofs->config.upperdir); |
985 | seq_show_option(m, name: "workdir" , value: ofs->config.workdir); |
986 | } |
987 | if (ofs->config.default_permissions) |
988 | seq_puts(m, s: ",default_permissions" ); |
989 | if (ofs->config.redirect_mode != ovl_redirect_mode_def()) |
990 | seq_printf(m, fmt: ",redirect_dir=%s" , |
991 | ovl_redirect_mode(config: &ofs->config)); |
992 | if (ofs->config.index != ovl_index_def) |
993 | seq_printf(m, fmt: ",index=%s" , ofs->config.index ? "on" : "off" ); |
994 | if (ofs->config.uuid != ovl_uuid_def()) |
995 | seq_printf(m, fmt: ",uuid=%s" , ovl_uuid_mode(config: &ofs->config)); |
996 | if (ofs->config.nfs_export != ovl_nfs_export_def) |
997 | seq_printf(m, fmt: ",nfs_export=%s" , ofs->config.nfs_export ? |
998 | "on" : "off" ); |
999 | if (ofs->config.xino != ovl_xino_def() && !ovl_same_fs(ofs)) |
1000 | seq_printf(m, fmt: ",xino=%s" , ovl_xino_mode(config: &ofs->config)); |
1001 | if (ofs->config.metacopy != ovl_metacopy_def) |
1002 | seq_printf(m, fmt: ",metacopy=%s" , |
1003 | ofs->config.metacopy ? "on" : "off" ); |
1004 | if (ofs->config.ovl_volatile) |
1005 | seq_puts(m, s: ",volatile" ); |
1006 | if (ofs->config.userxattr) |
1007 | seq_puts(m, s: ",userxattr" ); |
1008 | if (ofs->config.verity_mode != ovl_verity_mode_def()) |
1009 | seq_printf(m, fmt: ",verity=%s" , |
1010 | ovl_verity_mode(config: &ofs->config)); |
1011 | return 0; |
1012 | } |
1013 | |