diff --git a/[refs] b/[refs] index e1ec4f32f944..9d644f23b127 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 35f3d14dbbc58447c61e38a162ea10add6b31dc7 +refs/heads/master: b492e95be0ae672922f4734acf3f5d35c30be948 diff --git a/trunk/fs/pipe.c b/trunk/fs/pipe.c index 054b8a6a2c7a..d79872eba09a 100644 --- a/trunk/fs/pipe.c +++ b/trunk/fs/pipe.c @@ -19,10 +19,17 @@ #include #include #include +#include #include #include +/* + * The max size that a non-root user is allowed to grow the pipe. Can + * be set by root in /proc/sys/fs/pipe-max-pages + */ +unsigned int pipe_max_pages = PIPE_DEF_BUFFERS * 16; + /* * We use a start+len construction, which provides full use of the * allocated memory. @@ -1162,6 +1169,14 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) switch (cmd) { case F_SETPIPE_SZ: + if (!capable(CAP_SYS_ADMIN) && arg > pipe_max_pages) + return -EINVAL; + /* + * The pipe needs to be at least 2 pages large to + * guarantee POSIX behaviour. + */ + if (arg < 2) + return -EINVAL; ret = pipe_set_size(pipe, arg); break; case F_GETPIPE_SZ: diff --git a/trunk/include/linux/pipe_fs_i.h b/trunk/include/linux/pipe_fs_i.h index 65f4282fcbaf..16de3933c45e 100644 --- a/trunk/include/linux/pipe_fs_i.h +++ b/trunk/include/linux/pipe_fs_i.h @@ -139,6 +139,8 @@ void pipe_lock(struct pipe_inode_info *); void pipe_unlock(struct pipe_inode_info *); void pipe_double_lock(struct pipe_inode_info *, struct pipe_inode_info *); +extern unsigned int pipe_max_pages; + /* Drop the inode semaphore and wait for a pipe event, atomically */ void pipe_wait(struct pipe_inode_info *pipe); diff --git a/trunk/kernel/sysctl.c b/trunk/kernel/sysctl.c index 8686b0f5fc12..c649d1c5fe09 100644 --- a/trunk/kernel/sysctl.c +++ b/trunk/kernel/sysctl.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -1423,6 +1424,14 @@ static struct ctl_table fs_table[] = { .child = binfmt_misc_table, }, #endif + { + .procname = "pipe-max-pages", + .data = &pipe_max_pages, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .extra1 = &two, + }, /* * NOTE: do not add new entries to this table unless you have read * Documentation/sysctl/ctl_unnumbered.txt