From 54bdc6cfb0dd366e3d411e454b1dd113730b58bd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 19 Jan 2018 14:37:13 +0100 Subject: [PATCH] 4.14-stable patches added patches: pipe-avoid-round_pipe_size-nr_pages-overflow-on-32-bit.patch --- ...ipe_size-nr_pages-overflow-on-32-bit.patch | 115 ++++++++++++++++++ queue-4.14/series | 1 + 2 files changed, 116 insertions(+) create mode 100644 queue-4.14/pipe-avoid-round_pipe_size-nr_pages-overflow-on-32-bit.patch diff --git a/queue-4.14/pipe-avoid-round_pipe_size-nr_pages-overflow-on-32-bit.patch b/queue-4.14/pipe-avoid-round_pipe_size-nr_pages-overflow-on-32-bit.patch new file mode 100644 index 00000000000..85dd91d1009 --- /dev/null +++ b/queue-4.14/pipe-avoid-round_pipe_size-nr_pages-overflow-on-32-bit.patch @@ -0,0 +1,115 @@ +From d3f14c485867cfb2e0c48aa88c41d0ef4bf5209c Mon Sep 17 00:00:00 2001 +From: Joe Lawrence +Date: Fri, 17 Nov 2017 15:29:21 -0800 +Subject: pipe: avoid round_pipe_size() nr_pages overflow on 32-bit + +From: Joe Lawrence + +commit d3f14c485867cfb2e0c48aa88c41d0ef4bf5209c upstream. + +round_pipe_size() contains a right-bit-shift expression which may +overflow, which would cause undefined results in a subsequent +roundup_pow_of_two() call. + + static inline unsigned int round_pipe_size(unsigned int size) + { + unsigned long nr_pages; + + nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; + return roundup_pow_of_two(nr_pages) << PAGE_SHIFT; + } + +PAGE_SIZE is defined as (1UL << PAGE_SHIFT), so: + - 4 bytes wide on 32-bit (0 to 0xffffffff) + - 8 bytes wide on 64-bit (0 to 0xffffffffffffffff) + +That means that 32-bit round_pipe_size(), nr_pages may overflow to 0: + + size=0x00000000 nr_pages=0x0 + size=0x00000001 nr_pages=0x1 + size=0xfffff000 nr_pages=0xfffff + size=0xfffff001 nr_pages=0x0 << ! + size=0xffffffff nr_pages=0x0 << ! + +This is bad because roundup_pow_of_two(n) is undefined when n == 0! + +64-bit is not a problem as the unsigned int size is 4 bytes wide +(similar to 32-bit) and the larger, 8 byte wide unsigned long, is +sufficient to handle the largest value of the bit shift expression: + + size=0xffffffff nr_pages=100000 + +Modify round_pipe_size() to return 0 if n == 0 and updates its callers to +handle accordingly. + +Link: http://lkml.kernel.org/r/1507658689-11669-3-git-send-email-joe.lawrence@redhat.com +Signed-off-by: Joe Lawrence +Reported-by: Mikulas Patocka +Reviewed-by: Mikulas Patocka +Cc: Al Viro +Cc: Jens Axboe +Cc: Michael Kerrisk +Cc: Randy Dunlap +Cc: Josh Poimboeuf +Signed-off-by: Andrew Morton +Signed-off-by: Dong Jinguang +Signed-off-by: Linus Torvalds + +Signed-off-by: Greg Kroah-Hartman + +--- + fs/pipe.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +--- a/fs/pipe.c ++++ b/fs/pipe.c +@@ -1018,13 +1018,19 @@ const struct file_operations pipefifo_fo + + /* + * Currently we rely on the pipe array holding a power-of-2 number +- * of pages. ++ * of pages. Returns 0 on error. + */ + static inline unsigned int round_pipe_size(unsigned int size) + { + unsigned long nr_pages; + ++ if (size < pipe_min_size) ++ size = pipe_min_size; ++ + nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ if (nr_pages == 0) ++ return 0; ++ + return roundup_pow_of_two(nr_pages) << PAGE_SHIFT; + } + +@@ -1040,6 +1046,8 @@ static long pipe_set_size(struct pipe_in + long ret = 0; + + size = round_pipe_size(arg); ++ if (size == 0) ++ return -EINVAL; + nr_pages = size >> PAGE_SHIFT; + + if (!nr_pages) +@@ -1123,13 +1131,18 @@ out_revert_acct: + int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf, + size_t *lenp, loff_t *ppos) + { ++ unsigned int rounded_pipe_max_size; + int ret; + + ret = proc_douintvec_minmax(table, write, buf, lenp, ppos); + if (ret < 0 || !write) + return ret; + +- pipe_max_size = round_pipe_size(pipe_max_size); ++ rounded_pipe_max_size = round_pipe_size(pipe_max_size); ++ if (rounded_pipe_max_size == 0) ++ return -EINVAL; ++ ++ pipe_max_size = rounded_pipe_max_size; + return ret; + } + diff --git a/queue-4.14/series b/queue-4.14/series index dff1c545ee4..db595d939be 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -39,3 +39,4 @@ x86-mm-pkeys-fix-fill_sig_info_pkey.patch x86-idt-mark-idt-tables-__initconst.patch x86-tsc-future-proof-native_calibrate_tsc.patch x86-tsc-fix-erroneous-tsc-rate-on-skylake-xeon.patch +pipe-avoid-round_pipe_size-nr_pages-overflow-on-32-bit.patch -- 2.47.3