pipe: cap initial pipe capacity according to pipe-max-size limit

Started by Michael Kerrisk (man-pages) on Aug 19, 2016

Subsystems (2)

Maintainers (3)

DORMANTno replies

open the first message on its own page

Message details and related content
This is an patch that provides behavior that is more consistent,
and probably less surprising to users. I consider the change
optional, and welcome opinions about whether it should be applied.

By default, pipes are created with a capacity of 64 kiB.  However,
/proc/sys/fs/pipe-max-size may be set smaller than this value.  In
this scenario, an unprivileged user could thus create a pipe whose
initial capacity exceeds the limit. Therefore, it seems logical to
cap the initial pipe capacity according to the value of
pipe-max-size.

The test program shown earlier in this patch series can be used to
demonstrate the effect of the change brought about with this
patch:

    # cat /proc/sys/fs/pipe-max-size
    1048576
    # sudo -u mtk ./test_F_SETPIPE_SZ 1
    Initial pipe capacity: 65536
    # echo 10000 > /proc/sys/fs/pipe-max-size
    # cat /proc/sys/fs/pipe-max-size
    16384
    # sudo -u mtk ./test_F_SETPIPE_SZ 1
    Initial pipe capacity: 16384
    # ./test_F_SETPIPE_SZ 1
    Initial pipe capacity: 65536

The last two executions of 'test_F_SETPIPE_SZ' show that pipe-max-size
caps the initial allocation for a new pipe for unprivileged users, but
not for privileged users.

Cc: Willy Tarreau <w@1wt.eu>
Cc: Vegard Nossum <redacted>
Cc: <redacted>
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: Jens Axboe <redacted>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: <redacted>
Cc: <redacted>
Signed-off-by: Michael Kerrisk <redacted>

---
 fs/pipe.c | 3 +++
 1 file changed, 3 insertions(+)
diff --git a/fs/pipe.c b/fs/pipe.c
index ada1777..caced8b 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -631,6 +631,9 @@ struct pipe_inode_info *alloc_pipe_info(void)
 	if (pipe == NULL)
 		goto out_free_uid;
 
+	if (!capable(CAP_SYS_RESOURCE) && pipe_bufs * PAGE_SIZE > pipe_max_size)
+		pipe_bufs = pipe_max_size >> PAGE_SHIFT;
+
 	if (too_many_pipe_buffers_soft(atomic_long_read(&user->pipe_bufs)))
 		pipe_bufs = 1;
 
-- 
2.5.5
Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help