lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Wed, 14 Nov 2007 14:00:38 -0800 From: William Lee Irwin III <wli@...omorphy.com> To: aglitke <agl@...ibm.com> Cc: ciju@...ux.vnet.ibm.com, linux-kernel@...r.kernel.org Subject: Re: [RFC] [PATCH] hugetlbfs :shmget with SHM_HUGETLB only works as root On Wed, Nov 14, 2007 at 09:31:41AM -0600, aglitke wrote: > ... if the user's locked limit (ulimit -l) is set to unlimited, allowed > (above) is set to 1. In that case, the second part of that if() is > bypassed, and the function grants permission. Therefore, the easy > solution is to make sure your user's lock_limit is RLIM_INFINITY. This function deserves a minor cleanup and a bit more commenting. Reading user->locked_shm within shmlock_user_lock would be nice, too. Maybe something like this (untested, uncompiled) would do. -- wli diff --git a/mm/mlock.c b/mm/mlock.c index 7b26560..5f51792 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -234,6 +234,12 @@ asmlinkage long sys_munlockall(void) /* * Objects with different lifetime than processes (SHM_LOCK and SHM_HUGETLB * shm segments) get accounted against the user_struct instead. + * First, user_shm_lock() checks that the user has permission to lock + * enough memory; then if so, the locked shm is accounted to the user's + * system-wide state. shmlock_user_lock protects the per-user field + * tracking how much locked_shm is in use within the struct user_struct. + * shmlock_user_lock is taken early to guard the read-only check that + * user->locked_shm is in-bounds against updates to user->locked_shm. */ static DEFINE_SPINLOCK(shmlock_user_lock); @@ -242,19 +248,22 @@ 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_SIZE - 1) >> PAGE_SHIFT; lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; if (lock_limit == RLIM_INFINITY) allowed = 1; - lock_limit >>= PAGE_SHIFT; - spin_lock(&shmlock_user_lock); - if (!allowed && - locked + user->locked_shm > lock_limit && !capable(CAP_IPC_LOCK)) - goto out; - get_uid(user); - user->locked_shm += locked; - allowed = 1; -out: + else { + lock_limit >>= PAGE_SHIFT; + if (locked + user->locked_shm <= lock_limit) + allowed = 1; + else if (capable(CAP_IPC_LOCK)) + allowed = 1; + } + if (allowed) { + get_uid(user); + user->locked_shm += locked; + } spin_unlock(&shmlock_user_lock); return allowed; } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists