aboutsummaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
authorJann Horn <jann@thejh.net>2016-11-10 10:46:19 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-11-18 10:48:34 +0100
commit5c54f79ad234424b453ed34e6a7920777749e456 (patch)
treebcdb4d9f02f95ae71c8cb04d8828c3ef6e528a90 /mm
parent2f7496c48a7b0df262ff7081e377b73845cd31c8 (diff)
downloadlinux-linaro-stable-5c54f79ad234424b453ed34e6a7920777749e456.tar.gz
swapfile: fix memory corruption via malformed swapfile
commit dd111be69114cc867f8e826284559bfbc1c40e37 upstream. When root activates a swap partition whose header has the wrong endianness, nr_badpages elements of badpages are swabbed before nr_badpages has been checked, leading to a buffer overrun of up to 8GB. This normally is not a security issue because it can only be exploited by root (more specifically, a process with CAP_SYS_ADMIN or the ability to modify a swap file/partition), and such a process can already e.g. modify swapped-out memory of any other userspace process on the system. Link: http://lkml.kernel.org/r/1477949533-2509-1-git-send-email-jann@thejh.net Signed-off-by: Jann Horn <jann@thejh.net> Acked-by: Kees Cook <keescook@chromium.org> Acked-by: Jerome Marchand <jmarchan@redhat.com> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: Hugh Dickins <hughd@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/swapfile.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 58877312cf6b..c1a0f3dea8b5 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -2225,6 +2225,8 @@ static unsigned long read_swap_header(struct swap_info_struct *p,
swab32s(&swap_header->info.version);
swab32s(&swap_header->info.last_page);
swab32s(&swap_header->info.nr_badpages);
+ if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES)
+ return 0;
for (i = 0; i < swap_header->info.nr_badpages; i++)
swab32s(&swap_header->info.badpages[i]);
}