fs: use rlimit helpers
authorJiri Slaby <jslaby@suse.cz>
Fri, 5 Mar 2010 21:42:42 +0000 (13:42 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 6 Mar 2010 19:26:29 +0000 (11:26 -0800)
Make sure compiler won't do weird things with limits.  E.g.  fetching them
twice may return 2 different values after writable limits are implemented.

I.e.  either use rlimit helpers added in commit 3e10e716abf3 ("resource:
add helpers for fetching rlimits") or ACCESS_ONCE if not applicable.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/attr.c
fs/binfmt_aout.c
fs/binfmt_flat.c
fs/exec.c
fs/fcntl.c
fs/file.c
fs/proc/array.c
fs/select.c

index 0a6ea54..0815e93 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -81,7 +81,7 @@ int inode_newsize_ok(const struct inode *inode, loff_t offset)
        if (inode->i_size < offset) {
                unsigned long limit;
 
        if (inode->i_size < offset) {
                unsigned long limit;
 
-               limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
+               limit = rlimit(RLIMIT_FSIZE);
                if (limit != RLIM_INFINITY && offset > limit)
                        goto out_sig;
                if (offset > inode->i_sb->s_maxbytes)
                if (limit != RLIM_INFINITY && offset > limit)
                        goto out_sig;
                if (offset > inode->i_sb->s_maxbytes)
index fdd3970..61dd00a 100644 (file)
@@ -247,7 +247,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
         * size limits imposed on them by creating programs with large
         * arrays in the data or bss.
         */
         * size limits imposed on them by creating programs with large
         * arrays in the data or bss.
         */
-       rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
+       rlim = rlimit(RLIMIT_DATA);
        if (rlim >= RLIM_INFINITY)
                rlim = ~0;
        if (ex.a_data + ex.a_bss > rlim)
        if (rlim >= RLIM_INFINITY)
                rlim = ~0;
        if (ex.a_data + ex.a_bss > rlim)
index 42c6b4a..e0e769b 100644 (file)
@@ -501,7 +501,7 @@ static int load_flat_file(struct linux_binprm * bprm,
         * size limits imposed on them by creating programs with large
         * arrays in the data or bss.
         */
         * size limits imposed on them by creating programs with large
         * arrays in the data or bss.
         */
-       rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
+       rlim = rlimit(RLIMIT_DATA);
        if (rlim >= RLIM_INFINITY)
                rlim = ~0;
        if (data_len + bss_len > rlim) {
        if (rlim >= RLIM_INFINITY)
                rlim = ~0;
        if (data_len + bss_len > rlim) {
index 5910307..6348d79 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -195,7 +195,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
                 *    to work from.
                 */
                rlim = current->signal->rlim;
                 *    to work from.
                 */
                rlim = current->signal->rlim;
-               if (size > rlim[RLIMIT_STACK].rlim_cur / 4) {
+               if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) {
                        put_page(page);
                        return NULL;
                }
                        put_page(page);
                        return NULL;
                }
@@ -579,7 +579,7 @@ int setup_arg_pages(struct linux_binprm *bprm,
 
 #ifdef CONFIG_STACK_GROWSUP
        /* Limit stack size to 1GB */
 
 #ifdef CONFIG_STACK_GROWSUP
        /* Limit stack size to 1GB */
-       stack_base = current->signal->rlim[RLIMIT_STACK].rlim_max;
+       stack_base = rlimit_max(RLIMIT_STACK);
        if (stack_base > (1 << 30))
                stack_base = 1 << 30;
 
        if (stack_base > (1 << 30))
                stack_base = 1 << 30;
 
@@ -1535,7 +1535,7 @@ static int format_corename(char *corename, long signr)
                        /* core limit size */
                        case 'c':
                                rc = snprintf(out_ptr, out_end - out_ptr,
                        /* core limit size */
                        case 'c':
                                rc = snprintf(out_ptr, out_end - out_ptr,
-                                             "%lu", current->signal->rlim[RLIMIT_CORE].rlim_cur);
+                                             "%lu", rlimit(RLIMIT_CORE));
                                if (rc > out_end - out_ptr)
                                        goto out;
                                out_ptr += rc;
                                if (rc > out_end - out_ptr)
                                        goto out;
                                out_ptr += rc;
@@ -1800,7 +1800,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
        struct coredump_params cprm = {
                .signr = signr,
                .regs = regs,
        struct coredump_params cprm = {
                .signr = signr,
                .regs = regs,
-               .limit = current->signal->rlim[RLIMIT_CORE].rlim_cur,
+               .limit = rlimit(RLIMIT_CORE),
        };
 
        audit_core_dumps(signr);
        };
 
        audit_core_dumps(signr);
index 97e01dc..452d02f 100644 (file)
@@ -344,7 +344,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
        switch (cmd) {
        case F_DUPFD:
        case F_DUPFD_CLOEXEC:
        switch (cmd) {
        case F_DUPFD:
        case F_DUPFD_CLOEXEC:
-               if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
+               if (arg >= rlimit(RLIMIT_NOFILE))
                        break;
                err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
                if (err >= 0) {
                        break;
                err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
                if (err >= 0) {
index 38039af..34bb7f7 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -257,7 +257,7 @@ int expand_files(struct files_struct *files, int nr)
         * N.B. For clone tasks sharing a files structure, this test
         * will limit the total number of files that can be opened.
         */
         * N.B. For clone tasks sharing a files structure, this test
         * will limit the total number of files that can be opened.
         */
-       if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
+       if (nr >= rlimit(RLIMIT_NOFILE))
                return -EMFILE;
 
        /* Do we need to expand? */
                return -EMFILE;
 
        /* Do we need to expand? */
index 18e20fe..aa8637b 100644 (file)
@@ -273,7 +273,7 @@ static inline void task_sig(struct seq_file *m, struct task_struct *p)
                rcu_read_lock();  /* FIXME: is this correct? */
                qsize = atomic_read(&__task_cred(p)->user->sigpending);
                rcu_read_unlock();
                rcu_read_lock();  /* FIXME: is this correct? */
                qsize = atomic_read(&__task_cred(p)->user->sigpending);
                rcu_read_unlock();
-               qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur;
+               qlim = task_rlimit(p, RLIMIT_SIGPENDING);
                unlock_task_sighand(p, &flags);
        }
 
                unlock_task_sighand(p, &flags);
        }
 
@@ -420,7 +420,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
                cutime = sig->cutime;
                cstime = sig->cstime;
                cgtime = sig->cgtime;
                cutime = sig->cutime;
                cstime = sig->cstime;
                cgtime = sig->cgtime;
-               rsslim = sig->rlim[RLIMIT_RSS].rlim_cur;
+               rsslim = ACCESS_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);
 
                /* add up live thread stats at the group level */
                if (whole) {
 
                /* add up live thread stats at the group level */
                if (whole) {
index fd38ce2..73715e9 100644 (file)
@@ -821,7 +821,7 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
        struct poll_list *walk = head;
        unsigned long todo = nfds;
 
        struct poll_list *walk = head;
        unsigned long todo = nfds;
 
-       if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
+       if (nfds > rlimit(RLIMIT_NOFILE))
                return -EINVAL;
 
        len = min_t(unsigned int, nfds, N_STACK_PPS);
                return -EINVAL;
 
        len = min_t(unsigned int, nfds, N_STACK_PPS);