This commit allows tagged pointers to be passed to the following memory
syscalls: madvise, mbind, get_mempolicy, mincore, mlock, mlock2, brk,
mmap_pgoff, old_mmap, munmap, remap_file_pages, mprotect, pkey_mprotect,
mremap, msync and shmdt.

Signed-off-by: Andrey Konovalov <andreyk...@google.com>
---
 ipc/shm.c      | 2 ++
 mm/madvise.c   | 2 ++
 mm/mempolicy.c | 5 +++++
 mm/migrate.c   | 1 +
 mm/mincore.c   | 2 ++
 mm/mlock.c     | 5 +++++
 mm/mmap.c      | 7 +++++++
 mm/mprotect.c  | 2 ++
 mm/mremap.c    | 2 ++
 mm/msync.c     | 2 ++
 10 files changed, 30 insertions(+)

diff --git a/ipc/shm.c b/ipc/shm.c
index 0842411cb0e9..f0fd9591d28f 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -1567,6 +1567,7 @@ SYSCALL_DEFINE3(shmat, int, shmid, char __user *, 
shmaddr, int, shmflg)
        unsigned long ret;
        long err;
 
+       shmaddr = untagged_addr(shmaddr);
        err = do_shmat(shmid, shmaddr, shmflg, &ret, SHMLBA);
        if (err)
                return err;
@@ -1706,6 +1707,7 @@ long ksys_shmdt(char __user *shmaddr)
 
 SYSCALL_DEFINE1(shmdt, char __user *, shmaddr)
 {
+       shmaddr = untagged_addr(shmaddr);
        return ksys_shmdt(shmaddr);
 }
 
diff --git a/mm/madvise.c b/mm/madvise.c
index 21a7881a2db4..64e6d34a7f9b 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -809,6 +809,8 @@ SYSCALL_DEFINE3(madvise, unsigned long, start, size_t, 
len_in, int, behavior)
        size_t len;
        struct blk_plug plug;
 
+       start = untagged_addr(start);
+
        if (!madvise_behavior_valid(behavior))
                return error;
 
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index ee2bce59d2bf..0b5d5f794f4e 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1334,6 +1334,7 @@ static long kernel_mbind(unsigned long start, unsigned 
long len,
        int err;
        unsigned short mode_flags;
 
+       start = untagged_addr(start);
        mode_flags = mode & MPOL_MODE_FLAGS;
        mode &= ~MPOL_MODE_FLAGS;
        if (mode >= MPOL_MAX)
@@ -1491,6 +1492,8 @@ static int kernel_get_mempolicy(int __user *policy,
        int uninitialized_var(pval);
        nodemask_t nodes;
 
+       addr = untagged_addr(addr);
+
        if (nmask != NULL && maxnode < nr_node_ids)
                return -EINVAL;
 
@@ -1576,6 +1579,8 @@ COMPAT_SYSCALL_DEFINE6(mbind, compat_ulong_t, start, 
compat_ulong_t, len,
        unsigned long nr_bits, alloc_size;
        nodemask_t bm;
 
+       start = untagged_addr(start);
+
        nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES);
        alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
 
diff --git a/mm/migrate.c b/mm/migrate.c
index d4fd680be3b0..b9f414e66af1 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1601,6 +1601,7 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t 
task_nodes,
                if (get_user(node, nodes + i))
                        goto out_flush;
                addr = (unsigned long)p;
+               addr = untagged_addr(addr);
 
                err = -ENODEV;
                if (node < 0 || node >= MAX_NUMNODES)
diff --git a/mm/mincore.c b/mm/mincore.c
index 218099b5ed31..c4a3f4484b6b 100644
--- a/mm/mincore.c
+++ b/mm/mincore.c
@@ -228,6 +228,8 @@ SYSCALL_DEFINE3(mincore, unsigned long, start, size_t, len,
        unsigned long pages;
        unsigned char *tmp;
 
+       start = untagged_addr(start);
+
        /* Check the start address: needs to be page-aligned.. */
        if (start & ~PAGE_MASK)
                return -EINVAL;
diff --git a/mm/mlock.c b/mm/mlock.c
index 41cc47e28ad6..8fa29e7c0e73 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -715,6 +715,7 @@ static __must_check int do_mlock(unsigned long start, 
size_t len, vm_flags_t fla
 
 SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len)
 {
+       start = untagged_addr(start);
        return do_mlock(start, len, VM_LOCKED);
 }
 
@@ -722,6 +723,8 @@ SYSCALL_DEFINE3(mlock2, unsigned long, start, size_t, len, 
int, flags)
 {
        vm_flags_t vm_flags = VM_LOCKED;
 
+       start = untagged_addr(start);
+
        if (flags & ~MLOCK_ONFAULT)
                return -EINVAL;
 
@@ -735,6 +738,8 @@ SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len)
 {
        int ret;
 
+       start = untagged_addr(start);
+
        len = PAGE_ALIGN(len + (offset_in_page(start)));
        start &= PAGE_MASK;
 
diff --git a/mm/mmap.c b/mm/mmap.c
index f901065c4c64..fc8e908a97ba 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -199,6 +199,8 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
        bool downgraded = false;
        LIST_HEAD(uf);
 
+       brk = untagged_addr(brk);
+
        if (down_write_killable(&mm->mmap_sem))
                return -EINTR;
 
@@ -1571,6 +1573,8 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, 
unsigned long len,
        struct file *file = NULL;
        unsigned long retval;
 
+       addr = untagged_addr(addr);
+
        if (!(flags & MAP_ANONYMOUS)) {
                audit_mmap_fd(fd, flags);
                file = fget(fd);
@@ -2869,6 +2873,7 @@ EXPORT_SYMBOL(vm_munmap);
 
 SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
 {
+       addr = untagged_addr(addr);
        profile_munmap(addr);
        return __vm_munmap(addr, len, true);
 }
@@ -2887,6 +2892,8 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, 
unsigned long, size,
        unsigned long ret = -EINVAL;
        struct file *file;
 
+       start = untagged_addr(start);
+
        pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See 
Documentation/vm/remap_file_pages.rst.\n",
                     current->comm, current->pid);
 
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 36cb358db170..9d79594dabee 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -578,6 +578,7 @@ static int do_mprotect_pkey(unsigned long start, size_t len,
 SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len,
                unsigned long, prot)
 {
+       start = untagged_addr(start);
        return do_mprotect_pkey(start, len, prot, -1);
 }
 
@@ -586,6 +587,7 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len,
 SYSCALL_DEFINE4(pkey_mprotect, unsigned long, start, size_t, len,
                unsigned long, prot, int, pkey)
 {
+       start = untagged_addr(start);
        return do_mprotect_pkey(start, len, prot, pkey);
 }
 
diff --git a/mm/mremap.c b/mm/mremap.c
index 3320616ed93f..cd0e79c6ce63 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -588,6 +588,8 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, 
old_len,
        LIST_HEAD(uf_unmap_early);
        LIST_HEAD(uf_unmap);
 
+       addr = untagged_addr(addr);
+
        if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
                return ret;
 
diff --git a/mm/msync.c b/mm/msync.c
index ef30a429623a..c3bd3e75f687 100644
--- a/mm/msync.c
+++ b/mm/msync.c
@@ -37,6 +37,8 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, 
int, flags)
        int unmapped_error = 0;
        int error = -EINVAL;
 
+       start = untagged_addr(start);
+
        if (flags & ~(MS_ASYNC | MS_INVALIDATE | MS_SYNC))
                goto out;
        if (offset_in_page(start))
-- 
2.21.0.rc0.258.g878e2cd30e-goog

Reply via email to