diff options
author | Michael Kerrisk <mtk-lkml@gmx.net> | 2004-11-28 21:38:43 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-11-28 21:38:43 -0800 |
commit | 193aa382b81583beee3b6c2f05f6d012bf8dacec (patch) | |
tree | 1ac5cdf1c6f0a44f945ff09ac65fd960788415b5 /mm | |
parent | 8b92757dc223d2eddf8beb914bd5266bc8d8fc96 (diff) | |
download | history-193aa382b81583beee3b6c2f05f6d012bf8dacec.tar.gz |
[PATCH] RLIMIT_MEMLOCK accounting of shmctl() SHM_LOCK is broken
The accounting of shmctl() SHM_LOCK memory locks against the user
structure is broken. The check of the size of the to-be-locked region
is based on the size of the segment as specified when it was created by
shmget() (this size is *not* rounded up to a page boundary).
Fix it by rounding the size properlt. Also, tune up the spinlock
coverage in there a little.
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/mlock.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/mm/mlock.c b/mm/mlock.c index 4a00277487bad9..a75902f0485efc 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -211,10 +211,10 @@ 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; + locked = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; lock_limit >>= PAGE_SHIFT; + spin_lock(&shmlock_user_lock); if (locked + user->locked_shm > lock_limit && !capable(CAP_IPC_LOCK)) goto out; get_uid(user); @@ -228,7 +228,7 @@ out: void user_shm_unlock(size_t size, struct user_struct *user) { spin_lock(&shmlock_user_lock); - user->locked_shm -= (size >> PAGE_SHIFT); + user->locked_shm -= (size + PAGE_SIZE - 1) >> PAGE_SHIFT; spin_unlock(&shmlock_user_lock); free_uid(user); } |