aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pipe.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-02-07 01:15:42 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-02-07 01:15:42 -0500
commita2e5790d841658485d642196dbb0927303d6c22f (patch)
treeb3d28c9bcb7da6880806146fd22a88a7ee7f733e /fs/pipe.c
parentab2d92ad881da11331280aedf612d82e61cb6d41 (diff)
parent60c3e026d73ccabb075fb70ba02f8512ab40cf2c (diff)
Merge branch 'akpm' (patches from Andrew)
Merge misc updates from Andrew Morton: - kasan updates - procfs - lib/bitmap updates - other lib/ updates - checkpatch tweaks - rapidio - ubsan - pipe fixes and cleanups - lots of other misc bits * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (114 commits) Documentation/sysctl/user.txt: fix typo MAINTAINERS: update ARM/QUALCOMM SUPPORT patterns MAINTAINERS: update various PALM patterns MAINTAINERS: update "ARM/OXNAS platform support" patterns MAINTAINERS: update Cortina/Gemini patterns MAINTAINERS: remove ARM/CLKDEV SUPPORT file pattern MAINTAINERS: remove ANDROID ION pattern mm: docs: add blank lines to silence sphinx "Unexpected indentation" errors mm: docs: fix parameter names mismatch mm: docs: fixup punctuation pipe: read buffer limits atomically pipe: simplify round_pipe_size() pipe: reject F_SETPIPE_SZ with size over UINT_MAX pipe: fix off-by-one error when checking buffer limits pipe: actually allow root to exceed the pipe buffer limits pipe, sysctl: remove pipe_proc_fn() pipe, sysctl: drop 'min' parameter from pipe-max-size converter kasan: rework Kconfig settings crash_dump: is_kdump_kernel can be boolean kernel/mutex: mutex_is_locked can be boolean ...
Diffstat (limited to 'fs/pipe.c')
-rw-r--r--fs/pipe.c57
1 files changed, 24 insertions, 33 deletions
diff --git a/fs/pipe.c b/fs/pipe.c
index a449ca0ec0c6..0913aed7fd0d 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -35,11 +35,6 @@
35 */ 35 */
36unsigned int pipe_max_size = 1048576; 36unsigned int pipe_max_size = 1048576;
37 37
38/*
39 * Minimum pipe size, as required by POSIX
40 */
41unsigned int pipe_min_size = PAGE_SIZE;
42
43/* Maximum allocatable pages per user. Hard limit is unset by default, soft 38/* Maximum allocatable pages per user. Hard limit is unset by default, soft
44 * matches default values. 39 * matches default values.
45 */ 40 */
@@ -610,12 +605,21 @@ static unsigned long account_pipe_buffers(struct user_struct *user,
610 605
611static bool too_many_pipe_buffers_soft(unsigned long user_bufs) 606static bool too_many_pipe_buffers_soft(unsigned long user_bufs)
612{ 607{
613 return pipe_user_pages_soft && user_bufs >= pipe_user_pages_soft; 608 unsigned long soft_limit = READ_ONCE(pipe_user_pages_soft);
609
610 return soft_limit && user_bufs > soft_limit;
614} 611}
615 612
616static bool too_many_pipe_buffers_hard(unsigned long user_bufs) 613static bool too_many_pipe_buffers_hard(unsigned long user_bufs)
617{ 614{
618 return pipe_user_pages_hard && user_bufs >= pipe_user_pages_hard; 615 unsigned long hard_limit = READ_ONCE(pipe_user_pages_hard);
616
617 return hard_limit && user_bufs > hard_limit;
618}
619
620static bool is_unprivileged_user(void)
621{
622 return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
619} 623}
620 624
621struct pipe_inode_info *alloc_pipe_info(void) 625struct pipe_inode_info *alloc_pipe_info(void)
@@ -624,22 +628,23 @@ struct pipe_inode_info *alloc_pipe_info(void)
624 unsigned long pipe_bufs = PIPE_DEF_BUFFERS; 628 unsigned long pipe_bufs = PIPE_DEF_BUFFERS;
625 struct user_struct *user = get_current_user(); 629 struct user_struct *user = get_current_user();
626 unsigned long user_bufs; 630 unsigned long user_bufs;
631 unsigned int max_size = READ_ONCE(pipe_max_size);
627 632
628 pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL_ACCOUNT); 633 pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL_ACCOUNT);
629 if (pipe == NULL) 634 if (pipe == NULL)
630 goto out_free_uid; 635 goto out_free_uid;
631 636
632 if (pipe_bufs * PAGE_SIZE > pipe_max_size && !capable(CAP_SYS_RESOURCE)) 637 if (pipe_bufs * PAGE_SIZE > max_size && !capable(CAP_SYS_RESOURCE))
633 pipe_bufs = pipe_max_size >> PAGE_SHIFT; 638 pipe_bufs = max_size >> PAGE_SHIFT;
634 639
635 user_bufs = account_pipe_buffers(user, 0, pipe_bufs); 640 user_bufs = account_pipe_buffers(user, 0, pipe_bufs);
636 641
637 if (too_many_pipe_buffers_soft(user_bufs)) { 642 if (too_many_pipe_buffers_soft(user_bufs) && is_unprivileged_user()) {
638 user_bufs = account_pipe_buffers(user, pipe_bufs, 1); 643 user_bufs = account_pipe_buffers(user, pipe_bufs, 1);
639 pipe_bufs = 1; 644 pipe_bufs = 1;
640 } 645 }
641 646
642 if (too_many_pipe_buffers_hard(user_bufs)) 647 if (too_many_pipe_buffers_hard(user_bufs) && is_unprivileged_user())
643 goto out_revert_acct; 648 goto out_revert_acct;
644 649
645 pipe->bufs = kcalloc(pipe_bufs, sizeof(struct pipe_buffer), 650 pipe->bufs = kcalloc(pipe_bufs, sizeof(struct pipe_buffer),
@@ -1020,18 +1025,16 @@ const struct file_operations pipefifo_fops = {
1020 * Currently we rely on the pipe array holding a power-of-2 number 1025 * Currently we rely on the pipe array holding a power-of-2 number
1021 * of pages. Returns 0 on error. 1026 * of pages. Returns 0 on error.
1022 */ 1027 */
1023unsigned int round_pipe_size(unsigned int size) 1028unsigned int round_pipe_size(unsigned long size)
1024{ 1029{
1025 unsigned long nr_pages; 1030 if (size > (1U << 31))
1026
1027 if (size < pipe_min_size)
1028 size = pipe_min_size;
1029
1030 nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
1031 if (nr_pages == 0)
1032 return 0; 1031 return 0;
1033 1032
1034 return roundup_pow_of_two(nr_pages) << PAGE_SHIFT; 1033 /* Minimum pipe size, as required by POSIX */
1034 if (size < PAGE_SIZE)
1035 return PAGE_SIZE;
1036
1037 return roundup_pow_of_two(size);
1035} 1038}
1036 1039
1037/* 1040/*
@@ -1046,8 +1049,6 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
1046 long ret = 0; 1049 long ret = 0;
1047 1050
1048 size = round_pipe_size(arg); 1051 size = round_pipe_size(arg);
1049 if (size == 0)
1050 return -EINVAL;
1051 nr_pages = size >> PAGE_SHIFT; 1052 nr_pages = size >> PAGE_SHIFT;
1052 1053
1053 if (!nr_pages) 1054 if (!nr_pages)
@@ -1069,7 +1070,7 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
1069 if (nr_pages > pipe->buffers && 1070 if (nr_pages > pipe->buffers &&
1070 (too_many_pipe_buffers_hard(user_bufs) || 1071 (too_many_pipe_buffers_hard(user_bufs) ||
1071 too_many_pipe_buffers_soft(user_bufs)) && 1072 too_many_pipe_buffers_soft(user_bufs)) &&
1072 !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) { 1073 is_unprivileged_user()) {
1073 ret = -EPERM; 1074 ret = -EPERM;
1074 goto out_revert_acct; 1075 goto out_revert_acct;
1075 } 1076 }
@@ -1125,16 +1126,6 @@ out_revert_acct:
1125} 1126}
1126 1127
1127/* 1128/*
1128 * This should work even if CONFIG_PROC_FS isn't set, as proc_dopipe_max_size
1129 * will return an error.
1130 */
1131int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
1132 size_t *lenp, loff_t *ppos)
1133{
1134 return proc_dopipe_max_size(table, write, buf, lenp, ppos);
1135}
1136
1137/*
1138 * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same 1129 * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
1139 * location, so checking ->i_pipe is not enough to verify that this is a 1130 * location, so checking ->i_pipe is not enough to verify that this is a
1140 * pipe. 1131 * pipe.