diff options
Diffstat (limited to 'fs/pipe.c')
-rw-r--r-- | fs/pipe.c | 17 |
1 files changed, 15 insertions, 2 deletions
@@ -1018,13 +1018,19 @@ const struct file_operations pipefifo_fops = { | |||
1018 | 1018 | ||
1019 | /* | 1019 | /* |
1020 | * Currently we rely on the pipe array holding a power-of-2 number | 1020 | * Currently we rely on the pipe array holding a power-of-2 number |
1021 | * of pages. | 1021 | * of pages. Returns 0 on error. |
1022 | */ | 1022 | */ |
1023 | static inline unsigned int round_pipe_size(unsigned int size) | 1023 | static inline unsigned int round_pipe_size(unsigned int size) |
1024 | { | 1024 | { |
1025 | unsigned long nr_pages; | 1025 | unsigned long nr_pages; |
1026 | 1026 | ||
1027 | if (size < pipe_min_size) | ||
1028 | size = pipe_min_size; | ||
1029 | |||
1027 | nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; | 1030 | nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; |
1031 | if (nr_pages == 0) | ||
1032 | return 0; | ||
1033 | |||
1028 | return roundup_pow_of_two(nr_pages) << PAGE_SHIFT; | 1034 | return roundup_pow_of_two(nr_pages) << PAGE_SHIFT; |
1029 | } | 1035 | } |
1030 | 1036 | ||
@@ -1040,6 +1046,8 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg) | |||
1040 | long ret = 0; | 1046 | long ret = 0; |
1041 | 1047 | ||
1042 | size = round_pipe_size(arg); | 1048 | size = round_pipe_size(arg); |
1049 | if (size == 0) | ||
1050 | return -EINVAL; | ||
1043 | nr_pages = size >> PAGE_SHIFT; | 1051 | nr_pages = size >> PAGE_SHIFT; |
1044 | 1052 | ||
1045 | if (!nr_pages) | 1053 | if (!nr_pages) |
@@ -1123,13 +1131,18 @@ out_revert_acct: | |||
1123 | int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf, | 1131 | int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf, |
1124 | size_t *lenp, loff_t *ppos) | 1132 | size_t *lenp, loff_t *ppos) |
1125 | { | 1133 | { |
1134 | unsigned int rounded_pipe_max_size; | ||
1126 | int ret; | 1135 | int ret; |
1127 | 1136 | ||
1128 | ret = proc_douintvec_minmax(table, write, buf, lenp, ppos); | 1137 | ret = proc_douintvec_minmax(table, write, buf, lenp, ppos); |
1129 | if (ret < 0 || !write) | 1138 | if (ret < 0 || !write) |
1130 | return ret; | 1139 | return ret; |
1131 | 1140 | ||
1132 | pipe_max_size = round_pipe_size(pipe_max_size); | 1141 | rounded_pipe_max_size = round_pipe_size(pipe_max_size); |
1142 | if (rounded_pipe_max_size == 0) | ||
1143 | return -EINVAL; | ||
1144 | |||
1145 | pipe_max_size = rounded_pipe_max_size; | ||
1133 | return ret; | 1146 | return ret; |
1134 | } | 1147 | } |
1135 | 1148 | ||