Skip to content

Commit

Permalink
pipe: set lower and upper limit on max pages in the pipe page array
Browse files Browse the repository at this point in the history
We need at least two to guarantee proper POSIX behaviour, so
never allow a smaller limit than that.

Also expose a /proc/sys/fs/pipe-max-pages sysctl file that allows
root to define a sane upper limit. Make it default to 16 times the
default size, which is 16 pages.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
  • Loading branch information
Jens Axboe committed May 21, 2010
1 parent 35f3d14 commit b492e95
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 0 deletions.
15 changes: 15 additions & 0 deletions fs/pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,17 @@
#include <linux/pagemap.h>
#include <linux/audit.h>
#include <linux/syscalls.h>
#include <linux/fcntl.h>

#include <asm/uaccess.h>
#include <asm/ioctls.h>

/*
* 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.
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 2 additions & 0 deletions include/linux/pipe_fs_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
9 changes: 9 additions & 0 deletions kernel/sysctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#include <linux/slow-work.h>
#include <linux/perf_event.h>
#include <linux/kprobes.h>
#include <linux/pipe_fs_i.h>

#include <asm/uaccess.h>
#include <asm/processor.h>
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit b492e95

Please sign in to comment.