Pull more vfs updates from Al Viro: "Embarrassing braino fix + pipe page accounting + fixing an eyesore in find_filesystem() (checking that s1 is equal to prefix of s2 of given length can be done in many ways, but "compare strlen(s1) with length and then do strncmp()" is not a good one...)" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: [regression] fix braino in fs/dlm/user.c pipe: limit the per-user amount of pages allocated in pipes find_filesystem(): simplify comparison
Unified · Split
| @@ -32,6 +32,8 @@ Currently, these files are in /proc/sys/fs: · 31 unmodified lines | |||
| 32 | - nr_open | 32 | - nr_open |
| 33 | - overflowuid | 33 | - overflowuid |
| 34 | - overflowgid | 34 | - overflowgid |
| 35 | - pipe-user-pages-hard | ||
| 36 | - pipe-user-pages-soft | ||
| 35 | - protected_hardlinks | 37 | - protected_hardlinks |
| 36 | - protected_symlinks | 38 | - protected_symlinks |
| 37 | - suid_dumpable | 39 | - suid_dumpable |
| @@ -159,6 +161,27 @@ The default is 65534. · 121 unmodified lines | |||
| 159 | 161 | ||
| 160 | ============================================================== | 162 | ============================================================== |
| 161 | 163 | ||
| 164 | pipe-user-pages-hard: | ||
| 165 | |||
| 166 | Maximum total number of pages a non-privileged user may allocate for pipes. | ||
| 167 | Once this limit is reached, no new pipes may be allocated until usage goes | ||
| 168 | below the limit again. When set to 0, no limit is applied, which is the default | ||
| 169 | setting. | ||
| 170 | |||
| 171 | ============================================================== | ||
| 172 | |||
| 173 | pipe-user-pages-soft: | ||
| 174 | |||
| 175 | Maximum total number of pages a non-privileged user may allocate for pipes | ||
| 176 | before the pipe size gets limited to a single page. Once this limit is reached, | ||
| 177 | new pipes will be limited to a single page in size for this user in order to | ||
| 178 | limit total memory usage, and trying to increase them using fcntl() will be | ||
| 179 | denied until usage goes below the limit again. The default value allows to | ||
| 180 | allocate up to 1024 pipes at their default size. When set to 0, no limit is | ||
| 181 | applied. | ||
| 182 | |||
| 183 | ============================================================== | ||
| 184 | |||
| 162 | protected_hardlinks: | 185 | protected_hardlinks: |
| 163 | 186 | ||
| 164 | A long-standing class of security issues is the hardlink-based | 187 | A long-standing class of security issues is the hardlink-based |
| @@ -516,7 +516,7 @@ static ssize_t device_write(struct file *file, const char __user *buf, · 515 unmodified lines | |||
| 516 | return -EINVAL; | 516 | return -EINVAL; |
| 517 | 517 | ||
| 518 | kbuf = memdup_user_nul(buf, count); | 518 | kbuf = memdup_user_nul(buf, count); |
| 519 | if (!IS_ERR(kbuf)) | 519 | if (IS_ERR(kbuf)) |
| 520 | return PTR_ERR(kbuf); | 520 | return PTR_ERR(kbuf); |
| 521 | 521 | ||
| 522 | if (check_version(kbuf)) { | 522 | if (check_version(kbuf)) { |
| @@ -46,9 +46,9 @@ void put_filesystem(struct file_system_type *fs) · 45 unmodified lines | |||
| 46 | static struct file_system_type **find_filesystem(const char *name, unsigned len) | 46 | static struct file_system_type **find_filesystem(const char *name, unsigned len) |
| 47 | { | 47 | { |
| 48 | struct file_system_type **p; | 48 | struct file_system_type **p; |
| 49 | for (p=&file_systems; *p; p=&(*p)->next) | 49 | for (p = &file_systems; *p; p = &(*p)->next) |
| 50 | if (strlen((*p)->name) == len && | 50 | if (strncmp((*p)->name, name, len) == 0 && |
| 51 | strncmp((*p)->name, name, len) == 0) | 51 | !(*p)->name[len]) |
| 52 | break; | 52 | break; |
| 53 | return p; | 53 | return p; |
| 54 | } | 54 | } |
| @@ -38,6 +38,12 @@ unsigned int pipe_max_size = 1048576; · 37 unmodified lines | |||
| 38 | */ | 38 | */ |
| 39 | unsigned int pipe_min_size = PAGE_SIZE; | 39 | unsigned int pipe_min_size = PAGE_SIZE; |
| 40 | 40 | ||
| 41 | /* Maximum allocatable pages per user. Hard limit is unset by default, soft | ||
| 42 | * matches default values. | ||
| 43 | */ | ||
| 44 | unsigned long pipe_user_pages_hard; | ||
| 45 | unsigned long pipe_user_pages_soft = PIPE_DEF_BUFFERS * INR_OPEN_CUR; | ||
| 46 | |||
| 41 | /* | 47 | /* |
| 42 | * We use a start+len construction, which provides full use of the | 48 | * We use a start+len construction, which provides full use of the |
| 43 | * allocated memory. | 49 | * allocated memory. |
| @@ -583,20 +589,49 @@ pipe_fasync(int fd, struct file *filp, int on) · 539 unmodified lines | |||
| 583 | return retval; | 589 | return retval; |
| 584 | } | 590 | } |
| 585 | 591 | ||
| 592 | static void account_pipe_buffers(struct pipe_inode_info *pipe, | ||
| 593 | unsigned long old, unsigned long new) | ||
| 594 | { | ||
| 595 | atomic_long_add(new - old, &pipe->user->pipe_bufs); | ||
| 596 | } | ||
| 597 | |||
| 598 | static bool too_many_pipe_buffers_soft(struct user_struct *user) | ||
| 599 | { | ||
| 600 | return pipe_user_pages_soft && | ||
| 601 | atomic_long_read(&user->pipe_bufs) >= pipe_user_pages_soft; | ||
| 602 | } | ||
| 603 | |||
| 604 | static bool too_many_pipe_buffers_hard(struct user_struct *user) | ||
| 605 | { | ||
| 606 | return pipe_user_pages_hard && | ||
| 607 | atomic_long_read(&user->pipe_bufs) >= pipe_user_pages_hard; | ||
| 608 | } | ||
| 609 | |||
| 586 | struct pipe_inode_info *alloc_pipe_info(void) | 610 | struct pipe_inode_info *alloc_pipe_info(void) |
| 587 | { | 611 | { |
| 588 | struct pipe_inode_info *pipe; | 612 | struct pipe_inode_info *pipe; |
| 589 | 613 | ||
| 590 | pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL); | 614 | pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL); |
| 591 | if (pipe) { | 615 | if (pipe) { |
| 592 | pipe->bufs = kzalloc(sizeof(struct pipe_buffer) * PIPE_DEF_BUFFERS, GFP_KERNEL); | 616 | unsigned long pipe_bufs = PIPE_DEF_BUFFERS; |
| 617 | struct user_struct *user = get_current_user(); | ||
| 618 | |||
| 619 | if (!too_many_pipe_buffers_hard(user)) { | ||
| 620 | if (too_many_pipe_buffers_soft(user)) | ||
| 621 | pipe_bufs = 1; | ||
| 622 | pipe->bufs = kzalloc(sizeof(struct pipe_buffer) * pipe_bufs, GFP_KERNEL); | ||
| 623 | } | ||
| 624 | |||
| 593 | if (pipe->bufs) { | 625 | if (pipe->bufs) { |
| 594 | init_waitqueue_head(&pipe->wait); | 626 | init_waitqueue_head(&pipe->wait); |
| 595 | pipe->r_counter = pipe->w_counter = 1; | 627 | pipe->r_counter = pipe->w_counter = 1; |
| 596 | pipe->buffers = PIPE_DEF_BUFFERS; | 628 | pipe->buffers = pipe_bufs; |
| 629 | pipe->user = user; | ||
| 630 | account_pipe_buffers(pipe, 0, pipe_bufs); | ||
| 597 | mutex_init(&pipe->mutex); | 631 | mutex_init(&pipe->mutex); |
| 598 | return pipe; | 632 | return pipe; |
| 599 | } | 633 | } |
| 634 | free_uid(user); | ||
| 600 | kfree(pipe); | 635 | kfree(pipe); |
| 601 | } | 636 | } |
| 602 | 637 | ||
| @@ -607,6 +642,8 @@ void free_pipe_info(struct pipe_inode_info *pipe) · 4 unmodified lines | |||
| 607 | { | 642 | { |
| 608 | int i; | 643 | int i; |
| 609 | 644 | ||
| 645 | account_pipe_buffers(pipe, pipe->buffers, 0); | ||
| 646 | free_uid(pipe->user); | ||
| 610 | for (i = 0; i < pipe->buffers; i++) { | 647 | for (i = 0; i < pipe->buffers; i++) { |
| 611 | struct pipe_buffer *buf = pipe->bufs + i; | 648 | struct pipe_buffer *buf = pipe->bufs + i; |
| 612 | if (buf->ops) | 649 | if (buf->ops) |
| @@ -998,6 +1035,7 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages) · 385 unmodified lines | |||
| 998 | memcpy(bufs + head, pipe->bufs, tail * sizeof(struct pipe_buffer)); | 1035 | memcpy(bufs + head, pipe->bufs, tail * sizeof(struct pipe_buffer)); |
| 999 | } | 1036 | } |
| 1000 | 1037 | ||
| 1038 | account_pipe_buffers(pipe, pipe->buffers, nr_pages); | ||
| 1001 | pipe->curbuf = 0; | 1039 | pipe->curbuf = 0; |
| 1002 | kfree(pipe->bufs); | 1040 | kfree(pipe->bufs); |
| 1003 | pipe->bufs = bufs; | 1041 | pipe->bufs = bufs; |
| @@ -1069,6 +1107,11 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) · 65 unmodified lines | |||
| 1069 | if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) { | 1107 | if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) { |
| 1070 | ret = -EPERM; | 1108 | ret = -EPERM; |
| 1071 | goto out; | 1109 | goto out; |
| 1110 | } else if ((too_many_pipe_buffers_hard(pipe->user) || | ||
| 1111 | too_many_pipe_buffers_soft(pipe->user)) && | ||
| 1112 | !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) { | ||
| 1113 | ret = -EPERM; | ||
| 1114 | goto out; | ||
| 1072 | } | 1115 | } |
| 1073 | ret = pipe_set_size(pipe, nr_pages); | 1116 | ret = pipe_set_size(pipe, nr_pages); |
| 1074 | break; | 1117 | break; |
| @@ -42,6 +42,7 @@ struct pipe_buffer { · 41 unmodified lines | |||
| 42 | * @fasync_readers: reader side fasync | 42 | * @fasync_readers: reader side fasync |
| 43 | * @fasync_writers: writer side fasync | 43 | * @fasync_writers: writer side fasync |
| 44 | * @bufs: the circular array of pipe buffers | 44 | * @bufs: the circular array of pipe buffers |
| 45 | * @user: the user who created this pipe | ||
| 45 | **/ | 46 | **/ |
| 46 | struct pipe_inode_info { | 47 | struct pipe_inode_info { |
| 47 | struct mutex mutex; | 48 | struct mutex mutex; |
| @@ -57,6 +58,7 @@ struct pipe_inode_info { · 9 unmodified lines | |||
| 57 | struct fasync_struct *fasync_readers; | 58 | struct fasync_struct *fasync_readers; |
| 58 | struct fasync_struct *fasync_writers; | 59 | struct fasync_struct *fasync_writers; |
| 59 | struct pipe_buffer *bufs; | 60 | struct pipe_buffer *bufs; |
| 61 | struct user_struct *user; | ||
| 60 | }; | 62 | }; |
| 61 | 63 | ||
| 62 | /* | 64 | /* |
| @@ -123,6 +125,8 @@ void pipe_unlock(struct pipe_inode_info *); · 60 unmodified lines | |||
| 123 | void pipe_double_lock(struct pipe_inode_info *, struct pipe_inode_info *); | 125 | void pipe_double_lock(struct pipe_inode_info *, struct pipe_inode_info *); |
| 124 | 126 | ||
| 125 | extern unsigned int pipe_max_size, pipe_min_size; | 127 | extern unsigned int pipe_max_size, pipe_min_size; |
| 128 | extern unsigned long pipe_user_pages_hard; | ||
| 129 | extern unsigned long pipe_user_pages_soft; | ||
| 126 | int pipe_proc_fn(struct ctl_table *, int, void __user *, size_t *, loff_t *); | 130 | int pipe_proc_fn(struct ctl_table *, int, void __user *, size_t *, loff_t *); |
| 127 | 131 | ||
| 128 | 132 | ||
| @@ -835,6 +835,7 @@ struct user_struct { · 834 unmodified lines | |||
| 835 | #endif | 835 | #endif |
| 836 | unsigned long locked_shm; /* How many pages of mlocked shm ? */ | 836 | unsigned long locked_shm; /* How many pages of mlocked shm ? */ |
| 837 | unsigned long unix_inflight; /* How many files in flight in unix sockets */ | 837 | unsigned long unix_inflight; /* How many files in flight in unix sockets */ |
| 838 | atomic_long_t pipe_bufs; /* how many pages are allocated in pipe buffers */ | ||
| 838 | 839 | ||
| 839 | #ifdef CONFIG_KEYS | 840 | #ifdef CONFIG_KEYS |
| 840 | struct key *uid_keyring; /* UID specific keyring */ | 841 | struct key *uid_keyring; /* UID specific keyring */ |
| @@ -1757,6 +1757,20 @@ static struct ctl_table fs_table[] = { · 1756 unmodified lines | |||
| 1757 | .proc_handler = &pipe_proc_fn, | 1757 | .proc_handler = &pipe_proc_fn, |
| 1758 | .extra1 = &pipe_min_size, | 1758 | .extra1 = &pipe_min_size, |
| 1759 | }, | 1759 | }, |
| 1760 | { | ||
| 1761 | .procname = "pipe-user-pages-hard", | ||
| 1762 | .data = &pipe_user_pages_hard, | ||
| 1763 | .maxlen = sizeof(pipe_user_pages_hard), | ||
| 1764 | .mode = 0644, | ||
| 1765 | .proc_handler = proc_doulongvec_minmax, | ||
| 1766 | }, | ||
| 1767 | { | ||
| 1768 | .procname = "pipe-user-pages-soft", | ||
| 1769 | .data = &pipe_user_pages_soft, | ||
| 1770 | .maxlen = sizeof(pipe_user_pages_soft), | ||
| 1771 | .mode = 0644, | ||
| 1772 | .proc_handler = proc_doulongvec_minmax, | ||
| 1773 | }, | ||
| 1760 | { } | 1774 | { } |
| 1761 | }; | 1775 | }; |
| 1762 | 1776 | ||