summaryrefslogtreecommitdiff
path: root/mm/mmap.c
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2019-06-30 08:49:21 -0700
committerDarrick J. Wong <darrick.wong@oracle.com>2019-06-30 08:49:21 -0700
commit875e1b258e17c8a4549b658987572736bcc9aede (patch)
treefb3621b3af1b4fe20653dc14e784867482c8bb95 /mm/mmap.c
parent8af74d044d73ac24fa7148183d79d79bcaf20bcd (diff)
mm/fs: don't allow writes to immutable filesvfs-make-immutable-consistent-1
The chattr manpage has this to say about immutable files: "A file with the 'i' attribute cannot be modified: it cannot be deleted or renamed, no link can be created to this file, most of the file's metadata can not be modified, and the file can not be opened in write mode." Once the flag is set, it is enforced for quite a few file operations, such as fallocate, fpunch, fzero, rm, touch, open, etc. However, we don't check for immutability when doing a write(), a PROT_WRITE mmap(), a truncate(), or a write to a previously established mmap. If a program has an open write fd to a file that the administrator subsequently marks immutable, the program still can change the file contents. Weird! The ability to write to an immutable file does not follow the manpage promise that immutable files cannot be modified. Worse yet it's inconsistent with the behavior of other syscalls which don't allow modifications of immutable files. Therefore, add the necessary checks to make the write, mmap, and truncate behavior consistent with what the manpage says and consistent with other syscalls on filesystems which support IMMUTABLE. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'mm/mmap.c')
-rw-r--r--mm/mmap.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index 7e8c3e8ae75f..b3ebca2702bf 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1483,8 +1483,12 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
case MAP_SHARED_VALIDATE:
if (flags & ~flags_mask)
return -EOPNOTSUPP;
- if ((prot&PROT_WRITE) && !(file->f_mode&FMODE_WRITE))
- return -EACCES;
+ if (prot & PROT_WRITE) {
+ if (!(file->f_mode & FMODE_WRITE))
+ return -EACCES;
+ if (IS_IMMUTABLE(file->f_mapping->host))
+ return -EPERM;
+ }
/*
* Make sure we don't allow writing to an append-only