diff options
author | Michael Kerrisk (man-pages) <mtk.manpages@gmail.com> | 2016-10-11 16:53:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-11 18:06:31 -0400 |
commit | d37d41666408102bf0ac8e48d8efdce7b809e5f6 (patch) | |
tree | 89a771ab3ac640b7d9371cb922c9f1df14679e70 | |
parent | f491bd71118beba608d39ac2d5f1530e1160cd2e (diff) |
pipe: move limit checking logic into pipe_set_size()
This is a preparatory patch for following work. Move the F_SETPIPE_SZ
limit-checking logic from pipe_fcntl() into pipe_set_size(). This
simplifies the code a little, and allows for reworking required in
a later patch that fixes the limit checking in pipe_set_size()
Link: http://lkml.kernel.org/r/3701b2c5-2c52-2c3e-226d-29b9deb29b50@gmail.com
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
Reviewed-by: Vegard Nossum <vegard.nossum@oracle.com>
Cc: Willy Tarreau <w@1wt.eu>
Cc: <socketpair@gmail.com>
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: Jens Axboe <axboe@fb.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/pipe.c | 41 |
1 files changed, 18 insertions, 23 deletions
@@ -1023,9 +1023,24 @@ static inline unsigned int round_pipe_size(unsigned int size) | |||
1023 | * Allocate a new array of pipe buffers and copy the info over. Returns the | 1023 | * Allocate a new array of pipe buffers and copy the info over. Returns the |
1024 | * pipe size if successful, or return -ERROR on error. | 1024 | * pipe size if successful, or return -ERROR on error. |
1025 | */ | 1025 | */ |
1026 | static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages) | 1026 | static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg) |
1027 | { | 1027 | { |
1028 | struct pipe_buffer *bufs; | 1028 | struct pipe_buffer *bufs; |
1029 | unsigned int size, nr_pages; | ||
1030 | |||
1031 | size = round_pipe_size(arg); | ||
1032 | nr_pages = size >> PAGE_SHIFT; | ||
1033 | |||
1034 | if (!nr_pages) | ||
1035 | return -EINVAL; | ||
1036 | |||
1037 | if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) | ||
1038 | return -EPERM; | ||
1039 | |||
1040 | if ((too_many_pipe_buffers_hard(pipe->user) || | ||
1041 | too_many_pipe_buffers_soft(pipe->user)) && | ||
1042 | !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) | ||
1043 | return -EPERM; | ||
1029 | 1044 | ||
1030 | /* | 1045 | /* |
1031 | * We can shrink the pipe, if arg >= pipe->nrbufs. Since we don't | 1046 | * We can shrink the pipe, if arg >= pipe->nrbufs. Since we don't |
@@ -1109,28 +1124,9 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1109 | __pipe_lock(pipe); | 1124 | __pipe_lock(pipe); |
1110 | 1125 | ||
1111 | switch (cmd) { | 1126 | switch (cmd) { |
1112 | case F_SETPIPE_SZ: { | 1127 | case F_SETPIPE_SZ: |
1113 | unsigned int size, nr_pages; | 1128 | ret = pipe_set_size(pipe, arg); |
1114 | |||
1115 | size = round_pipe_size(arg); | ||
1116 | nr_pages = size >> PAGE_SHIFT; | ||
1117 | |||
1118 | ret = -EINVAL; | ||
1119 | if (!nr_pages) | ||
1120 | goto out; | ||
1121 | |||
1122 | if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) { | ||
1123 | ret = -EPERM; | ||
1124 | goto out; | ||
1125 | } else if ((too_many_pipe_buffers_hard(pipe->user) || | ||
1126 | too_many_pipe_buffers_soft(pipe->user)) && | ||
1127 | !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) { | ||
1128 | ret = -EPERM; | ||
1129 | goto out; | ||
1130 | } | ||
1131 | ret = pipe_set_size(pipe, nr_pages); | ||
1132 | break; | 1129 | break; |
1133 | } | ||
1134 | case F_GETPIPE_SZ: | 1130 | case F_GETPIPE_SZ: |
1135 | ret = pipe->buffers * PAGE_SIZE; | 1131 | ret = pipe->buffers * PAGE_SIZE; |
1136 | break; | 1132 | break; |
@@ -1139,7 +1135,6 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1139 | break; | 1135 | break; |
1140 | } | 1136 | } |
1141 | 1137 | ||
1142 | out: | ||
1143 | __pipe_unlock(pipe); | 1138 | __pipe_unlock(pipe); |
1144 | return ret; | 1139 | return ret; |
1145 | } | 1140 | } |