diff options
author | Jann Horn <jann@thejh.net> | 2016-11-10 10:46:19 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-04-18 07:55:47 +0200 |
commit | 26d45300bcecaba2d912df0662906dd96e085f2a (patch) | |
tree | bce909d66fb9bfa258ce9436e12ef40adf795b04 /mm | |
parent | 63f4bbed1b277aacf267404f812173734511a63b (diff) | |
download | linux-stable-26d45300bcecaba2d912df0662906dd96e085f2a.tar.gz linux-stable-26d45300bcecaba2d912df0662906dd96e085f2a.tar.bz2 linux-stable-26d45300bcecaba2d912df0662906dd96e085f2a.zip |
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.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c index 8798b2e0ac59..14ae9e3ec728 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -2184,6 +2184,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]); } |