|
@@ -1091,8 +1091,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;
|
|
@@ -1113,8 +1113,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)
|