1 /*
2  * Copyright (C) 2017 Red Hat, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 as published by
6  * the Free Software Foundation.
7  */
8 
9 #include <linux/cred.h>
10 #include <linux/file.h>
11 #include <linux/mount.h>
12 #include <linux/xattr.h>
13 #include <linux/uio.h>
14 #include <linux/uaccess.h>
15 #include "overlayfs.h"
16 
ovl_whatisit(struct inode * inode,struct inode * realinode)17 static char ovl_whatisit(struct inode *inode, struct inode *realinode)
18 {
19 	if (realinode != ovl_inode_upper(inode))
20 		return 'l';
21 	if (ovl_has_upperdata(inode))
22 		return 'u';
23 	else
24 		return 'm';
25 }
26 
27 /* No atime modificaton nor notify on underlying */
28 #define OVL_OPEN_FLAGS (O_NOATIME | FMODE_NONOTIFY)
29 
ovl_open_realfile(const struct file * file,struct inode * realinode)30 static struct file *ovl_open_realfile(const struct file *file,
31 				      struct inode *realinode)
32 {
33 	struct inode *inode = file_inode(file);
34 	struct file *realfile;
35 	const struct cred *old_cred;
36 	int flags = file->f_flags | OVL_OPEN_FLAGS;
37 
38 	old_cred = ovl_override_creds(inode->i_sb);
39 	realfile = open_with_fake_path(&file->f_path, flags, realinode,
40 				       current_cred());
41 	revert_creds(old_cred);
42 
43 	pr_debug("open(%p[%pD2/%c], 0%o) -> (%p, 0%o)\n",
44 		 file, file, ovl_whatisit(inode, realinode), file->f_flags,
45 		 realfile, IS_ERR(realfile) ? 0 : realfile->f_flags);
46 
47 	return realfile;
48 }
49 
50 #define OVL_SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT)
51 
ovl_change_flags(struct file * file,unsigned int flags)52 static int ovl_change_flags(struct file *file, unsigned int flags)
53 {
54 	struct inode *inode = file_inode(file);
55 	int err;
56 
57 	flags |= OVL_OPEN_FLAGS;
58 
59 	/* If some flag changed that cannot be changed then something's amiss */
60 	if (WARN_ON((file->f_flags ^ flags) & ~OVL_SETFL_MASK))
61 		return -EIO;
62 
63 	flags &= OVL_SETFL_MASK;
64 
65 	if (((flags ^ file->f_flags) & O_APPEND) && IS_APPEND(inode))
66 		return -EPERM;
67 
68 	if (flags & O_DIRECT) {
69 		if (!file->f_mapping->a_ops ||
70 		    !file->f_mapping->a_ops->direct_IO)
71 			return -EINVAL;
72 	}
73 
74 	if (file->f_op->check_flags) {
75 		err = file->f_op->check_flags(flags);
76 		if (err)
77 			return err;
78 	}
79 
80 	spin_lock(&file->f_lock);
81 	file->f_flags = (file->f_flags & ~OVL_SETFL_MASK) | flags;
82 	spin_unlock(&file->f_lock);
83 
84 	return 0;
85 }
86 
ovl_real_fdget_meta(const struct file * file,struct fd * real,bool allow_meta)87 static int ovl_real_fdget_meta(const struct file *file, struct fd *real,
88 			       bool allow_meta)
89 {
90 	struct inode *inode = file_inode(file);
91 	struct inode *realinode;
92 
93 	real->flags = 0;
94 	real->file = file->private_data;
95 
96 	if (allow_meta)
97 		realinode = ovl_inode_real(inode);
98 	else
99 		realinode = ovl_inode_realdata(inode);
100 
101 	/* Has it been copied up since we'd opened it? */
102 	if (unlikely(file_inode(real->file) != realinode)) {
103 		real->flags = FDPUT_FPUT;
104 		real->file = ovl_open_realfile(file, realinode);
105 
106 		return PTR_ERR_OR_ZERO(real->file);
107 	}
108 
109 	/* Did the flags change since open? */
110 	if (unlikely((file->f_flags ^ real->file->f_flags) & ~OVL_OPEN_FLAGS))
111 		return ovl_change_flags(real->file, file->f_flags);
112 
113 	return 0;
114 }
115 
ovl_real_fdget(const struct file * file,struct fd * real)116 static int ovl_real_fdget(const struct file *file, struct fd *real)
117 {
118 	return ovl_real_fdget_meta(file, real, false);
119 }
120 
ovl_open(struct inode * inode,struct file * file)121 static int ovl_open(struct inode *inode, struct file *file)
122 {
123 	struct file *realfile;
124 	int err;
125 
126 	err = ovl_maybe_copy_up(file_dentry(file), file->f_flags);
127 	if (err)
128 		return err;
129 
130 	/* No longer need these flags, so don't pass them on to underlying fs */
131 	file->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
132 
133 	realfile = ovl_open_realfile(file, ovl_inode_realdata(inode));
134 	if (IS_ERR(realfile))
135 		return PTR_ERR(realfile);
136 
137 	file->private_data = realfile;
138 
139 	return 0;
140 }
141 
ovl_release(struct inode * inode,struct file * file)142 static int ovl_release(struct inode *inode, struct file *file)
143 {
144 	fput(file->private_data);
145 
146 	return 0;
147 }
148 
ovl_llseek(struct file * file,loff_t offset,int whence)149 static loff_t ovl_llseek(struct file *file, loff_t offset, int whence)
150 {
151 	struct inode *inode = file_inode(file);
152 	struct fd real;
153 	const struct cred *old_cred;
154 	loff_t ret;
155 
156 	/*
157 	 * The two special cases below do not need to involve real fs,
158 	 * so we can optimizing concurrent callers.
159 	 */
160 	if (offset == 0) {
161 		if (whence == SEEK_CUR)
162 			return file->f_pos;
163 
164 		if (whence == SEEK_SET)
165 			return vfs_setpos(file, 0, 0);
166 	}
167 
168 	ret = ovl_real_fdget(file, &real);
169 	if (ret)
170 		return ret;
171 
172 	/*
173 	 * Overlay file f_pos is the master copy that is preserved
174 	 * through copy up and modified on read/write, but only real
175 	 * fs knows how to SEEK_HOLE/SEEK_DATA and real fs may impose
176 	 * limitations that are more strict than ->s_maxbytes for specific
177 	 * files, so we use the real file to perform seeks.
178 	 */
179 	inode_lock(inode);
180 	real.file->f_pos = file->f_pos;
181 
182 	old_cred = ovl_override_creds(inode->i_sb);
183 	ret = vfs_llseek(real.file, offset, whence);
184 	revert_creds(old_cred);
185 
186 	file->f_pos = real.file->f_pos;
187 	inode_unlock(inode);
188 
189 	fdput(real);
190 
191 	return ret;
192 }
193 
ovl_file_accessed(struct file * file)194 static void ovl_file_accessed(struct file *file)
195 {
196 	struct inode *inode, *upperinode;
197 
198 	if (file->f_flags & O_NOATIME)
199 		return;
200 
201 	inode = file_inode(file);
202 	upperinode = ovl_inode_upper(inode);
203 
204 	if (!upperinode)
205 		return;
206 
207 	if ((!timespec64_equal(&inode->i_mtime, &upperinode->i_mtime) ||
208 	     !timespec64_equal(&inode->i_ctime, &upperinode->i_ctime))) {
209 		inode->i_mtime = upperinode->i_mtime;
210 		inode->i_ctime = upperinode->i_ctime;
211 	}
212 
213 	touch_atime(&file->f_path);
214 }
215 
ovl_iocb_to_rwf(struct kiocb * iocb)216 static rwf_t ovl_iocb_to_rwf(struct kiocb *iocb)
217 {
218 	int ifl = iocb->ki_flags;
219 	rwf_t flags = 0;
220 
221 	if (ifl & IOCB_NOWAIT)
222 		flags |= RWF_NOWAIT;
223 	if (ifl & IOCB_HIPRI)
224 		flags |= RWF_HIPRI;
225 	if (ifl & IOCB_DSYNC)
226 		flags |= RWF_DSYNC;
227 	if (ifl & IOCB_SYNC)
228 		flags |= RWF_SYNC;
229 
230 	return flags;
231 }
232 
ovl_read_iter(struct kiocb * iocb,struct iov_iter * iter)233 static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
234 {
235 	struct file *file = iocb->ki_filp;
236 	struct fd real;
237 	const struct cred *old_cred;
238 	ssize_t ret;
239 
240 	if (!iov_iter_count(iter))
241 		return 0;
242 
243 	ret = ovl_real_fdget(file, &real);
244 	if (ret)
245 		return ret;
246 
247 	old_cred = ovl_override_creds(file_inode(file)->i_sb);
248 	ret = vfs_iter_read(real.file, iter, &iocb->ki_pos,
249 			    ovl_iocb_to_rwf(iocb));
250 	revert_creds(old_cred);
251 
252 	ovl_file_accessed(file);
253 
254 	fdput(real);
255 
256 	return ret;
257 }
258 
ovl_write_iter(struct kiocb * iocb,struct iov_iter * iter)259 static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
260 {
261 	struct file *file = iocb->ki_filp;
262 	struct inode *inode = file_inode(file);
263 	struct fd real;
264 	const struct cred *old_cred;
265 	ssize_t ret;
266 
267 	if (!iov_iter_count(iter))
268 		return 0;
269 
270 	inode_lock(inode);
271 	/* Update mode */
272 	ovl_copyattr(ovl_inode_real(inode), inode);
273 	ret = file_remove_privs(file);
274 	if (ret)
275 		goto out_unlock;
276 
277 	ret = ovl_real_fdget(file, &real);
278 	if (ret)
279 		goto out_unlock;
280 
281 	old_cred = ovl_override_creds(file_inode(file)->i_sb);
282 	file_start_write(real.file);
283 	ret = vfs_iter_write(real.file, iter, &iocb->ki_pos,
284 			     ovl_iocb_to_rwf(iocb));
285 	file_end_write(real.file);
286 	revert_creds(old_cred);
287 
288 	/* Update size */
289 	ovl_copyattr(ovl_inode_real(inode), inode);
290 
291 	fdput(real);
292 
293 out_unlock:
294 	inode_unlock(inode);
295 
296 	return ret;
297 }
298 
ovl_fsync(struct file * file,loff_t start,loff_t end,int datasync)299 static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
300 {
301 	struct fd real;
302 	const struct cred *old_cred;
303 	int ret;
304 
305 	ret = ovl_real_fdget_meta(file, &real, !datasync);
306 	if (ret)
307 		return ret;
308 
309 	/* Don't sync lower file for fear of receiving EROFS error */
310 	if (file_inode(real.file) == ovl_inode_upper(file_inode(file))) {
311 		old_cred = ovl_override_creds(file_inode(file)->i_sb);
312 		ret = vfs_fsync_range(real.file, start, end, datasync);
313 		revert_creds(old_cred);
314 	}
315 
316 	fdput(real);
317 
318 	return ret;
319 }
320 
ovl_mmap(struct file * file,struct vm_area_struct * vma)321 static int ovl_mmap(struct file *file, struct vm_area_struct *vma)
322 {
323 	struct file *realfile = file->private_data;
324 	const struct cred *old_cred;
325 	int ret;
326 
327 	if (!realfile->f_op->mmap)
328 		return -ENODEV;
329 
330 	if (WARN_ON(file != vma->vm_file))
331 		return -EIO;
332 
333 	vma->vm_file = get_file(realfile);
334 
335 	old_cred = ovl_override_creds(file_inode(file)->i_sb);
336 	ret = call_mmap(vma->vm_file, vma);
337 	revert_creds(old_cred);
338 
339 	if (ret) {
340 		/* Drop reference count from new vm_file value */
341 		fput(realfile);
342 	} else {
343 		/* Drop reference count from previous vm_file value */
344 		fput(file);
345 	}
346 
347 	ovl_file_accessed(file);
348 
349 	return ret;
350 }
351 
ovl_fallocate(struct file * file,int mode,loff_t offset,loff_t len)352 static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
353 {
354 	struct inode *inode = file_inode(file);
355 	struct fd real;
356 	const struct cred *old_cred;
357 	int ret;
358 
359 	ret = ovl_real_fdget(file, &real);
360 	if (ret)
361 		return ret;
362 
363 	old_cred = ovl_override_creds(file_inode(file)->i_sb);
364 	ret = vfs_fallocate(real.file, mode, offset, len);
365 	revert_creds(old_cred);
366 
367 	/* Update size */
368 	ovl_copyattr(ovl_inode_real(inode), inode);
369 
370 	fdput(real);
371 
372 	return ret;
373 }
374 
ovl_fadvise(struct file * file,loff_t offset,loff_t len,int advice)375 static int ovl_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
376 {
377 	struct fd real;
378 	const struct cred *old_cred;
379 	int ret;
380 
381 	ret = ovl_real_fdget(file, &real);
382 	if (ret)
383 		return ret;
384 
385 	old_cred = ovl_override_creds(file_inode(file)->i_sb);
386 	ret = vfs_fadvise(real.file, offset, len, advice);
387 	revert_creds(old_cred);
388 
389 	fdput(real);
390 
391 	return ret;
392 }
393 
ovl_real_ioctl(struct file * file,unsigned int cmd,unsigned long arg)394 static long ovl_real_ioctl(struct file *file, unsigned int cmd,
395 			   unsigned long arg)
396 {
397 	struct fd real;
398 	const struct cred *old_cred;
399 	long ret;
400 
401 	ret = ovl_real_fdget(file, &real);
402 	if (ret)
403 		return ret;
404 
405 	old_cred = ovl_override_creds(file_inode(file)->i_sb);
406 	ret = vfs_ioctl(real.file, cmd, arg);
407 	revert_creds(old_cred);
408 
409 	fdput(real);
410 
411 	return ret;
412 }
413 
ovl_ioctl_set_flags(struct file * file,unsigned int cmd,unsigned long arg,unsigned int iflags)414 static long ovl_ioctl_set_flags(struct file *file, unsigned int cmd,
415 				unsigned long arg, unsigned int iflags)
416 {
417 	long ret;
418 	struct inode *inode = file_inode(file);
419 	unsigned int old_iflags;
420 
421 	if (!inode_owner_or_capable(inode))
422 		return -EACCES;
423 
424 	ret = mnt_want_write_file(file);
425 	if (ret)
426 		return ret;
427 
428 	inode_lock(inode);
429 
430 	/* Check the capability before cred override */
431 	ret = -EPERM;
432 	old_iflags = READ_ONCE(inode->i_flags);
433 	if (((iflags ^ old_iflags) & (S_APPEND | S_IMMUTABLE)) &&
434 	    !capable(CAP_LINUX_IMMUTABLE))
435 		goto unlock;
436 
437 	ret = ovl_maybe_copy_up(file_dentry(file), O_WRONLY);
438 	if (ret)
439 		goto unlock;
440 
441 	ret = ovl_real_ioctl(file, cmd, arg);
442 
443 	ovl_copyflags(ovl_inode_real(inode), inode);
444 unlock:
445 	inode_unlock(inode);
446 
447 	mnt_drop_write_file(file);
448 
449 	return ret;
450 
451 }
452 
ovl_fsflags_to_iflags(unsigned int flags)453 static unsigned int ovl_fsflags_to_iflags(unsigned int flags)
454 {
455 	unsigned int iflags = 0;
456 
457 	if (flags & FS_SYNC_FL)
458 		iflags |= S_SYNC;
459 	if (flags & FS_APPEND_FL)
460 		iflags |= S_APPEND;
461 	if (flags & FS_IMMUTABLE_FL)
462 		iflags |= S_IMMUTABLE;
463 	if (flags & FS_NOATIME_FL)
464 		iflags |= S_NOATIME;
465 
466 	return iflags;
467 }
468 
ovl_ioctl_set_fsflags(struct file * file,unsigned int cmd,unsigned long arg)469 static long ovl_ioctl_set_fsflags(struct file *file, unsigned int cmd,
470 				  unsigned long arg)
471 {
472 	unsigned int flags;
473 
474 	if (get_user(flags, (int __user *) arg))
475 		return -EFAULT;
476 
477 	return ovl_ioctl_set_flags(file, cmd, arg,
478 				   ovl_fsflags_to_iflags(flags));
479 }
480 
ovl_fsxflags_to_iflags(unsigned int xflags)481 static unsigned int ovl_fsxflags_to_iflags(unsigned int xflags)
482 {
483 	unsigned int iflags = 0;
484 
485 	if (xflags & FS_XFLAG_SYNC)
486 		iflags |= S_SYNC;
487 	if (xflags & FS_XFLAG_APPEND)
488 		iflags |= S_APPEND;
489 	if (xflags & FS_XFLAG_IMMUTABLE)
490 		iflags |= S_IMMUTABLE;
491 	if (xflags & FS_XFLAG_NOATIME)
492 		iflags |= S_NOATIME;
493 
494 	return iflags;
495 }
496 
ovl_ioctl_set_fsxflags(struct file * file,unsigned int cmd,unsigned long arg)497 static long ovl_ioctl_set_fsxflags(struct file *file, unsigned int cmd,
498 				   unsigned long arg)
499 {
500 	struct fsxattr fa;
501 
502 	memset(&fa, 0, sizeof(fa));
503 	if (copy_from_user(&fa, (void __user *) arg, sizeof(fa)))
504 		return -EFAULT;
505 
506 	return ovl_ioctl_set_flags(file, cmd, arg,
507 				   ovl_fsxflags_to_iflags(fa.fsx_xflags));
508 }
509 
ovl_ioctl(struct file * file,unsigned int cmd,unsigned long arg)510 static long ovl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
511 {
512 	long ret;
513 
514 	switch (cmd) {
515 	case FS_IOC_GETFLAGS:
516 	case FS_IOC_FSGETXATTR:
517 		ret = ovl_real_ioctl(file, cmd, arg);
518 		break;
519 
520 	case FS_IOC_SETFLAGS:
521 		ret = ovl_ioctl_set_fsflags(file, cmd, arg);
522 		break;
523 
524 	case FS_IOC_FSSETXATTR:
525 		ret = ovl_ioctl_set_fsxflags(file, cmd, arg);
526 		break;
527 
528 	default:
529 		ret = -ENOTTY;
530 	}
531 
532 	return ret;
533 }
534 
ovl_compat_ioctl(struct file * file,unsigned int cmd,unsigned long arg)535 static long ovl_compat_ioctl(struct file *file, unsigned int cmd,
536 			     unsigned long arg)
537 {
538 	switch (cmd) {
539 	case FS_IOC32_GETFLAGS:
540 		cmd = FS_IOC_GETFLAGS;
541 		break;
542 
543 	case FS_IOC32_SETFLAGS:
544 		cmd = FS_IOC_SETFLAGS;
545 		break;
546 
547 	default:
548 		return -ENOIOCTLCMD;
549 	}
550 
551 	return ovl_ioctl(file, cmd, arg);
552 }
553 
554 enum ovl_copyop {
555 	OVL_COPY,
556 	OVL_CLONE,
557 	OVL_DEDUPE,
558 };
559 
ovl_copyfile(struct file * file_in,loff_t pos_in,struct file * file_out,loff_t pos_out,u64 len,unsigned int flags,enum ovl_copyop op)560 static ssize_t ovl_copyfile(struct file *file_in, loff_t pos_in,
561 			    struct file *file_out, loff_t pos_out,
562 			    u64 len, unsigned int flags, enum ovl_copyop op)
563 {
564 	struct inode *inode_out = file_inode(file_out);
565 	struct fd real_in, real_out;
566 	const struct cred *old_cred;
567 	ssize_t ret;
568 
569 	ret = ovl_real_fdget(file_out, &real_out);
570 	if (ret)
571 		return ret;
572 
573 	ret = ovl_real_fdget(file_in, &real_in);
574 	if (ret) {
575 		fdput(real_out);
576 		return ret;
577 	}
578 
579 	old_cred = ovl_override_creds(file_inode(file_out)->i_sb);
580 	switch (op) {
581 	case OVL_COPY:
582 		ret = vfs_copy_file_range(real_in.file, pos_in,
583 					  real_out.file, pos_out, len, flags);
584 		break;
585 
586 	case OVL_CLONE:
587 		ret = vfs_clone_file_range(real_in.file, pos_in,
588 					   real_out.file, pos_out, len);
589 		break;
590 
591 	case OVL_DEDUPE:
592 		ret = vfs_dedupe_file_range_one(real_in.file, pos_in,
593 						real_out.file, pos_out, len);
594 		break;
595 	}
596 	revert_creds(old_cred);
597 
598 	/* Update size */
599 	ovl_copyattr(ovl_inode_real(inode_out), inode_out);
600 
601 	fdput(real_in);
602 	fdput(real_out);
603 
604 	return ret;
605 }
606 
ovl_copy_file_range(struct file * file_in,loff_t pos_in,struct file * file_out,loff_t pos_out,size_t len,unsigned int flags)607 static ssize_t ovl_copy_file_range(struct file *file_in, loff_t pos_in,
608 				   struct file *file_out, loff_t pos_out,
609 				   size_t len, unsigned int flags)
610 {
611 	return ovl_copyfile(file_in, pos_in, file_out, pos_out, len, flags,
612 			    OVL_COPY);
613 }
614 
ovl_clone_file_range(struct file * file_in,loff_t pos_in,struct file * file_out,loff_t pos_out,u64 len)615 static int ovl_clone_file_range(struct file *file_in, loff_t pos_in,
616 				struct file *file_out, loff_t pos_out, u64 len)
617 {
618 	return ovl_copyfile(file_in, pos_in, file_out, pos_out, len, 0,
619 			    OVL_CLONE);
620 }
621 
ovl_dedupe_file_range(struct file * file_in,loff_t pos_in,struct file * file_out,loff_t pos_out,u64 len)622 static int ovl_dedupe_file_range(struct file *file_in, loff_t pos_in,
623 				 struct file *file_out, loff_t pos_out, u64 len)
624 {
625 	/*
626 	 * Don't copy up because of a dedupe request, this wouldn't make sense
627 	 * most of the time (data would be duplicated instead of deduplicated).
628 	 */
629 	if (!ovl_inode_upper(file_inode(file_in)) ||
630 	    !ovl_inode_upper(file_inode(file_out)))
631 		return -EPERM;
632 
633 	return ovl_copyfile(file_in, pos_in, file_out, pos_out, len, 0,
634 			    OVL_DEDUPE);
635 }
636 
637 const struct file_operations ovl_file_operations = {
638 	.open		= ovl_open,
639 	.release	= ovl_release,
640 	.llseek		= ovl_llseek,
641 	.read_iter	= ovl_read_iter,
642 	.write_iter	= ovl_write_iter,
643 	.fsync		= ovl_fsync,
644 	.mmap		= ovl_mmap,
645 	.fallocate	= ovl_fallocate,
646 	.fadvise	= ovl_fadvise,
647 	.unlocked_ioctl	= ovl_ioctl,
648 	.compat_ioctl	= ovl_compat_ioctl,
649 
650 	.copy_file_range	= ovl_copy_file_range,
651 	.clone_file_range	= ovl_clone_file_range,
652 	.dedupe_file_range	= ovl_dedupe_file_range,
653 };
654