Test for uname26 exploit CVE-2012-0957
PATCH 3/4 Test for uname26 exploit CVE-2012-0957
Attempt to exploit the uname kernel memory leak which occurred when the UNAME26 personality was set.
Signed-off-by Richard Palethorpe <[email protected]>
--- testcases/cve/cve-2012-0957.c | 90 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 testcases/cve/cve-2012-0957.c
testcases/cve/cve-2012-0957.c new file +90 -0
@@ -0,0 +1,90 @@ +/* +* Copyright (c) 2017 Richard Palethorpe <[email protected]> +* Copyright (c) 2012, Kees Cook <[email protected]> +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +/* +* Check that memory after the string terminator in all the utsname fields has +* been zeroed. cve-2012-0957 leaked kernel memory through the release field +* when the UNAME26 personality was set. +* +* Thanks to Kees Cook for the original proof of concept: +* http://www.securityfocus.com/bid/55855/info +*/ + +#include <string.h> +#include <sys/utsname.h> +#include <sys/personality.h> +#include "tst_test.h" + +#define UNAME26 0x0020000 + +static int check_field (char *bytes,size_t length,char *field) +{ +size_t i =strlen (bytes) +1 ; + +for (; i < length; i++) { +if (bytes[i]) { +tst_res (TFAIL ,"Bytes leaked in %s!" , field); +return 1 ; + } + } +return 0 ; +} + + +static void try_leak_bytes (void ) +{ +struct utsname buf; + +if (uname (&buf)) +tst_brk (TBROK |TERRNO ,"Call to uname failed" ); + +#define CHECK_FIELD (field_name) \ + (check_field(buf.field_name, ARRAY_SIZE(buf.field_name), #field_name)) + +if (!(CHECK_FIELD (release) | +CHECK_FIELD (sysname) | +CHECK_FIELD (nodename) | +CHECK_FIELD (version) | +CHECK_FIELD (machine) | +#ifdef _GNU_SOURCE +CHECK_FIELD (domainname) | +#endif +0 )) { +tst_res (TPASS ,"All fields zeroed after string terminator" ); + } +#undef CHECK_FIELD +} + +static void run (unsigned int test_nr) +{ +if (!test_nr) { +tst_res (TINFO ,"Calling uname with default personality" ); +try_leak_bytes (); + }else { +if (personality (PER_LINUX |UNAME26 ) <0 ) +tst_brk (TCONF |TERRNO , +"Could not change personality to UNAME26" ); +tst_res (TINFO ,"Calling uname with UNAME26 personality" ); +try_leak_bytes (); + } +} + +static struct tst_test test = { + .tid ="cve-2012-0957" , + .test = run, + .tcnt =2 , +};
Signature · 1 line
2.12.0
PATCH 3/4 Test for uname26 exploit CVE-2012-0957
Hi!
testcases/cve/cve-2012-0957.c line 45
Quoted 12 lines
testcases/cve/cve-2012-0957.c new file +12
-0+static int check_field (char *bytes,size_t length,char *field) +{ +size_t i =strlen (bytes) +1 ; + +for (; i < length; i++) { +if (bytes[i]) { +tst_res (TFAIL ,"Bytes leaked in %s!" , field); +return 1 ; + } + } +return 0 ; +}
I guess that this could be void, since we don't use the return value, but that is very minor...
Signature · 2 lines
Cyril Hrubis [email protected]