blob: 213a726cff963d210856f6aa88da300b53665a13 [file] [log] [blame]
Miklos Szeredie9be9d52014-10-24 00:14:38 +02001/*
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 "overlayfs.h"
14
15static int ovl_copy_up_last(struct dentry *dentry, struct iattr *attr,
16 bool no_data)
17{
18 int err;
19 struct dentry *parent;
20 struct kstat stat;
21 struct path lowerpath;
22
23 parent = dget_parent(dentry);
24 err = ovl_copy_up(parent);
25 if (err)
26 goto out_dput_parent;
27
28 ovl_path_lower(dentry, &lowerpath);
29 err = vfs_getattr(&lowerpath, &stat);
30 if (err)
31 goto out_dput_parent;
32
33 if (no_data)
34 stat.size = 0;
35
36 err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat, attr);
37
38out_dput_parent:
39 dput(parent);
40 return err;
41}
42
43int ovl_setattr(struct dentry *dentry, struct iattr *attr)
44{
45 int err;
46 struct dentry *upperdentry;
47
Miklos Szeredicf9a6782015-12-11 16:30:49 +010048 /*
49 * Check for permissions before trying to copy-up. This is redundant
50 * since it will be rechecked later by ->setattr() on upper dentry. But
51 * without this, copy-up can be triggered by just about anybody.
52 *
53 * We don't initialize inode->size, which just means that
54 * inode_newsize_ok() will always check against MAX_LFS_FILESIZE and not
55 * check for a swapfile (which this won't be anyway).
56 */
57 err = inode_change_ok(dentry->d_inode, attr);
58 if (err)
59 return err;
60
Miklos Szeredie9be9d52014-10-24 00:14:38 +020061 err = ovl_want_write(dentry);
62 if (err)
63 goto out;
64
65 upperdentry = ovl_dentry_upper(dentry);
66 if (upperdentry) {
67 mutex_lock(&upperdentry->d_inode->i_mutex);
68 err = notify_change(upperdentry, attr, NULL);
69 mutex_unlock(&upperdentry->d_inode->i_mutex);
70 } else {
71 err = ovl_copy_up_last(dentry, attr, false);
72 }
73 ovl_drop_write(dentry);
74out:
75 return err;
76}
77
78static int ovl_getattr(struct vfsmount *mnt, struct dentry *dentry,
79 struct kstat *stat)
80{
81 struct path realpath;
82
83 ovl_path_real(dentry, &realpath);
84 return vfs_getattr(&realpath, stat);
85}
86
87int ovl_permission(struct inode *inode, int mask)
88{
89 struct ovl_entry *oe;
90 struct dentry *alias = NULL;
91 struct inode *realinode;
92 struct dentry *realdentry;
93 bool is_upper;
94 int err;
95
96 if (S_ISDIR(inode->i_mode)) {
97 oe = inode->i_private;
98 } else if (mask & MAY_NOT_BLOCK) {
99 return -ECHILD;
100 } else {
101 /*
102 * For non-directories find an alias and get the info
103 * from there.
104 */
105 alias = d_find_any_alias(inode);
106 if (WARN_ON(!alias))
107 return -ENOENT;
108
109 oe = alias->d_fsdata;
110 }
111
112 realdentry = ovl_entry_real(oe, &is_upper);
113
Miklos Szeredi8d3095f2015-10-12 17:11:44 +0200114 if (ovl_is_default_permissions(inode)) {
115 struct kstat stat;
116 struct path realpath = { .dentry = realdentry };
117
118 if (mask & MAY_NOT_BLOCK)
119 return -ECHILD;
120
121 realpath.mnt = ovl_entry_mnt_real(oe, inode, is_upper);
122
123 err = vfs_getattr(&realpath, &stat);
124 if (err)
125 return err;
126
127 if ((stat.mode ^ inode->i_mode) & S_IFMT)
128 return -ESTALE;
129
130 inode->i_mode = stat.mode;
131 inode->i_uid = stat.uid;
132 inode->i_gid = stat.gid;
133
134 return generic_permission(inode, mask);
135 }
136
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200137 /* Careful in RCU walk mode */
138 realinode = ACCESS_ONCE(realdentry->d_inode);
139 if (!realinode) {
140 WARN_ON(!(mask & MAY_NOT_BLOCK));
141 err = -ENOENT;
142 goto out_dput;
143 }
144
145 if (mask & MAY_WRITE) {
146 umode_t mode = realinode->i_mode;
147
148 /*
149 * Writes will always be redirected to upper layer, so
150 * ignore lower layer being read-only.
151 *
152 * If the overlay itself is read-only then proceed
153 * with the permission check, don't return EROFS.
154 * This will only happen if this is the lower layer of
155 * another overlayfs.
156 *
157 * If upper fs becomes read-only after the overlay was
158 * constructed return EROFS to prevent modification of
159 * upper layer.
160 */
161 err = -EROFS;
162 if (is_upper && !IS_RDONLY(inode) && IS_RDONLY(realinode) &&
163 (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
164 goto out_dput;
165 }
166
167 err = __inode_permission(realinode, mask);
168out_dput:
169 dput(alias);
170 return err;
171}
172
173
174struct ovl_link_data {
175 struct dentry *realdentry;
176 void *cookie;
177};
178
Al Viro6e77137b2015-05-02 13:37:52 -0400179static const char *ovl_follow_link(struct dentry *dentry, void **cookie)
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200180{
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200181 struct dentry *realdentry;
182 struct inode *realinode;
NeilBrown3188b292015-03-23 13:37:39 +1100183 struct ovl_link_data *data = NULL;
Al Viro680baac2015-05-02 13:32:22 -0400184 const char *ret;
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200185
186 realdentry = ovl_dentry_real(dentry);
187 realinode = realdentry->d_inode;
188
189 if (WARN_ON(!realinode->i_op->follow_link))
190 return ERR_PTR(-EPERM);
191
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200192 if (realinode->i_op->put_link) {
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200193 data = kmalloc(sizeof(struct ovl_link_data), GFP_KERNEL);
NeilBrown3188b292015-03-23 13:37:39 +1100194 if (!data)
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200195 return ERR_PTR(-ENOMEM);
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200196 data->realdentry = realdentry;
NeilBrown3188b292015-03-23 13:37:39 +1100197 }
198
Al Viro6e77137b2015-05-02 13:37:52 -0400199 ret = realinode->i_op->follow_link(realdentry, cookie);
Al Viro680baac2015-05-02 13:32:22 -0400200 if (IS_ERR_OR_NULL(ret)) {
NeilBrown3188b292015-03-23 13:37:39 +1100201 kfree(data);
202 return ret;
203 }
204
205 if (data)
Al Viro680baac2015-05-02 13:32:22 -0400206 data->cookie = *cookie;
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200207
Al Viro680baac2015-05-02 13:32:22 -0400208 *cookie = data;
209
210 return ret;
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200211}
212
Al Viro5f2c4172015-05-07 11:14:26 -0400213static void ovl_put_link(struct inode *unused, void *c)
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200214{
215 struct inode *realinode;
216 struct ovl_link_data *data = c;
217
218 if (!data)
219 return;
220
221 realinode = data->realdentry->d_inode;
Al Viro5f2c4172015-05-07 11:14:26 -0400222 realinode->i_op->put_link(realinode, data->cookie);
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200223 kfree(data);
224}
225
226static int ovl_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
227{
228 struct path realpath;
229 struct inode *realinode;
230
231 ovl_path_real(dentry, &realpath);
232 realinode = realpath.dentry->d_inode;
233
234 if (!realinode->i_op->readlink)
235 return -EINVAL;
236
237 touch_atime(&realpath);
238
239 return realinode->i_op->readlink(realpath.dentry, buf, bufsiz);
240}
241
242
243static bool ovl_is_private_xattr(const char *name)
244{
hujianyangcead89b2014-11-24 18:25:21 +0800245 return strncmp(name, OVL_XATTR_PRE_NAME, OVL_XATTR_PRE_LEN) == 0;
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200246}
247
248int ovl_setxattr(struct dentry *dentry, const char *name,
249 const void *value, size_t size, int flags)
250{
251 int err;
252 struct dentry *upperdentry;
253
254 err = ovl_want_write(dentry);
255 if (err)
256 goto out;
257
258 err = -EPERM;
259 if (ovl_is_private_xattr(name))
260 goto out_drop_write;
261
262 err = ovl_copy_up(dentry);
263 if (err)
264 goto out_drop_write;
265
266 upperdentry = ovl_dentry_upper(dentry);
267 err = vfs_setxattr(upperdentry, name, value, size, flags);
268
269out_drop_write:
270 ovl_drop_write(dentry);
271out:
272 return err;
273}
274
Miklos Szeredi52148462014-11-20 16:40:00 +0100275static bool ovl_need_xattr_filter(struct dentry *dentry,
276 enum ovl_path_type type)
277{
Miklos Szeredi1afaba12014-12-13 00:59:42 +0100278 if ((type & (__OVL_PATH_PURE | __OVL_PATH_UPPER)) == __OVL_PATH_UPPER)
279 return S_ISDIR(dentry->d_inode->i_mode);
280 else
281 return false;
Miklos Szeredi52148462014-11-20 16:40:00 +0100282}
283
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200284ssize_t ovl_getxattr(struct dentry *dentry, const char *name,
285 void *value, size_t size)
286{
Miklos Szeredi52148462014-11-20 16:40:00 +0100287 struct path realpath;
288 enum ovl_path_type type = ovl_path_real(dentry, &realpath);
289
290 if (ovl_need_xattr_filter(dentry, type) && ovl_is_private_xattr(name))
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200291 return -ENODATA;
292
Miklos Szeredi52148462014-11-20 16:40:00 +0100293 return vfs_getxattr(realpath.dentry, name, value, size);
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200294}
295
296ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
297{
Miklos Szeredi52148462014-11-20 16:40:00 +0100298 struct path realpath;
299 enum ovl_path_type type = ovl_path_real(dentry, &realpath);
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200300 ssize_t res;
301 int off;
302
Miklos Szeredi52148462014-11-20 16:40:00 +0100303 res = vfs_listxattr(realpath.dentry, list, size);
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200304 if (res <= 0 || size == 0)
305 return res;
306
Miklos Szeredi52148462014-11-20 16:40:00 +0100307 if (!ovl_need_xattr_filter(dentry, type))
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200308 return res;
309
310 /* filter out private xattrs */
311 for (off = 0; off < res;) {
312 char *s = list + off;
313 size_t slen = strlen(s) + 1;
314
315 BUG_ON(off + slen > res);
316
317 if (ovl_is_private_xattr(s)) {
318 res -= slen;
319 memmove(s, s + slen, res - off);
320 } else {
321 off += slen;
322 }
323 }
324
325 return res;
326}
327
328int ovl_removexattr(struct dentry *dentry, const char *name)
329{
330 int err;
331 struct path realpath;
Miklos Szeredi52148462014-11-20 16:40:00 +0100332 enum ovl_path_type type = ovl_path_real(dentry, &realpath);
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200333
334 err = ovl_want_write(dentry);
335 if (err)
336 goto out;
337
Miklos Szeredi52148462014-11-20 16:40:00 +0100338 err = -ENODATA;
339 if (ovl_need_xattr_filter(dentry, type) && ovl_is_private_xattr(name))
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200340 goto out_drop_write;
341
Miklos Szeredi1afaba12014-12-13 00:59:42 +0100342 if (!OVL_TYPE_UPPER(type)) {
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200343 err = vfs_getxattr(realpath.dentry, name, NULL, 0);
344 if (err < 0)
345 goto out_drop_write;
346
347 err = ovl_copy_up(dentry);
348 if (err)
349 goto out_drop_write;
350
351 ovl_path_upper(dentry, &realpath);
352 }
353
354 err = vfs_removexattr(realpath.dentry, name);
355out_drop_write:
356 ovl_drop_write(dentry);
357out:
358 return err;
359}
360
361static bool ovl_open_need_copy_up(int flags, enum ovl_path_type type,
362 struct dentry *realdentry)
363{
Miklos Szeredi1afaba12014-12-13 00:59:42 +0100364 if (OVL_TYPE_UPPER(type))
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200365 return false;
366
367 if (special_file(realdentry->d_inode->i_mode))
368 return false;
369
370 if (!(OPEN_FMODE(flags) & FMODE_WRITE) && !(flags & O_TRUNC))
371 return false;
372
373 return true;
374}
375
David Howells4bacc9c2015-06-18 14:32:31 +0100376struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags)
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200377{
378 int err;
379 struct path realpath;
380 enum ovl_path_type type;
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200381
Al Viro9391dd02015-07-12 10:39:45 -0400382 if (d_is_dir(dentry))
383 return d_backing_inode(dentry);
384
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200385 type = ovl_path_real(dentry, &realpath);
David Howells4bacc9c2015-06-18 14:32:31 +0100386 if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) {
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200387 err = ovl_want_write(dentry);
388 if (err)
David Howells4bacc9c2015-06-18 14:32:31 +0100389 return ERR_PTR(err);
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200390
David Howells4bacc9c2015-06-18 14:32:31 +0100391 if (file_flags & O_TRUNC)
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200392 err = ovl_copy_up_last(dentry, NULL, true);
393 else
394 err = ovl_copy_up(dentry);
David Howellsf25801e2015-06-18 14:32:23 +0100395 ovl_drop_write(dentry);
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200396 if (err)
David Howells4bacc9c2015-06-18 14:32:31 +0100397 return ERR_PTR(err);
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200398
399 ovl_path_upper(dentry, &realpath);
400 }
401
Miklos Szeredi1c8a47d2015-10-12 15:56:20 +0200402 if (realpath.dentry->d_flags & DCACHE_OP_SELECT_INODE)
403 return realpath.dentry->d_op->d_select_inode(realpath.dentry, file_flags);
404
David Howells4bacc9c2015-06-18 14:32:31 +0100405 return d_backing_inode(realpath.dentry);
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200406}
407
408static const struct inode_operations ovl_file_inode_operations = {
409 .setattr = ovl_setattr,
410 .permission = ovl_permission,
411 .getattr = ovl_getattr,
412 .setxattr = ovl_setxattr,
413 .getxattr = ovl_getxattr,
414 .listxattr = ovl_listxattr,
415 .removexattr = ovl_removexattr,
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200416};
417
418static const struct inode_operations ovl_symlink_inode_operations = {
419 .setattr = ovl_setattr,
420 .follow_link = ovl_follow_link,
421 .put_link = ovl_put_link,
422 .readlink = ovl_readlink,
423 .getattr = ovl_getattr,
424 .setxattr = ovl_setxattr,
425 .getxattr = ovl_getxattr,
426 .listxattr = ovl_listxattr,
427 .removexattr = ovl_removexattr,
428};
429
430struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
431 struct ovl_entry *oe)
432{
433 struct inode *inode;
434
435 inode = new_inode(sb);
436 if (!inode)
437 return NULL;
438
439 mode &= S_IFMT;
440
441 inode->i_ino = get_next_ino();
442 inode->i_mode = mode;
443 inode->i_flags |= S_NOATIME | S_NOCMTIME;
444
445 switch (mode) {
446 case S_IFDIR:
447 inode->i_private = oe;
448 inode->i_op = &ovl_dir_inode_operations;
449 inode->i_fop = &ovl_dir_operations;
450 break;
451
452 case S_IFLNK:
453 inode->i_op = &ovl_symlink_inode_operations;
454 break;
455
456 case S_IFREG:
457 case S_IFSOCK:
458 case S_IFBLK:
459 case S_IFCHR:
460 case S_IFIFO:
461 inode->i_op = &ovl_file_inode_operations;
462 break;
463
464 default:
465 WARN(1, "illegal file type: %i\n", mode);
466 iput(inode);
467 inode = NULL;
468 }
469
470 return inode;
Miklos Szeredie9be9d52014-10-24 00:14:38 +0200471}