diff options
author | SeongJae Park <sj@kernel.org> | 2025-02-05 22:15:15 -0800 |
---|---|---|
committer | Andrew Morton <akpm@linux-foundation.org> | 2025-03-16 22:06:04 -0700 |
commit | dbb0020bbc2c9f563d68564b36d6e8d32f82008b (patch) | |
tree | 1e1b4502233e8dfb7516be60bb2c53c241cd7f1b | |
parent | 4cc39f91ef6c6f876651eb231974a59ffbcb3a21 (diff) |
mm/madvise: split out madvise input validity check
Split out the madvise parameters validation logic from do_madvise(), for
easy reuse of the logic from a future change.
Link: https://lkml.kernel.org/r/20250206061517.2958-3-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Reviewed-by: Shakeel Butt <shakeel.butt@linux.dev>
Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Reviewed-by: Davidlohr Bueso <dave@stgolabs.net>
Reviewed-by: Liam R. Howlett <howlett@gmail.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-rw-r--r-- | mm/madvise.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/mm/madvise.c b/mm/madvise.c index fa5dae5a7723..ca858b8a837b 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -1618,6 +1618,27 @@ static void madvise_unlock(struct mm_struct *mm, int behavior) mmap_read_unlock(mm); } +static bool is_valid_madvise(unsigned long start, size_t len_in, int behavior) +{ + size_t len; + + if (!madvise_behavior_valid(behavior)) + return false; + + if (!PAGE_ALIGNED(start)) + return false; + len = PAGE_ALIGN(len_in); + + /* Check to see whether len was rounded up from small -ve to zero */ + if (len_in && !len) + return false; + + if (start + len < start) + return false; + + return true; +} + /* * The madvise(2) system call. * @@ -1697,20 +1718,11 @@ int do_madvise(struct mm_struct *mm, unsigned long start, size_t len_in, int beh size_t len; struct blk_plug plug; - if (!madvise_behavior_valid(behavior)) + if (!is_valid_madvise(start, len_in, behavior)) return -EINVAL; - if (!PAGE_ALIGNED(start)) - return -EINVAL; len = PAGE_ALIGN(len_in); - - /* Check to see whether len was rounded up from small -ve to zero */ - if (len_in && !len) - return -EINVAL; - end = start + len; - if (end < start) - return -EINVAL; if (end == start) return 0; |