diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-23 22:20:12 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-23 22:20:12 -0400 |
| commit | 33e17876ea4edcd7f5c01efa78e8d02889261abf (patch) | |
| tree | 3b192cd2314bd0e118ca55a2be17693407e176f7 /fs | |
| parent | d475fac95779577afefbad312c8635c29fe4441c (diff) | |
| parent | 2b7403035459c75e193c6b04a293e518a4212de0 (diff) | |
Merge branch 'akpm' (patches from Andrew)
Merge yet more updates from Andrew Morton:
- the rest of MM
- various misc fixes and tweaks
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (22 commits)
mm: Change return type int to vm_fault_t for fault handlers
lib/fonts: convert comments to utf-8
s390: ebcdic: convert comments to UTF-8
treewide: convert ISO_8859-1 text comments to utf-8
drivers/gpu/drm/gma500/: change return type to vm_fault_t
docs/core-api: mm-api: add section about GFP flags
docs/mm: make GFP flags descriptions usable as kernel-doc
docs/core-api: split memory management API to a separate file
docs/core-api: move *{str,mem}dup* to "String Manipulation"
docs/core-api: kill trailing whitespace in kernel-api.rst
mm/util: add kernel-doc for kvfree
mm/util: make strndup_user description a kernel-doc comment
fs/proc/vmcore.c: hide vmcoredd_mmap_dumps() for nommu builds
treewide: correct "differenciate" and "instanciate" typos
fs/afs: use new return type vm_fault_t
drivers/hwtracing/intel_th/msu.c: change return type to vm_fault_t
mm: soft-offline: close the race against page allocation
mm: fix race on soft-offlining free huge pages
namei: allow restricted O_CREAT of FIFOs and regular files
hfs: prevent crash on exit from failed search
...
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/afs/internal.h | 3 | ||||
| -rw-r--r-- | fs/afs/write.c | 2 | ||||
| -rw-r--r-- | fs/hfs/brec.c | 7 | ||||
| -rw-r--r-- | fs/hfsplus/brec.c | 7 | ||||
| -rw-r--r-- | fs/hfsplus/dir.c | 4 | ||||
| -rw-r--r-- | fs/namei.c | 53 | ||||
| -rw-r--r-- | fs/proc/vmcore.c | 2 | ||||
| -rw-r--r-- | fs/userfaultfd.c | 6 |
8 files changed, 67 insertions, 17 deletions
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 9778df135717..871a228d7f37 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/fscache.h> | 21 | #include <linux/fscache.h> |
| 22 | #include <linux/backing-dev.h> | 22 | #include <linux/backing-dev.h> |
| 23 | #include <linux/uuid.h> | 23 | #include <linux/uuid.h> |
| 24 | #include <linux/mm_types.h> | ||
| 24 | #include <net/net_namespace.h> | 25 | #include <net/net_namespace.h> |
| 25 | #include <net/netns/generic.h> | 26 | #include <net/netns/generic.h> |
| 26 | #include <net/sock.h> | 27 | #include <net/sock.h> |
| @@ -1076,7 +1077,7 @@ extern int afs_writepages(struct address_space *, struct writeback_control *); | |||
| 1076 | extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *); | 1077 | extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *); |
| 1077 | extern ssize_t afs_file_write(struct kiocb *, struct iov_iter *); | 1078 | extern ssize_t afs_file_write(struct kiocb *, struct iov_iter *); |
| 1078 | extern int afs_fsync(struct file *, loff_t, loff_t, int); | 1079 | extern int afs_fsync(struct file *, loff_t, loff_t, int); |
| 1079 | extern int afs_page_mkwrite(struct vm_fault *); | 1080 | extern vm_fault_t afs_page_mkwrite(struct vm_fault *vmf); |
| 1080 | extern void afs_prune_wb_keys(struct afs_vnode *); | 1081 | extern void afs_prune_wb_keys(struct afs_vnode *); |
| 1081 | extern int afs_launder_page(struct page *); | 1082 | extern int afs_launder_page(struct page *); |
| 1082 | 1083 | ||
diff --git a/fs/afs/write.c b/fs/afs/write.c index 8b39e6ebb40b..19c04caf3c01 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c | |||
| @@ -753,7 +753,7 @@ int afs_fsync(struct file *file, loff_t start, loff_t end, int datasync) | |||
| 753 | * notification that a previously read-only page is about to become writable | 753 | * notification that a previously read-only page is about to become writable |
| 754 | * - if it returns an error, the caller will deliver a bus error signal | 754 | * - if it returns an error, the caller will deliver a bus error signal |
| 755 | */ | 755 | */ |
| 756 | int afs_page_mkwrite(struct vm_fault *vmf) | 756 | vm_fault_t afs_page_mkwrite(struct vm_fault *vmf) |
| 757 | { | 757 | { |
| 758 | struct file *file = vmf->vma->vm_file; | 758 | struct file *file = vmf->vma->vm_file; |
| 759 | struct inode *inode = file_inode(file); | 759 | struct inode *inode = file_inode(file); |
diff --git a/fs/hfs/brec.c b/fs/hfs/brec.c index ad04a5741016..9a8772465a90 100644 --- a/fs/hfs/brec.c +++ b/fs/hfs/brec.c | |||
| @@ -75,9 +75,10 @@ int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len) | |||
| 75 | if (!fd->bnode) { | 75 | if (!fd->bnode) { |
| 76 | if (!tree->root) | 76 | if (!tree->root) |
| 77 | hfs_btree_inc_height(tree); | 77 | hfs_btree_inc_height(tree); |
| 78 | fd->bnode = hfs_bnode_find(tree, tree->leaf_head); | 78 | node = hfs_bnode_find(tree, tree->leaf_head); |
| 79 | if (IS_ERR(fd->bnode)) | 79 | if (IS_ERR(node)) |
| 80 | return PTR_ERR(fd->bnode); | 80 | return PTR_ERR(node); |
| 81 | fd->bnode = node; | ||
| 81 | fd->record = -1; | 82 | fd->record = -1; |
| 82 | } | 83 | } |
| 83 | new_node = NULL; | 84 | new_node = NULL; |
diff --git a/fs/hfsplus/brec.c b/fs/hfsplus/brec.c index 808f4d8c859c..ed8eacb34452 100644 --- a/fs/hfsplus/brec.c +++ b/fs/hfsplus/brec.c | |||
| @@ -73,9 +73,10 @@ int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len) | |||
| 73 | if (!fd->bnode) { | 73 | if (!fd->bnode) { |
| 74 | if (!tree->root) | 74 | if (!tree->root) |
| 75 | hfs_btree_inc_height(tree); | 75 | hfs_btree_inc_height(tree); |
| 76 | fd->bnode = hfs_bnode_find(tree, tree->leaf_head); | 76 | node = hfs_bnode_find(tree, tree->leaf_head); |
| 77 | if (IS_ERR(fd->bnode)) | 77 | if (IS_ERR(node)) |
| 78 | return PTR_ERR(fd->bnode); | 78 | return PTR_ERR(node); |
| 79 | fd->bnode = node; | ||
| 79 | fd->record = -1; | 80 | fd->record = -1; |
| 80 | } | 81 | } |
| 81 | new_node = NULL; | 82 | new_node = NULL; |
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index c5a70f83dbe7..f37662675c3a 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
| @@ -77,13 +77,13 @@ again: | |||
| 77 | cpu_to_be32(HFSP_HARDLINK_TYPE) && | 77 | cpu_to_be32(HFSP_HARDLINK_TYPE) && |
| 78 | entry.file.user_info.fdCreator == | 78 | entry.file.user_info.fdCreator == |
| 79 | cpu_to_be32(HFSP_HFSPLUS_CREATOR) && | 79 | cpu_to_be32(HFSP_HFSPLUS_CREATOR) && |
| 80 | HFSPLUS_SB(sb)->hidden_dir && | ||
| 80 | (entry.file.create_date == | 81 | (entry.file.create_date == |
| 81 | HFSPLUS_I(HFSPLUS_SB(sb)->hidden_dir)-> | 82 | HFSPLUS_I(HFSPLUS_SB(sb)->hidden_dir)-> |
| 82 | create_date || | 83 | create_date || |
| 83 | entry.file.create_date == | 84 | entry.file.create_date == |
| 84 | HFSPLUS_I(d_inode(sb->s_root))-> | 85 | HFSPLUS_I(d_inode(sb->s_root))-> |
| 85 | create_date) && | 86 | create_date)) { |
| 86 | HFSPLUS_SB(sb)->hidden_dir) { | ||
| 87 | struct qstr str; | 87 | struct qstr str; |
| 88 | char name[32]; | 88 | char name[32]; |
| 89 | 89 | ||
diff --git a/fs/namei.c b/fs/namei.c index ae6aa9ae757c..0cab6494978c 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -887,6 +887,8 @@ static inline void put_link(struct nameidata *nd) | |||
| 887 | 887 | ||
| 888 | int sysctl_protected_symlinks __read_mostly = 0; | 888 | int sysctl_protected_symlinks __read_mostly = 0; |
| 889 | int sysctl_protected_hardlinks __read_mostly = 0; | 889 | int sysctl_protected_hardlinks __read_mostly = 0; |
| 890 | int sysctl_protected_fifos __read_mostly; | ||
| 891 | int sysctl_protected_regular __read_mostly; | ||
| 890 | 892 | ||
| 891 | /** | 893 | /** |
| 892 | * may_follow_link - Check symlink following for unsafe situations | 894 | * may_follow_link - Check symlink following for unsafe situations |
| @@ -1003,6 +1005,45 @@ static int may_linkat(struct path *link) | |||
| 1003 | return -EPERM; | 1005 | return -EPERM; |
| 1004 | } | 1006 | } |
| 1005 | 1007 | ||
| 1008 | /** | ||
| 1009 | * may_create_in_sticky - Check whether an O_CREAT open in a sticky directory | ||
| 1010 | * should be allowed, or not, on files that already | ||
| 1011 | * exist. | ||
| 1012 | * @dir: the sticky parent directory | ||
| 1013 | * @inode: the inode of the file to open | ||
| 1014 | * | ||
| 1015 | * Block an O_CREAT open of a FIFO (or a regular file) when: | ||
| 1016 | * - sysctl_protected_fifos (or sysctl_protected_regular) is enabled | ||
| 1017 | * - the file already exists | ||
| 1018 | * - we are in a sticky directory | ||
| 1019 | * - we don't own the file | ||
| 1020 | * - the owner of the directory doesn't own the file | ||
| 1021 | * - the directory is world writable | ||
| 1022 | * If the sysctl_protected_fifos (or sysctl_protected_regular) is set to 2 | ||
| 1023 | * the directory doesn't have to be world writable: being group writable will | ||
| 1024 | * be enough. | ||
| 1025 | * | ||
| 1026 | * Returns 0 if the open is allowed, -ve on error. | ||
| 1027 | */ | ||
| 1028 | static int may_create_in_sticky(struct dentry * const dir, | ||
| 1029 | struct inode * const inode) | ||
| 1030 | { | ||
| 1031 | if ((!sysctl_protected_fifos && S_ISFIFO(inode->i_mode)) || | ||
| 1032 | (!sysctl_protected_regular && S_ISREG(inode->i_mode)) || | ||
| 1033 | likely(!(dir->d_inode->i_mode & S_ISVTX)) || | ||
| 1034 | uid_eq(inode->i_uid, dir->d_inode->i_uid) || | ||
| 1035 | uid_eq(current_fsuid(), inode->i_uid)) | ||
| 1036 | return 0; | ||
| 1037 | |||
| 1038 | if (likely(dir->d_inode->i_mode & 0002) || | ||
| 1039 | (dir->d_inode->i_mode & 0020 && | ||
| 1040 | ((sysctl_protected_fifos >= 2 && S_ISFIFO(inode->i_mode)) || | ||
| 1041 | (sysctl_protected_regular >= 2 && S_ISREG(inode->i_mode))))) { | ||
| 1042 | return -EACCES; | ||
| 1043 | } | ||
| 1044 | return 0; | ||
| 1045 | } | ||
| 1046 | |||
| 1006 | static __always_inline | 1047 | static __always_inline |
| 1007 | const char *get_link(struct nameidata *nd) | 1048 | const char *get_link(struct nameidata *nd) |
| 1008 | { | 1049 | { |
| @@ -3348,9 +3389,15 @@ finish_open: | |||
| 3348 | if (error) | 3389 | if (error) |
| 3349 | return error; | 3390 | return error; |
| 3350 | audit_inode(nd->name, nd->path.dentry, 0); | 3391 | audit_inode(nd->name, nd->path.dentry, 0); |
| 3351 | error = -EISDIR; | 3392 | if (open_flag & O_CREAT) { |
| 3352 | if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry)) | 3393 | error = -EISDIR; |
| 3353 | goto out; | 3394 | if (d_is_dir(nd->path.dentry)) |
| 3395 | goto out; | ||
| 3396 | error = may_create_in_sticky(dir, | ||
| 3397 | d_backing_inode(nd->path.dentry)); | ||
| 3398 | if (unlikely(error)) | ||
| 3399 | goto out; | ||
| 3400 | } | ||
| 3354 | error = -ENOTDIR; | 3401 | error = -ENOTDIR; |
| 3355 | if ((nd->flags & LOOKUP_DIRECTORY) && !d_can_lookup(nd->path.dentry)) | 3402 | if ((nd->flags & LOOKUP_DIRECTORY) && !d_can_lookup(nd->path.dentry)) |
| 3356 | goto out; | 3403 | goto out; |
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 6c1c2607e9e4..cbde728f8ac6 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c | |||
| @@ -225,6 +225,7 @@ out_unlock: | |||
| 225 | return ret; | 225 | return ret; |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | #ifdef CONFIG_MMU | ||
| 228 | static int vmcoredd_mmap_dumps(struct vm_area_struct *vma, unsigned long dst, | 229 | static int vmcoredd_mmap_dumps(struct vm_area_struct *vma, unsigned long dst, |
| 229 | u64 start, size_t size) | 230 | u64 start, size_t size) |
| 230 | { | 231 | { |
| @@ -259,6 +260,7 @@ out_unlock: | |||
| 259 | mutex_unlock(&vmcoredd_mutex); | 260 | mutex_unlock(&vmcoredd_mutex); |
| 260 | return ret; | 261 | return ret; |
| 261 | } | 262 | } |
| 263 | #endif /* CONFIG_MMU */ | ||
| 262 | #endif /* CONFIG_PROC_VMCORE_DEVICE_DUMP */ | 264 | #endif /* CONFIG_PROC_VMCORE_DEVICE_DUMP */ |
| 263 | 265 | ||
| 264 | /* Read from the ELF header and then the crash dump. On error, negative value is | 266 | /* Read from the ELF header and then the crash dump. On error, negative value is |
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index f649023b19b5..bfa0ec69f924 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c | |||
| @@ -340,17 +340,15 @@ out: | |||
| 340 | * fatal_signal_pending()s, and the mmap_sem must be released before | 340 | * fatal_signal_pending()s, and the mmap_sem must be released before |
| 341 | * returning it. | 341 | * returning it. |
| 342 | */ | 342 | */ |
| 343 | int handle_userfault(struct vm_fault *vmf, unsigned long reason) | 343 | vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason) |
| 344 | { | 344 | { |
| 345 | struct mm_struct *mm = vmf->vma->vm_mm; | 345 | struct mm_struct *mm = vmf->vma->vm_mm; |
| 346 | struct userfaultfd_ctx *ctx; | 346 | struct userfaultfd_ctx *ctx; |
| 347 | struct userfaultfd_wait_queue uwq; | 347 | struct userfaultfd_wait_queue uwq; |
| 348 | int ret; | 348 | vm_fault_t ret = VM_FAULT_SIGBUS; |
| 349 | bool must_wait, return_to_userland; | 349 | bool must_wait, return_to_userland; |
| 350 | long blocking_state; | 350 | long blocking_state; |
| 351 | 351 | ||
| 352 | ret = VM_FAULT_SIGBUS; | ||
| 353 | |||
| 354 | /* | 352 | /* |
| 355 | * We don't do userfault handling for the final child pid update. | 353 | * We don't do userfault handling for the final child pid update. |
| 356 | * | 354 | * |
