]> git.baikalelectronics.ru Git - kernel.git/commitdiff
mm/mempolicy: unify the parameter sanity check for mbind and set_mempolicy
authorFeng Tang <feng.tang@intel.com>
Thu, 1 Jul 2021 01:51:03 +0000 (18:51 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 1 Jul 2021 03:47:29 +0000 (20:47 -0700)
Currently the kernel_mbind() and kernel_set_mempolicy() do almost the same
operation for parameter sanity check.

Add a helper function to unify the code to reduce the redundancy, and make
it easier for changing the sanity check code in future.

[thanks to David Rientjes for suggesting using helper function instead of
macro].

[feng.tang@intel.com: add comment]
Link: https://lkml.kernel.org/r/1622560492-1294-4-git-send-email-feng.tang@intel.com
Link: https://lkml.kernel.org/r/1622469956-82897-4-git-send-email-feng.tang@intel.com
Signed-off-by: Feng Tang <feng.tang@intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Ben Widawsky <ben.widawsky@intel.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Huang Ying <ying.huang@intel.com>
Cc: Michal Hocko <mhocko@suse.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/mempolicy.c

index 22addae6c4eee248a6c94417161807b46157d5a4..89721501b22cb1ab3203f4f6fc3dd03d4a756eea 100644 (file)
@@ -1441,26 +1441,38 @@ static int copy_nodes_to_user(unsigned long __user *mask, unsigned long maxnode,
        return copy_to_user(mask, nodes_addr(*nodes), copy) ? -EFAULT : 0;
 }
 
+/* Basic parameter sanity check used by both mbind() and set_mempolicy() */
+static inline int sanitize_mpol_flags(int *mode, unsigned short *flags)
+{
+       *flags = *mode & MPOL_MODE_FLAGS;
+       *mode &= ~MPOL_MODE_FLAGS;
+       if ((unsigned int)(*mode) >= MPOL_MAX)
+               return -EINVAL;
+       if ((*flags & MPOL_F_STATIC_NODES) && (*flags & MPOL_F_RELATIVE_NODES))
+               return -EINVAL;
+
+       return 0;
+}
+
 static long kernel_mbind(unsigned long start, unsigned long len,
                         unsigned long mode, const unsigned long __user *nmask,
                         unsigned long maxnode, unsigned int flags)
 {
+       unsigned short mode_flags;
        nodemask_t nodes;
+       int lmode = mode;
        int err;
-       unsigned short mode_flags;
 
        start = untagged_addr(start);
-       mode_flags = mode & MPOL_MODE_FLAGS;
-       mode &= ~MPOL_MODE_FLAGS;
-       if (mode >= MPOL_MAX)
-               return -EINVAL;
-       if ((mode_flags & MPOL_F_STATIC_NODES) &&
-           (mode_flags & MPOL_F_RELATIVE_NODES))
-               return -EINVAL;
+       err = sanitize_mpol_flags(&lmode, &mode_flags);
+       if (err)
+               return err;
+
        err = get_nodes(&nodes, nmask, maxnode);
        if (err)
                return err;
-       return do_mbind(start, len, mode, mode_flags, &nodes, flags);
+
+       return do_mbind(start, len, lmode, mode_flags, &nodes, flags);
 }
 
 SYSCALL_DEFINE6(mbind, unsigned long, start, unsigned long, len,
@@ -1474,20 +1486,20 @@ SYSCALL_DEFINE6(mbind, unsigned long, start, unsigned long, len,
 static long kernel_set_mempolicy(int mode, const unsigned long __user *nmask,
                                 unsigned long maxnode)
 {
-       int err;
+       unsigned short mode_flags;
        nodemask_t nodes;
-       unsigned short flags;
+       int lmode = mode;
+       int err;
+
+       err = sanitize_mpol_flags(&lmode, &mode_flags);
+       if (err)
+               return err;
 
-       flags = mode & MPOL_MODE_FLAGS;
-       mode &= ~MPOL_MODE_FLAGS;
-       if ((unsigned int)mode >= MPOL_MAX)
-               return -EINVAL;
-       if ((flags & MPOL_F_STATIC_NODES) && (flags & MPOL_F_RELATIVE_NODES))
-               return -EINVAL;
        err = get_nodes(&nodes, nmask, maxnode);
        if (err)
                return err;
-       return do_set_mempolicy(mode, flags, &nodes);
+
+       return do_set_mempolicy(lmode, mode_flags, &nodes);
 }
 
 SYSCALL_DEFINE3(set_mempolicy, int, mode, const unsigned long __user *, nmask,