Commit 193aa382 authored by Michael Kerrisk's avatar Michael Kerrisk Committed by Linus Torvalds

[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: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 8b92757d
......@@ -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 @@ int user_shm_lock(size_t size, struct user_struct *user)
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);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment