From d6e3c04a4e52818a073c51476f219d2923590d03 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 22 Aug 2004 22:27:17 -0700 Subject: [PATCH] ppc32: remove hardcoded offsets from ppc asm This patch by Vincent Hanquez removes some hard coded offsets for accessing thread info fields from assembly, uses the normal offset generation mecanism that we already have for other things instead. Signed-off-by: Vincent Hanquez Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-ppc/thread_info.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'include/asm-ppc') diff --git a/include/asm-ppc/thread_info.h b/include/asm-ppc/thread_info.h index 62aeec9804ea..340235dfc1c9 100644 --- a/include/asm-ppc/thread_info.h +++ b/include/asm-ppc/thread_info.h @@ -65,16 +65,6 @@ static inline struct thread_info *current_thread_info(void) */ #define THREAD_SIZE 8192 /* 2 pages */ -/* - * Offsets in thread_info structure, used in assembly code - */ -#define TI_TASK 0 -#define TI_EXECDOMAIN 4 -#define TI_FLAGS 8 -#define TI_LOCAL_FLAGS 12 -#define TI_CPU 16 -#define TI_PREEMPT 20 - #define PREEMPT_ACTIVE 0x4000000 /* -- cgit v1.2.3 From 81ca0296edb7b1ab4ea588159cca4cac0215a73e Mon Sep 17 00:00:00 2001 From: Matt Mackall Date: Sun, 22 Aug 2004 22:55:57 -0700 Subject: [PATCH] move duplicate BUG and WARN_ON bits to asm-generic This moves duplicate BUG, PAGE_BUG, BUG_ON, and WARN_ON code to asm-generic and makes them slightly more consistent. This cleanup is also preparatory work for making BUG and WARN verbosity configurable. Signed-off-by: Matt Mackall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-alpha/bug.h | 12 ++---------- include/asm-arm/bug.h | 14 +++----------- include/asm-arm26/bug.h | 17 ++--------------- include/asm-cris/bug.h | 19 +------------------ include/asm-generic/bug.h | 34 ++++++++++++++++++++++++++++++++++ include/asm-h8300/bug.h | 19 +------------------ include/asm-i386/bug.h | 14 ++------------ include/asm-ia64/bug.h | 13 +++---------- include/asm-m68k/bug.h | 17 ++--------------- include/asm-m68knommu/bug.h | 22 +--------------------- include/asm-mips/bug.h | 10 ++-------- include/asm-parisc/bug.h | 27 +-------------------------- include/asm-ppc/bug.h | 7 +++++-- include/asm-ppc64/bug.h | 8 ++++++-- include/asm-s390/bug.h | 19 +++---------------- include/asm-sh/bug.h | 17 ++--------------- include/asm-sparc/bug.h | 17 ++--------------- include/asm-sparc64/bug.h | 19 ++----------------- include/asm-um/bug.h | 28 +--------------------------- include/asm-v850/bug.h | 12 ++---------- include/asm-x86_64/bug.h | 25 +++++++++---------------- 21 files changed, 86 insertions(+), 284 deletions(-) create mode 100644 include/asm-generic/bug.h (limited to 'include/asm-ppc') diff --git a/include/asm-alpha/bug.h b/include/asm-alpha/bug.h index 61bd72ea84b1..ae1e0a5fa492 100644 --- a/include/asm-alpha/bug.h +++ b/include/asm-alpha/bug.h @@ -9,15 +9,7 @@ __asm__ __volatile__("call_pal %0 # bugchk\n\t"".long %1\n\t.8byte %2" \ : : "i" (PAL_bugchk), "i"(__LINE__), "i"(__FILE__)) -#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) - -#define PAGE_BUG(page) BUG() - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) +#define HAVE_ARCH_BUG +#include #endif diff --git a/include/asm-arm/bug.h b/include/asm-arm/bug.h index a1afde728b03..5e91b90a8181 100644 --- a/include/asm-arm/bug.h +++ b/include/asm-arm/bug.h @@ -8,23 +8,15 @@ extern volatile void __bug(const char *file, int line, void *data); /* give file/line information */ #define BUG() __bug(__FILE__, __LINE__, NULL) -#define PAGE_BUG(page) __bug(__FILE__, __LINE__, page) #else -/* these just cause an oops */ +/* this just causes an oops */ #define BUG() (*(int *)0 = 0) -#define PAGE_BUG(page) (*(int *)0 = 0) #endif -#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) +#define HAVE_ARCH_BUG +#include #endif diff --git a/include/asm-arm26/bug.h b/include/asm-arm26/bug.h index a1afde728b03..920b70533368 100644 --- a/include/asm-arm26/bug.h +++ b/include/asm-arm26/bug.h @@ -5,26 +5,13 @@ #ifdef CONFIG_DEBUG_BUGVERBOSE extern volatile void __bug(const char *file, int line, void *data); - /* give file/line information */ #define BUG() __bug(__FILE__, __LINE__, NULL) -#define PAGE_BUG(page) __bug(__FILE__, __LINE__, page) - #else - -/* these just cause an oops */ #define BUG() (*(int *)0 = 0) -#define PAGE_BUG(page) (*(int *)0 = 0) - #endif -#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) +#define HAVE_ARCH_BUG +#include #endif diff --git a/include/asm-cris/bug.h b/include/asm-cris/bug.h index d6286c265cbc..8dd6b23c15d6 100644 --- a/include/asm-cris/bug.h +++ b/include/asm-cris/bug.h @@ -1,21 +1,4 @@ #ifndef _CRIS_BUG_H #define _CRIS_BUG_H - -#define BUG() do { \ - printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ -} while (0) - -#define PAGE_BUG(page) do { \ - BUG(); \ -} while (0) - -#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) - +#include #endif diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h new file mode 100644 index 000000000000..e5913c3b715a --- /dev/null +++ b/include/asm-generic/bug.h @@ -0,0 +1,34 @@ +#ifndef _ASM_GENERIC_BUG_H +#define _ASM_GENERIC_BUG_H + +#include +#include + +#ifndef HAVE_ARCH_BUG +#define BUG() do { \ + printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ + panic("BUG!"); \ +} while (0) +#endif + +#ifndef HAVE_ARCH_PAGE_BUG +#define PAGE_BUG(page) do { \ + printk("page BUG for page at %p\n", page); \ + BUG(); \ +} while (0) +#endif + +#ifndef HAVE_ARCH_BUG_ON +#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) +#endif + +#ifndef HAVE_ARCH_WARN_ON +#define WARN_ON(condition) do { \ + if (unlikely((condition)!=0)) { \ + printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ + dump_stack(); \ + } \ +} while (0) +#endif + +#endif diff --git a/include/asm-h8300/bug.h b/include/asm-h8300/bug.h index 3b6f0102f12e..edddf5b086e5 100644 --- a/include/asm-h8300/bug.h +++ b/include/asm-h8300/bug.h @@ -1,21 +1,4 @@ #ifndef _H8300_BUG_H #define _H8300_BUG_H - -#define BUG() do { \ - printk("%s(%d): kernel BUG!\n", __FILE__, __LINE__); \ -} while (0) - -#define PAGE_BUG(page) do { \ - BUG(); \ -} while (0) - -#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) - +#include #endif diff --git a/include/asm-i386/bug.h b/include/asm-i386/bug.h index 433a6e525d1b..c9f0bf3435d1 100644 --- a/include/asm-i386/bug.h +++ b/include/asm-i386/bug.h @@ -19,17 +19,7 @@ #define BUG() __asm__ __volatile__("ud2\n") #endif -#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) - -#define PAGE_BUG(page) do { \ - BUG(); \ -} while (0) - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) +#define HAVE_ARCH_BUG +#include #endif diff --git a/include/asm-ia64/bug.h b/include/asm-ia64/bug.h index abbf37a444ec..2c0cd51e8856 100644 --- a/include/asm-ia64/bug.h +++ b/include/asm-ia64/bug.h @@ -8,15 +8,8 @@ #endif #define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); ia64_abort(); } while (0) -#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) - -#define PAGE_BUG(page) do { BUG(); } while (0) - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) +/* should this BUG should be made generic? */ +#define HAVE_ARCH_BUG +#include #endif diff --git a/include/asm-m68k/bug.h b/include/asm-m68k/bug.h index 1f21b0d19727..3e1d2266fa69 100644 --- a/include/asm-m68k/bug.h +++ b/include/asm-m68k/bug.h @@ -21,20 +21,7 @@ } while (0) #endif -#define BUG_ON(condition) do { \ - if (unlikely((condition)!=0)) \ - BUG(); \ -} while(0) - -#define PAGE_BUG(page) do { \ - BUG(); \ -} while (0) - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) +#define HAVE_ARCH_BUG +#include #endif diff --git a/include/asm-m68knommu/bug.h b/include/asm-m68knommu/bug.h index bc027eadb9c3..70e7dc0af21a 100644 --- a/include/asm-m68knommu/bug.h +++ b/include/asm-m68knommu/bug.h @@ -1,24 +1,4 @@ #ifndef _M68KNOMMU_BUG_H #define _M68KNOMMU_BUG_H - -#define BUG() do { \ - printk("%s(%d): kernel BUG!\n", __FILE__, __LINE__); \ -} while (0) - -#define BUG_ON(condition) do { \ - if (unlikely((condition)!=0)) \ - BUG(); \ -} while(0) - -#define PAGE_BUG(page) do { \ - BUG(); \ -} while (0) - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) - +#include #endif diff --git a/include/asm-mips/bug.h b/include/asm-mips/bug.h index f1f483d4fc34..eb94bb96cfbc 100644 --- a/include/asm-mips/bug.h +++ b/include/asm-mips/bug.h @@ -7,14 +7,8 @@ do { \ __asm__ __volatile__("break %0" : : "i" (BRK_BUG)); \ } while (0) -#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) -#define PAGE_BUG(page) do { BUG(); } while (0) -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) +#define HAVE_ARCH_BUG +#include #endif diff --git a/include/asm-parisc/bug.h b/include/asm-parisc/bug.h index 00d6aa7f05f5..98d36ad3cf87 100644 --- a/include/asm-parisc/bug.h +++ b/include/asm-parisc/bug.h @@ -1,29 +1,4 @@ #ifndef _PARISC_BUG_H #define _PARISC_BUG_H - -/* - * Tell the user there is some problem. - */ -#define BUG() do { \ - extern void dump_stack(void); \ - printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ - dump_stack(); \ -} while (0) - -#define BUG_ON(condition) do { \ - if (unlikely((condition)!=0)) \ - BUG(); \ -} while(0) - -#define PAGE_BUG(page) do { \ - BUG(); \ -} while (0) - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) - +#include #endif diff --git a/include/asm-ppc/bug.h b/include/asm-ppc/bug.h index 6b2579d9d4ee..e99c6cb9d618 100644 --- a/include/asm-ppc/bug.h +++ b/include/asm-ppc/bug.h @@ -35,8 +35,6 @@ struct bug_entry { } \ } while (0) -#define PAGE_BUG(page) BUG() - #define WARN_ON(x) do { \ if (!__builtin_constant_p(x) || (x)) { \ __asm__ __volatile__( \ @@ -49,4 +47,9 @@ struct bug_entry { } \ } while (0) +#define HAVE_ARCH_BUG +#define HAVE_ARCH_BUG_ON +#define HAVE_ARCH_WARN_ON +#include + #endif diff --git a/include/asm-ppc64/bug.h b/include/asm-ppc64/bug.h index 9e439ee1ed4f..790bc56091d6 100644 --- a/include/asm-ppc64/bug.h +++ b/include/asm-ppc64/bug.h @@ -43,8 +43,6 @@ struct bug_entry { "i" (__FUNCTION__)); \ } while (0) -#define PAGE_BUG(page) do { BUG(); } while (0) - #define WARN_ON(x) do { \ __asm__ __volatile__( \ "1: tdnei %0,0\n" \ @@ -56,4 +54,10 @@ struct bug_entry { } while (0) #endif + +#define HAVE_ARCH_BUG +#define HAVE_ARCH_BUG_ON +#define HAVE_ARCH_WARN_ON +#include + #endif diff --git a/include/asm-s390/bug.h b/include/asm-s390/bug.h index d59639386f7c..2b8d6d4dffcf 100644 --- a/include/asm-s390/bug.h +++ b/include/asm-s390/bug.h @@ -6,22 +6,9 @@ #define BUG() do { \ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ __asm__ __volatile__(".long 0"); \ -} while (0) - -#define BUG_ON(condition) do { \ - if (unlikely((condition)!=0)) \ - BUG(); \ -} while(0) - -#define PAGE_BUG(page) do { \ - BUG(); \ -} while (0) - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ } while (0) +#define HAVE_ARCH_BUG +#include + #endif diff --git a/include/asm-sh/bug.h b/include/asm-sh/bug.h index 0ffc7087c3d3..ea41e17bb959 100644 --- a/include/asm-sh/bug.h +++ b/include/asm-sh/bug.h @@ -11,20 +11,7 @@ asm volatile("nop"); \ } while (0) -#define BUG_ON(condition) do { \ - if (unlikely((condition)!=0)) \ - BUG(); \ -} while(0) - -#define PAGE_BUG(page) do { \ - BUG(); \ -} while (0) - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) +#define HAVE_ARCH_BUG +#include #endif diff --git a/include/asm-sparc/bug.h b/include/asm-sparc/bug.h index 1f321b091141..0d30a67d87a3 100644 --- a/include/asm-sparc/bug.h +++ b/include/asm-sparc/bug.h @@ -25,20 +25,7 @@ extern void do_BUG(const char *file, int line); #define BUG() __bug_trap() #endif -#define BUG_ON(condition) do { \ - if (unlikely((condition)!=0)) \ - BUG(); \ -} while(0) - -#define PAGE_BUG(page) do { \ - BUG(); \ -} while (0) - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) +#define HAVE_ARCH_BUG +#include #endif diff --git a/include/asm-sparc64/bug.h b/include/asm-sparc64/bug.h index bfac1afa9983..25c5b1dfe378 100644 --- a/include/asm-sparc64/bug.h +++ b/include/asm-sparc64/bug.h @@ -1,5 +1,3 @@ -/* $Id$ */ - #ifndef _SPARC64_BUG_H #define _SPARC64_BUG_H @@ -15,20 +13,7 @@ extern void do_BUG(const char *file, int line); #define BUG() __builtin_trap() #endif -#define BUG_ON(condition) do { \ - if (unlikely((condition)!=0)) \ - BUG(); \ -} while(0) - -#define PAGE_BUG(page) do { \ - BUG(); \ -} while (0) - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) +#define HAVE_ARCH_BUG +#include #endif diff --git a/include/asm-um/bug.h b/include/asm-um/bug.h index f5836c5ae760..1e22fa26ff06 100644 --- a/include/asm-um/bug.h +++ b/include/asm-um/bug.h @@ -1,30 +1,4 @@ #ifndef __UM_BUG_H #define __UM_BUG_H - -#ifndef __ASSEMBLY__ - -#define BUG() do { \ - panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ -} while (0) - -#define BUG_ON(condition) do { \ - if (unlikely((condition)!=0)) \ - BUG(); \ -} while(0) - -#define PAGE_BUG(page) do { \ - BUG(); \ -} while (0) - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) - -extern int foo; - -#endif - +#include #endif diff --git a/include/asm-v850/bug.h b/include/asm-v850/bug.h index ce68b9abace6..c778916bf7f2 100644 --- a/include/asm-v850/bug.h +++ b/include/asm-v850/bug.h @@ -16,15 +16,7 @@ extern void __bug (void) __attribute__ ((noreturn)); #define BUG() __bug() -#define PAGE_BUG(page) __bug() - -#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) +#define HAVE_ARCH_BUG +#include #endif /* __V850_BUG_H__ */ diff --git a/include/asm-x86_64/bug.h b/include/asm-x86_64/bug.h index 44d70dea00e7..d2032f56e87c 100644 --- a/include/asm-x86_64/bug.h +++ b/include/asm-x86_64/bug.h @@ -6,27 +6,20 @@ /* * Tell the user there is some problem. The exception handler decodes * this frame. - */ -struct bug_frame { - unsigned char ud2[2]; + */ +struct bug_frame { + unsigned char ud2[2]; /* should use 32bit offset instead, but the assembler doesn't - like it */ - char *filename; - unsigned short line; -} __attribute__((packed)); + like it */ + char *filename; + unsigned short line; +} __attribute__((packed)); +#define HAVE_ARCH_BUG #define BUG() \ asm volatile("ud2 ; .quad %c1 ; .short %c0" :: \ "i"(__LINE__), "i" (__stringify(KBUILD_BASENAME))) -#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) -#define PAGE_BUG(page) BUG() void out_of_line_bug(void); - -#define WARN_ON(condition) do { \ - if (unlikely((condition)!=0)) { \ - printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ - } \ -} while (0) +#include #endif -- cgit v1.2.3 From 16698c49bbb42567c0bbc528d3820d18885e4642 Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Sun, 22 Aug 2004 23:06:46 -0700 Subject: [PATCH] rlimit-based mlocks for unprivileged users Here is the last agreed-on patch that lets normal users mlock pages up to their rlimit. This patch addresses all the issues brought up by Chris and Andrea. From: Chris Wright Couple more nits. The default lockable amount is one page now (first patch is was 0). Why don't we keep it as 0, with the CAP_IPC_LOCK overrides in place? That way nothing is changed from user perspective, and the rest of the policy can be done by userspace as it should. This patch breaks in one scenario. When ulimit == 0, process has CAP_IPC_LOCK, and does SHM_LOCK. The subsequent unlock or destroy will corrupt the locked_shm count. It's also inconsistent in handling user_can_mlock/CAP_IPC_LOCK interaction betwen shm_lock and shm_hugetlb. SHM_HUGETLB can now only be done by the shm_group or CAP_IPC_LOCK. Not any can_do_mlock() user. Double check of can_do_mlock isn't needed in SHM_LOCK path. Interface names user_can_mlock and user_substract_mlock could be better. Incremental update below. Ran some simple sanity tests on this plus my patch below and didn't find any problems. * Make default RLIM_MEMLOCK limit 0. * Move CAP_IPC_LOCK check into user_can_mlock to be consistent and fix but with ulimit == 0 && CAP_IPC_LOCK with SHM_LOCK. * Allow can_do_mlock() user to try SHM_HUGETLB setup. * Remove unecessary extra can_do_mlock() test in shmem_lock(). * Rename user_can_mlock to user_shm_lock and user_subtract_mlock to user_shm_unlock. * Use user instead of current->user to fit in 80 cols on SHM_LOCK. Signed-off-by: Rik van Riel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/hugetlbfs/inode.c | 12 +++++++++--- include/asm-alpha/resource.h | 2 +- include/asm-arm/resource.h | 2 +- include/asm-arm26/resource.h | 2 +- include/asm-cris/resource.h | 2 +- include/asm-h8300/resource.h | 2 +- include/asm-i386/resource.h | 2 +- include/asm-ia64/resource.h | 2 +- include/asm-m68k/resource.h | 2 +- include/asm-parisc/resource.h | 2 +- include/asm-ppc/resource.h | 2 +- include/asm-ppc64/resource.h | 2 +- include/asm-s390/resource.h | 2 +- include/asm-sh/resource.h | 2 +- include/asm-sparc/resource.h | 2 +- include/asm-sparc64/resource.h | 2 +- include/asm-v850/resource.h | 2 +- include/asm-x86_64/resource.h | 2 +- include/linux/mm.h | 13 ++++++++++++- include/linux/sched.h | 1 + include/linux/shm.h | 1 + ipc/shm.c | 36 ++++++++++++++++++++++-------------- kernel/user.c | 4 +++- mm/mlock.c | 41 +++++++++++++++++++++++++++++++++++++---- mm/mmap.c | 14 +++++++++----- mm/mremap.c | 6 ++++-- mm/shmem.c | 15 ++++++++++++--- 27 files changed, 127 insertions(+), 50 deletions(-) (limited to 'include/asm-ppc') diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 90c07ffb7800..d5aa417d8956 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -720,12 +720,13 @@ static unsigned long hugetlbfs_counter(void) static int can_do_hugetlb_shm(void) { return likely(capable(CAP_IPC_LOCK) || - in_group_p(sysctl_hugetlb_shm_group)); + in_group_p(sysctl_hugetlb_shm_group) || + can_do_mlock()); } struct file *hugetlb_zero_setup(size_t size) { - int error; + int error = -ENOMEM; struct file *file; struct inode *inode; struct dentry *dentry, *root; @@ -738,6 +739,9 @@ struct file *hugetlb_zero_setup(size_t size) if (!is_hugepage_mem_enough(size)) return ERR_PTR(-ENOMEM); + if (!user_shm_lock(size, current->user)) + return ERR_PTR(-ENOMEM); + root = hugetlbfs_vfsmount->mnt_root; snprintf(buf, 16, "%lu", hugetlbfs_counter()); quick_string.name = buf; @@ -745,7 +749,7 @@ struct file *hugetlb_zero_setup(size_t size) quick_string.hash = 0; dentry = d_alloc(root, &quick_string); if (!dentry) - return ERR_PTR(-ENOMEM); + goto out_shm_unlock; error = -ENFILE; file = get_empty_filp(); @@ -772,6 +776,8 @@ out_file: put_filp(file); out_dentry: dput(dentry); +out_shm_unlock: + user_shm_unlock(size, current->user); return ERR_PTR(error); } diff --git a/include/asm-alpha/resource.h b/include/asm-alpha/resource.h index b94759c61521..2b0f4bcf2644 100644 --- a/include/asm-alpha/resource.h +++ b/include/asm-alpha/resource.h @@ -41,7 +41,7 @@ {INR_OPEN, INR_OPEN}, /* RLIMIT_NOFILE */ \ {LONG_MAX, LONG_MAX}, /* RLIMIT_AS */ \ {LONG_MAX, LONG_MAX}, /* RLIMIT_NPROC */ \ - {LONG_MAX, LONG_MAX}, /* RLIMIT_MEMLOCK */ \ + {0, 0 }, /* RLIMIT_MEMLOCK */ \ {LONG_MAX, LONG_MAX}, /* RLIMIT_LOCKS */ \ {MAX_SIGPENDING, MAX_SIGPENDING}, /* RLIMIT_SIGPENDING */ \ {MQ_BYTES_MAX, MQ_BYTES_MAX}, /* RLIMIT_MSGQUEUE */ \ diff --git a/include/asm-arm/resource.h b/include/asm-arm/resource.h index 748c660edb15..323167464b97 100644 --- a/include/asm-arm/resource.h +++ b/include/asm-arm/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING}, \ diff --git a/include/asm-arm26/resource.h b/include/asm-arm26/resource.h index 748c660edb15..28a05990277d 100644 --- a/include/asm-arm26/resource.h +++ b/include/asm-arm26/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING}, \ diff --git a/include/asm-cris/resource.h b/include/asm-cris/resource.h index e33ada08d9b8..606a4c9a9579 100644 --- a/include/asm-cris/resource.h +++ b/include/asm-cris/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-h8300/resource.h b/include/asm-h8300/resource.h index a87720b14a90..65cf2c6962f2 100644 --- a/include/asm-h8300/resource.h +++ b/include/asm-h8300/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-i386/resource.h b/include/asm-i386/resource.h index 3e391b2e941f..47bdff24d040 100644 --- a/include/asm-i386/resource.h +++ b/include/asm-i386/resource.h @@ -40,7 +40,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-ia64/resource.h b/include/asm-ia64/resource.h index 76345b5c14c8..c0a403a8a42e 100644 --- a/include/asm-ia64/resource.h +++ b/include/asm-ia64/resource.h @@ -46,7 +46,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-m68k/resource.h b/include/asm-m68k/resource.h index 8362001c286c..51ef4bbb8e6a 100644 --- a/include/asm-m68k/resource.h +++ b/include/asm-m68k/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-parisc/resource.h b/include/asm-parisc/resource.h index 59a446534c5b..ac9de533eb62 100644 --- a/include/asm-parisc/resource.h +++ b/include/asm-parisc/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-ppc/resource.h b/include/asm-ppc/resource.h index 3d29914559fc..a8392167ae6e 100644 --- a/include/asm-ppc/resource.h +++ b/include/asm-ppc/resource.h @@ -36,7 +36,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-ppc64/resource.h b/include/asm-ppc64/resource.h index c54e9d69d829..d23ea5ba1b9b 100644 --- a/include/asm-ppc64/resource.h +++ b/include/asm-ppc64/resource.h @@ -45,7 +45,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-s390/resource.h b/include/asm-s390/resource.h index 5f0f2ba958dd..837ed3ab1275 100644 --- a/include/asm-s390/resource.h +++ b/include/asm-s390/resource.h @@ -47,7 +47,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-sh/resource.h b/include/asm-sh/resource.h index 73e517a3e80f..690f83a92b21 100644 --- a/include/asm-sh/resource.h +++ b/include/asm-sh/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-sparc/resource.h b/include/asm-sparc/resource.h index 58e90f72ca70..098bfa7145f8 100644 --- a/include/asm-sparc/resource.h +++ b/include/asm-sparc/resource.h @@ -44,7 +44,7 @@ { 0, RLIM_INFINITY}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {INR_OPEN, INR_OPEN}, {0, 0}, \ - {RLIM_INFINITY, RLIM_INFINITY}, \ + {0, 0}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {MAX_SIGPENDING, MAX_SIGPENDING}, \ diff --git a/include/asm-sparc64/resource.h b/include/asm-sparc64/resource.h index 4a77dd620621..60afa3362b7f 100644 --- a/include/asm-sparc64/resource.h +++ b/include/asm-sparc64/resource.h @@ -43,7 +43,7 @@ { 0, RLIM_INFINITY}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {INR_OPEN, INR_OPEN}, {0, 0}, \ - {RLIM_INFINITY, RLIM_INFINITY}, \ + {0, 0 }, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {MAX_SIGPENDING, MAX_SIGPENDING}, \ diff --git a/include/asm-v850/resource.h b/include/asm-v850/resource.h index 9f4ca4ae638f..0b757f33dd92 100644 --- a/include/asm-v850/resource.h +++ b/include/asm-v850/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-x86_64/resource.h b/include/asm-x86_64/resource.h index 9628f77179fd..4ed168acafb8 100644 --- a/include/asm-x86_64/resource.h +++ b/include/asm-x86_64/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/linux/mm.h b/include/linux/mm.h index fc8716245294..b7859da6d333 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -496,9 +496,20 @@ int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *new); struct mempolicy *shmem_get_policy(struct vm_area_struct *vma, unsigned long addr); struct file *shmem_file_setup(char * name, loff_t size, unsigned long flags); -void shmem_lock(struct file * file, int lock); +int shmem_lock(struct file *file, int lock, struct user_struct *user); int shmem_zero_setup(struct vm_area_struct *); +static inline int can_do_mlock(void) +{ + if (capable(CAP_IPC_LOCK)) + return 1; + if (current->rlim[RLIMIT_MEMLOCK].rlim_cur != 0) + return 1; + return 0; +} +extern int user_shm_lock(size_t, struct user_struct *); +extern void user_shm_unlock(size_t, struct user_struct *); + /* * Parameter block passed down to zap_pte_range in exceptional cases. */ diff --git a/include/linux/sched.h b/include/linux/sched.h index a01f849da7a5..24066551b966 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -316,6 +316,7 @@ struct user_struct { atomic_t sigpending; /* How many pending signals does this user have? */ /* protected by mq_lock */ unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */ + unsigned long locked_shm; /* How many pages of mlocked shm ? */ /* Hash table maintenance information */ struct list_head uidhash_list; diff --git a/include/linux/shm.h b/include/linux/shm.h index 9a00f5ff6c58..1907355c0eb1 100644 --- a/include/linux/shm.h +++ b/include/linux/shm.h @@ -84,6 +84,7 @@ struct shmid_kernel /* private to the kernel */ time_t shm_ctim; pid_t shm_cprid; pid_t shm_lprid; + struct user_struct *mlock_user; }; /* shm_mode upper byte flags */ diff --git a/ipc/shm.c b/ipc/shm.c index de76c1961367..55dc1ba4229e 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -114,7 +114,10 @@ static void shm_destroy (struct shmid_kernel *shp) shm_rmid (shp->id); shm_unlock(shp); if (!is_file_hugepages(shp->shm_file)) - shmem_lock(shp->shm_file, 0); + shmem_lock(shp->shm_file, 0, shp->mlock_user); + else + user_shm_unlock(shp->shm_file->f_dentry->d_inode->i_size, + shp->mlock_user); fput (shp->shm_file); security_shm_free(shp); ipc_rcu_putref(shp); @@ -190,6 +193,7 @@ static int newseg (key_t key, int shmflg, size_t size) shp->shm_perm.key = key; shp->shm_flags = (shmflg & S_IRWXUGO); + shp->mlock_user = NULL; shp->shm_perm.security = NULL; error = security_shm_alloc(shp); @@ -198,9 +202,11 @@ static int newseg (key_t key, int shmflg, size_t size) return error; } - if (shmflg & SHM_HUGETLB) + if (shmflg & SHM_HUGETLB) { + /* hugetlb_zero_setup takes care of mlock user accounting */ file = hugetlb_zero_setup(size); - else { + shp->mlock_user = current->user; + } else { sprintf (name, "SYSV%08x", key); file = shmem_file_setup(name, size, VM_ACCOUNT); } @@ -504,14 +510,11 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) case SHM_LOCK: case SHM_UNLOCK: { -/* Allow superuser to lock segment in memory */ -/* Should the pages be faulted in here or leave it to user? */ -/* need to determine interaction with current->swappable */ - if (!capable(CAP_IPC_LOCK)) { + /* Allow superuser to lock segment in memory */ + if (!can_do_mlock() && cmd == SHM_LOCK) { err = -EPERM; goto out; } - shp = shm_lock(shmid); if(shp==NULL) { err = -EINVAL; @@ -526,13 +529,18 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) goto out_unlock; if(cmd==SHM_LOCK) { - if (!is_file_hugepages(shp->shm_file)) - shmem_lock(shp->shm_file, 1); - shp->shm_flags |= SHM_LOCKED; - } else { - if (!is_file_hugepages(shp->shm_file)) - shmem_lock(shp->shm_file, 0); + struct user_struct * user = current->user; + if (!is_file_hugepages(shp->shm_file)) { + err = shmem_lock(shp->shm_file, 1, user); + if (!err) { + shp->shm_flags |= SHM_LOCKED; + shp->mlock_user = user; + } + } + } else if (!is_file_hugepages(shp->shm_file)) { + shmem_lock(shp->shm_file, 0, shp->mlock_user); shp->shm_flags &= ~SHM_LOCKED; + shp->mlock_user = NULL; } shm_unlock(shp); goto out; diff --git a/kernel/user.c b/kernel/user.c index 9f9859ef88ea..523175afeecd 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -32,7 +32,8 @@ struct user_struct root_user = { .processes = ATOMIC_INIT(1), .files = ATOMIC_INIT(0), .sigpending = ATOMIC_INIT(0), - .mq_bytes = 0 + .mq_bytes = 0, + .locked_shm = 0, }; /* @@ -113,6 +114,7 @@ struct user_struct * alloc_uid(uid_t uid) atomic_set(&new->sigpending, 0); new->mq_bytes = 0; + new->locked_shm = 0; /* * Before adding this, check whether we raced diff --git a/mm/mlock.c b/mm/mlock.c index a9e37161dcef..b428752c6187 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -60,7 +60,7 @@ static int do_mlock(unsigned long start, size_t len, int on) struct vm_area_struct * vma, * next; int error; - if (on && !capable(CAP_IPC_LOCK)) + if (on && !can_do_mlock()) return -EPERM; len = PAGE_ALIGN(len); end = start + len; @@ -118,7 +118,7 @@ asmlinkage long sys_mlock(unsigned long start, size_t len) lock_limit >>= PAGE_SHIFT; /* check against resource limits */ - if (locked <= lock_limit) + if ( (locked <= lock_limit) || capable(CAP_IPC_LOCK)) error = do_mlock(start, len, 1); up_write(¤t->mm->mmap_sem); return error; @@ -142,7 +142,7 @@ static int do_mlockall(int flags) unsigned int def_flags; struct vm_area_struct * vma; - if (!capable(CAP_IPC_LOCK)) + if (!can_do_mlock()) return -EPERM; def_flags = 0; @@ -177,7 +177,7 @@ asmlinkage long sys_mlockall(int flags) lock_limit >>= PAGE_SHIFT; ret = -ENOMEM; - if (current->mm->total_vm <= lock_limit) + if ((current->mm->total_vm <= lock_limit) || capable(CAP_IPC_LOCK)) ret = do_mlockall(flags); out: up_write(¤t->mm->mmap_sem); @@ -193,3 +193,36 @@ asmlinkage long sys_munlockall(void) up_write(¤t->mm->mmap_sem); return ret; } + +/* + * Objects with different lifetime than processes (SHM_LOCK and SHM_HUGETLB + * shm segments) get accounted against the user_struct instead. + */ +static spinlock_t shmlock_user_lock = SPIN_LOCK_UNLOCKED; + +int user_shm_lock(size_t size, struct user_struct *user) +{ + unsigned long lock_limit, locked; + int allowed = 0; + + spin_lock(&shmlock_user_lock); + locked = size >> PAGE_SHIFT; + lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur; + lock_limit >>= PAGE_SHIFT; + if (locked + user->locked_shm > lock_limit && !capable(CAP_IPC_LOCK)) + goto out; + get_uid(user); + user->locked_shm += locked; + allowed = 1; +out: + spin_unlock(&shmlock_user_lock); + return allowed; +} + +void user_shm_unlock(size_t size, struct user_struct *user) +{ + spin_lock(&shmlock_user_lock); + user->locked_shm -= (size >> PAGE_SHIFT); + spin_unlock(&shmlock_user_lock); + free_uid(user); +} diff --git a/mm/mmap.c b/mm/mmap.c index 3f7495c75228..04dc9e284918 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -796,15 +796,17 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; if (flags & MAP_LOCKED) { - if (!capable(CAP_IPC_LOCK)) + if (!can_do_mlock()) return -EPERM; vm_flags |= VM_LOCKED; } /* mlock MCL_FUTURE? */ if (vm_flags & VM_LOCKED) { - unsigned long locked = mm->locked_vm << PAGE_SHIFT; + unsigned long locked, lock_limit; + locked = mm->locked_vm << PAGE_SHIFT; + lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur; locked += len; - if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur) + if (locked > lock_limit && !capable(CAP_IPC_LOCK)) return -EAGAIN; } @@ -1625,9 +1627,11 @@ unsigned long do_brk(unsigned long addr, unsigned long len) * mlock MCL_FUTURE? */ if (mm->def_flags & VM_LOCKED) { - unsigned long locked = mm->locked_vm << PAGE_SHIFT; + unsigned long locked, lock_limit; + locked = mm->locked_vm << PAGE_SHIFT; + lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur; locked += len; - if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur) + if (locked > lock_limit && !capable(CAP_IPC_LOCK)) return -EAGAIN; } diff --git a/mm/mremap.c b/mm/mremap.c index 984b8ddbd218..6be63314688f 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -324,10 +324,12 @@ unsigned long do_mremap(unsigned long addr, goto out; } if (vma->vm_flags & VM_LOCKED) { - unsigned long locked = current->mm->locked_vm << PAGE_SHIFT; + unsigned long locked, lock_limit; + locked = current->mm->locked_vm << PAGE_SHIFT; + lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur; locked += new_len - old_len; ret = -EAGAIN; - if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur) + if (locked > lock_limit && !capable(CAP_IPC_LOCK)) goto out; } ret = -ENOMEM; diff --git a/mm/shmem.c b/mm/shmem.c index 8ca20e04b60c..c3b4cc5d59ff 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1151,17 +1151,26 @@ shmem_get_policy(struct vm_area_struct *vma, unsigned long addr) } #endif -void shmem_lock(struct file *file, int lock) +int shmem_lock(struct file *file, int lock, struct user_struct *user) { struct inode *inode = file->f_dentry->d_inode; struct shmem_inode_info *info = SHMEM_I(inode); + int retval = -ENOMEM; spin_lock(&info->lock); - if (lock) + if (lock && !(info->flags & VM_LOCKED)) { + if (!user_shm_lock(inode->i_size, user)) + goto out_nomem; info->flags |= VM_LOCKED; - else + } + if (!lock && (info->flags & VM_LOCKED) && user) { + user_shm_unlock(inode->i_size, user); info->flags &= ~VM_LOCKED; + } + retval = 0; +out_nomem: spin_unlock(&info->lock); + return retval; } static int shmem_mmap(struct file *file, struct vm_area_struct *vma) -- cgit v1.2.3 From f947ff8af30f75cb9cf0e966caf8f4809ad1b92e Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Sun, 22 Aug 2004 23:06:58 -0700 Subject: [PATCH] increase per-user mlock limit default to 32k Since various gnupg users have indicated that gpg wants to mlock 32kB of memory, I created the patch below that increases the default mlock ulimit to 32kB. This is no security problem because it's trivial for processes to lock way more memory than this in page tables, network buffers, etc. In fact, since this patch allows gnupg to mlock to prevent passphrase data from being swapped out, the security people will probably like it ;) This gets the new per-user mlock limit a bit more testing, too. Signed-off-by: Rik van Riel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-alpha/resource.h | 2 +- include/asm-arm/resource.h | 2 +- include/asm-arm26/resource.h | 2 +- include/asm-cris/resource.h | 2 +- include/asm-h8300/resource.h | 2 +- include/asm-i386/resource.h | 2 +- include/asm-ia64/resource.h | 2 +- include/asm-m68k/resource.h | 2 +- include/asm-mips/resource.h | 2 +- include/asm-parisc/resource.h | 2 +- include/asm-ppc/resource.h | 2 +- include/asm-ppc64/resource.h | 2 +- include/asm-s390/resource.h | 2 +- include/asm-sh/resource.h | 2 +- include/asm-sparc/resource.h | 2 +- include/asm-sparc64/resource.h | 2 +- include/asm-v850/resource.h | 2 +- include/asm-x86_64/resource.h | 2 +- include/linux/resource.h | 6 ++++++ 19 files changed, 24 insertions(+), 18 deletions(-) (limited to 'include/asm-ppc') diff --git a/include/asm-alpha/resource.h b/include/asm-alpha/resource.h index 2b0f4bcf2644..bfacb0aa27b5 100644 --- a/include/asm-alpha/resource.h +++ b/include/asm-alpha/resource.h @@ -41,7 +41,7 @@ {INR_OPEN, INR_OPEN}, /* RLIMIT_NOFILE */ \ {LONG_MAX, LONG_MAX}, /* RLIMIT_AS */ \ {LONG_MAX, LONG_MAX}, /* RLIMIT_NPROC */ \ - {0, 0 }, /* RLIMIT_MEMLOCK */ \ + {MLOCK_LIMIT, MLOCK_LIMIT }, /* RLIMIT_MEMLOCK */ \ {LONG_MAX, LONG_MAX}, /* RLIMIT_LOCKS */ \ {MAX_SIGPENDING, MAX_SIGPENDING}, /* RLIMIT_SIGPENDING */ \ {MQ_BYTES_MAX, MQ_BYTES_MAX}, /* RLIMIT_MSGQUEUE */ \ diff --git a/include/asm-arm/resource.h b/include/asm-arm/resource.h index 323167464b97..354afada3807 100644 --- a/include/asm-arm/resource.h +++ b/include/asm-arm/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { 0, 0 }, \ + { MLOCK_LIMIT, MLOCK_LIMIT }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING}, \ diff --git a/include/asm-arm26/resource.h b/include/asm-arm26/resource.h index 28a05990277d..354afada3807 100644 --- a/include/asm-arm26/resource.h +++ b/include/asm-arm26/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { 0, 0 }, \ + { MLOCK_LIMIT, MLOCK_LIMIT }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING}, \ diff --git a/include/asm-cris/resource.h b/include/asm-cris/resource.h index 606a4c9a9579..7a83ad536124 100644 --- a/include/asm-cris/resource.h +++ b/include/asm-cris/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { 0, 0 }, \ + { MLOCK_LIMIT, MLOCK_LIMIT }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-h8300/resource.h b/include/asm-h8300/resource.h index 65cf2c6962f2..2031e3ce4bfd 100644 --- a/include/asm-h8300/resource.h +++ b/include/asm-h8300/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { 0, 0 }, \ + { MLOCK_LIMIT, MLOCK_LIMIT }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-i386/resource.h b/include/asm-i386/resource.h index 47bdff24d040..5c3505a4a52e 100644 --- a/include/asm-i386/resource.h +++ b/include/asm-i386/resource.h @@ -40,7 +40,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { 0, 0 }, \ + { MLOCK_LIMIT, MLOCK_LIMIT }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-ia64/resource.h b/include/asm-ia64/resource.h index c0a403a8a42e..52a737eabf24 100644 --- a/include/asm-ia64/resource.h +++ b/include/asm-ia64/resource.h @@ -46,7 +46,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { 0, 0 }, \ + { MLOCK_LIMIT, MLOCK_LIMIT }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-m68k/resource.h b/include/asm-m68k/resource.h index 51ef4bbb8e6a..92a8ff5c8294 100644 --- a/include/asm-m68k/resource.h +++ b/include/asm-m68k/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { 0, 0 }, \ + { MLOCK_LIMIT, MLOCK_LIMIT }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-mips/resource.h b/include/asm-mips/resource.h index 2453e0d1c35c..62e1ce0282f8 100644 --- a/include/asm-mips/resource.h +++ b/include/asm-mips/resource.h @@ -53,7 +53,7 @@ { INR_OPEN, INR_OPEN }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ - { 0, 0 }, \ + { MLOCK_LIMIT, MLOCK_LIMIT }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-parisc/resource.h b/include/asm-parisc/resource.h index ac9de533eb62..491f29e49239 100644 --- a/include/asm-parisc/resource.h +++ b/include/asm-parisc/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { 0, 0 }, \ + { MLOCK_LIMIT, MLOCK_LIMIT }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-ppc/resource.h b/include/asm-ppc/resource.h index a8392167ae6e..2953d9bdc8c5 100644 --- a/include/asm-ppc/resource.h +++ b/include/asm-ppc/resource.h @@ -36,7 +36,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { 0, 0 }, \ + { MLOCK_LIMIT, MLOCK_LIMIT }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-ppc64/resource.h b/include/asm-ppc64/resource.h index d23ea5ba1b9b..f5d6b2e8c659 100644 --- a/include/asm-ppc64/resource.h +++ b/include/asm-ppc64/resource.h @@ -45,7 +45,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { 0, 0 }, \ + { MLOCK_LIMIT, MLOCK_LIMIT }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-s390/resource.h b/include/asm-s390/resource.h index 837ed3ab1275..05720dbdfe89 100644 --- a/include/asm-s390/resource.h +++ b/include/asm-s390/resource.h @@ -47,7 +47,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { 0, 0 }, \ + { MLOCK_LIMIT, MLOCK_LIMIT }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-sh/resource.h b/include/asm-sh/resource.h index 690f83a92b21..bf6152e11561 100644 --- a/include/asm-sh/resource.h +++ b/include/asm-sh/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { 0, 0 }, \ + { MLOCK_LIMIT, MLOCK_LIMIT }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-sparc/resource.h b/include/asm-sparc/resource.h index 098bfa7145f8..d4fb2b4d3b9f 100644 --- a/include/asm-sparc/resource.h +++ b/include/asm-sparc/resource.h @@ -44,7 +44,7 @@ { 0, RLIM_INFINITY}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {INR_OPEN, INR_OPEN}, {0, 0}, \ - {0, 0}, \ + {MLOCK_LIMIT, MLOCK_LIMIT}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {MAX_SIGPENDING, MAX_SIGPENDING}, \ diff --git a/include/asm-sparc64/resource.h b/include/asm-sparc64/resource.h index 60afa3362b7f..f33d38bccab2 100644 --- a/include/asm-sparc64/resource.h +++ b/include/asm-sparc64/resource.h @@ -43,7 +43,7 @@ { 0, RLIM_INFINITY}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {INR_OPEN, INR_OPEN}, {0, 0}, \ - {0, 0 }, \ + { MLOCK_LIMIT, MLOCK_LIMIT}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {MAX_SIGPENDING, MAX_SIGPENDING}, \ diff --git a/include/asm-v850/resource.h b/include/asm-v850/resource.h index 0b757f33dd92..adcbbb896369 100644 --- a/include/asm-v850/resource.h +++ b/include/asm-v850/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { 0, 0 }, \ + { MLOCK_LIMIT, MLOCK_LIMIT }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/asm-x86_64/resource.h b/include/asm-x86_64/resource.h index 4ed168acafb8..f1b71c320934 100644 --- a/include/asm-x86_64/resource.h +++ b/include/asm-x86_64/resource.h @@ -39,7 +39,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { 0, 0 }, \ + { MLOCK_LIMIT, MLOCK_LIMIT }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { MAX_SIGPENDING, MAX_SIGPENDING }, \ diff --git a/include/linux/resource.h b/include/linux/resource.h index 94494789e0af..b930c9cb7727 100644 --- a/include/linux/resource.h +++ b/include/linux/resource.h @@ -55,6 +55,12 @@ struct rlimit { */ #define _STK_LIM (8*1024*1024) +/* + * GPG wants 32kB of mlocked memory, to make sure pass phrases + * and other sensitive information are never written to disk. + */ +#define MLOCK_LIMIT (32*1024) + /* * Due to binary compatibility, the actual resource numbers * may be different for different linux versions.. -- cgit v1.2.3