|
@@ -1018,13 +1018,19 @@ const struct file_operations pipefifo_fops = {
|
|
|
|
|
|
/*
|
|
|
* 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_inode_info *pipe, unsigned long arg)
|
|
|
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;
|
|
|
}
|
|
|
|