aboutsummaryrefslogtreecommitdiff
path: root/ipc/shm.c
diff options
context:
space:
mode:
authorAlex Shi <alex.shi@linaro.org>2017-03-20 12:03:13 +0800
committerAlex Shi <alex.shi@linaro.org>2017-03-20 12:03:13 +0800
commit89e7fad96be88f30f491bf227d864bf5e8e701b2 (patch)
tree6316161ebd26b780991ff8632471fbbfa3af7ea8 /ipc/shm.c
parent5b0250d2571ee75ca3c0b34579c3e90bc2bd9c6a (diff)
parent1c563c0006661025d7a6c9bc85fc889a4e8a1c06 (diff)
Diffstat (limited to 'ipc/shm.c')
-rw-r--r--ipc/shm.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/ipc/shm.c b/ipc/shm.c
index 3174634ca4e5..4982a4e7f009 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -1083,8 +1083,8 @@ out_unlock1:
* "raddr" thing points to kernel space, and there has to be a wrapper around
* this.
*/
-long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
- unsigned long shmlba)
+long do_shmat(int shmid, char __user *shmaddr, int shmflg,
+ ulong *raddr, unsigned long shmlba)
{
struct shmid_kernel *shp;
unsigned long addr;
@@ -1105,8 +1105,13 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
goto out;
else if ((addr = (ulong)shmaddr)) {
if (addr & (shmlba - 1)) {
- if (shmflg & SHM_RND)
- addr &= ~(shmlba - 1); /* round down */
+ /*
+ * Round down to the nearest multiple of shmlba.
+ * For sane do_mmap_pgoff() parameters, avoid
+ * round downs that trigger nil-page and MAP_FIXED.
+ */
+ if ((shmflg & SHM_RND) && addr >= shmlba)
+ addr &= ~(shmlba - 1);
else
#ifndef __ARCH_FORCE_SHMLBA
if (addr & ~PAGE_MASK)