From patchwork Fri Nov 10 13:56:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kaiwan N Billimoria X-Patchwork-Id: 10053243 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 631386035D for ; Fri, 10 Nov 2017 13:56:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 570532B17C for ; Fri, 10 Nov 2017 13:56:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4B7982B18F; Fri, 10 Nov 2017 13:56:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id CFF7F2B17C for ; Fri, 10 Nov 2017 13:56:57 +0000 (UTC) Received: (qmail 28264 invoked by uid 550); 10 Nov 2017 13:56:55 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 28240 invoked from network); 10 Nov 2017 13:56:54 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:subject:from:to:cc:date:in-reply-to:references :mime-version:content-transfer-encoding; bh=o0TXcErv7D07fPEMzw+Ao3KU8w/EIo1IK49sSHZvY2A=; b=ZoWYnNQ2jJuSMQhhEVVk1l02VjwZ7VJ0TDFSGIkl1uB/ZzqTDV9+RCNUm30nWmfPLb WosKz1jl9XUCpkfwws1/MXFCcLffAOU8noURMkXsD7FHUCvNQeGpeemfvhjwLqw2bx9Q Rp/hO/rHDQ8ztyYbvHruDRzYiqsz+ZTXr2vPEJltzkEI427FysN5ZHZ9Jy3MvTkTvUmT bcQX69C6A+2KpCeSGKVC0RDRxNrBpSk2MZwGnH62i3JWbIvY52LdrsFTp+/wrMbNoZlh VL16fgjgfHm5Tg1T1Pthqw/6mIPuOyLOd5V0kJYrs6yCcESwaJQ8ijVzAXvij849Vuoz p8Hw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:subject:from:to:cc:date:in-reply-to :references:mime-version:content-transfer-encoding; bh=o0TXcErv7D07fPEMzw+Ao3KU8w/EIo1IK49sSHZvY2A=; b=g69ROMx2hjjC8hdxniws2ei4/maTmH6HtRXUEr8/EW7odeVtBPVdZ4VpErVgY7RSNe rcSY2qQvUbbjT6KfjZ9+9cWb0s8vjwECXEXaFeaFYCea/gSj+TbhJW/kCPRjDGa5SD6h R4pXJx8nKNIDllIie6X3bZwNfH1Dnw/a8PNMxO3ON4fOIfBl0XBQ2aoeTTng6UndtMn6 MOdOo21DApCtRwItNJSUX3x47Ee1DUPWPOeJdcv+hdsRHX7EgVcwxH8kCCfItQOQNoeL PMSUph/4cMI8sghNvMt7foepHtNNxmezReL0NxPKm/6wqCGkJekvs08dV/64cvd6zlGT 4N9A== X-Gm-Message-State: AJaThX6T/JUJmTkwl7zOKBUCEQ5iNJpzftEsYO6NKLYfAQk7hXRavhEC YtKhGWrS5qZcoCXJWqR6bm0= X-Google-Smtp-Source: AGs4zMZVFBNILtpCMK/hJ1pMSB2VHhxBgwaRJJ9pkY9FJF4cyP+U+53y19W0ZapSh7dK0X9zCm+b8Q== X-Received: by 10.98.144.129 with SMTP id q1mr494371pfk.38.1510322202542; Fri, 10 Nov 2017 05:56:42 -0800 (PST) Message-ID: <1510322194.19812.3.camel@gmail.com> From: kaiwan.billimoria@gmail.com To: "Tobin C. Harding" , kernel-hardening@lists.openwall.com Cc: "Jason A. Donenfeld" , Theodore Ts'o , Linus Torvalds , Kees Cook , Paolo Bonzini , Tycho Andersen , "Roberts, William C" , Tejun Heo , Jordan Glover , Greg KH , Petr Mladek , Joe Perches , Ian Campbell , Sergey Senozhatsky , Catalin Marinas , Will Deacon , Steven Rostedt , Chris Fries , Dave Weinstein , Daniel Micay , Djalal Harouni , linux-kernel@vger.kernel.org, Network Development , David Miller Date: Fri, 10 Nov 2017 19:26:34 +0530 In-Reply-To: <1510050731-32446-1-git-send-email-me@tobin.cc> References: <1510050731-32446-1-git-send-email-me@tobin.cc> X-Mailer: Evolution 3.24.6 (3.24.6-1.fc26) Mime-Version: 1.0 Subject: Re: [kernel-hardening] [PATCH v4] scripts: add leaking_addresses.pl X-Virus-Scanned: ClamAV using ClamSMTP On Tue, 2017-11-07 at 21:32 +1100, Tobin C. Harding wrote: > Currently we are leaking addresses from the kernel to user space. > This > script is an attempt to find some of those leakages. Script parses > `dmesg` output and /proc and /sys files for hex strings that look > like > kernel addresses. > > Only works for 64 bit kernels, the reason being that kernel addresses > on 64 bit kernels have 'ffff' as the leading bit pattern making > greping > possible. On 32 kernels we don't have this luxury. Tobin C. Harding wrote: >Only works for 64 bit kernels, the reason being that kernel addresses >on 64 bit kernels have 'ffff' as the leading bit pattern making greping >possible. On 32 kernels we don't have this luxury. [RFC] leaking_addresses.pl - enhance it to work for 32-bit kernels as well (Firstly, apologies if I've got the protocol horribly wrong- should this be a new thread altogether?) Ok so, I was interested in figuring - why not have this useful script work for 32-bit kernel virtual addresses as well (and those systems by extension). The approach am considering, pl correct me if I'm way off: on 32-bit, the kernel macro PAGE_OFFSET will give us the user-kernel split; (alternatively, could also script up CONFIG_VMSPLIT_[n]G and figure the split from there.) For the time being, lets say we go with the "use PAGE_OFFSET" approach and PAGE_OFFSET = 0xc0000000 , whch implies we have a 3:1 GB user:kernel split. So any virtual addresses >= PAGE_OFFSET are kernel virtual addresses (i know, untrue on some ARM-32 systems!). As a very early and *far-from-perfect* start, I've enhanced Tobin's Perl script to take into account 32-bit address space by passing the parameter '--bit-size='. The patch below does Not take into account (yet) stuff like: - exactly which files & dirs should be skipped on 32-bit (will it be identical to 64-bit?; unsure..) - it currently hard-codes a global 'PAGE_OFFSET_32BIT=0xc0000000' , just so I can test quickly; must figure whether to query it or pass it; Suggestions? - the 'false positives'; again, what differs for 32-bit? (BTW, shouldn't the dmesg 'root=UUID=<...>' line be a false positive & skipped?). Also, I must point out that I'm a complete newbie to Perl :-) so, pl excuse my highly inadequate perl-foo; I rely on you perl gurus out there to fix and optimize :) Yes, I've **Very Minimally** tested the patch in it's current form on: a) a regular (Fedora 26) x86_64 desktop, b) a (Debian 7) 32-bit kernel (VM) with PAGE_OFFSET=3 Gb and it seems all right, considering... Some sample output from test (b), if interested: scripts/leaking_addresses.pl | 40 +++++++++++++++++++++++++++++++++------- ===== dmesg: [ 0.000000] found SMP MP-table at [c00f1280] f1280 dmesg: [ 0.000000] Base memory trampoline at [c009b000] 9b000 size 16384 dmesg: [ 0.000000] ACPI: Local APIC address 0xfee00000 dmesg: [ 0.000000] free_area_init_node: node 0, pgdat c1418bc0, node_mem_map dfbfa200 dmesg: [ 0.000000] ACPI: Local APIC address 0xfee00000 dmesg: [ 0.000000] ACPI: IOAPIC (id[0x00] address[0xfec00000] gsi_base[0]) dmesg: [ 0.000000] IOAPIC[0]: apic_id 0, version 17, address 0xfec00000, GSI 0-23 dmesg: [ 0.000000] PERCPU: Embedded 14 pages/cpu @dfbe8000 s33344 r0 d24000 u57344 dmesg: [ 0.000000] fixmap : 0xffd36000 - 0xfffff000 (2852 kB) dmesg: [ 0.000000] pkmap : 0xffa00000 - 0xffc00000 (2048 kB) dmesg: [ 0.000000] vmalloc : 0xe07fb000 - 0xff9fe000 ( 498 MB) dmesg: [ 0.000000] lowmem : 0xc0000000 - 0xdfffb000 ( 511 MB) dmesg: [ 0.000000] .init : 0xc1421000 - 0xc148c000 ( 428 kB) [...] /proc/kallsyms: c10010e8 T _stext /proc/kallsyms: c1002000 T hypercall_page /proc/kallsyms: c1003000 t arch_local_save_flags /proc/kallsyms: c1003007 t arch_local_irq_enable /proc/kallsyms: c100300e T do_one_initcall << ... plenty more kallsyms of course (92.5% of the output to be precise!) ... >> /proc/modules: loop 17803 0 - Live 0xe097c000 /proc/modules: crc32c_intel 12659 0 - Live 0xe096e000 /proc/modules: snd_pcm 53461 0 - Live 0xe09f5000 /proc/modules: snd_page_alloc 12867 1 snd_pcm, Live 0xe0957000 /proc/modules: snd_timer 22401 1 snd_pcm, Live 0xe093c000 [...] /proc/modules: usb_common 12338 1 usbcore, Live 0xe0860000 /proc/timer_list: .base: dfbeb8b0 /proc/timer_list: #0: , tick_sched_timer, S:01, hrtimer_start_range_ns, swapper/0/0 [...] /proc/iomem: f8000000-fbffffff : 0000:00:02.0 /proc/iomem: fc000000-fcffffff : 0000:00:02.0 /proc/iomem: fd000000-fd03ffff : 0000:00:03.0 [...] /proc/11422/syscall: 7 0xffffffff 0xbf814618 0xa 0xa 0x0 0x1 0xbf8145b8 0xb7780428 /proc/11422/stack: [] kmap_atomic_prot+0x2f/0xe0 /proc/11422/stack: [] security_task_wait+0xc/0xd [...] /proc/bus/input/devices: B: KEY=4 2000000 3803078 f800d001 feffffdf ffefffff ffffffff fffffffe /proc/1/net/ipv6_route: 00000000000000000000000000000000 00 00000000000000000000000000000000 00 00000000000000000000000000000000 ffffffff 00000001 0000000f 00200200 lo [...] /proc/2/net/unix: dce872c0: 00000005 00000000 00000000 0002 01 4978 /dev/log /proc/2/net/unix: dce87a40: 00000002 00000000 00010000 0001 01 5006 /var/run/acpid.socket /proc/2/net/unix: dce87540: 00000002 00000000 00010000 0005 01 3246 /run/udev/control [...] ===== etc etc. Finally, unsure if am working against the latest ver of your script Tobin, apologies if not. Signed-off-by: Kaiwan N Billimoria --- diff --git a/scripts/leaking_addresses.pl b/scripts/leaking_addresses.pl index 2977371b2956..b6280dca8c46 100755 --- a/scripts/leaking_addresses.pl +++ b/scripts/leaking_addresses.pl @@ -45,6 +45,7 @@ my $P = $0; my $V = '0.01'; # Directories to scan. +#my @DIRS = ('/home/kai/0tmp/addr32_pl'); my @DIRS = ('/proc', '/sys'); # Command line options. @@ -52,6 +53,7 @@ my $help = 0; my $debug = 0; my @dont_walk = (); my @dont_parse = (); +my $bit_size = 64; # Do not parse these files (absolute path). my @skip_parse_files_abs = ('/proc/kmsg', @@ -86,6 +88,8 @@ my @skip_walk_dirs_any = ('self', 'stdin', 'stdout'); +my $PAGE_OFFSET_32BIT = 0xc0000000; + sub help { my ($exitcode) = @_; @@ -96,10 +100,12 @@ Version: $V Options: + --bit-size= 32|[64] Checks for 64-bit kernel addresses by default; + change to check for 32-bit kernel addresses by passing 32 here --dont-walk= Don't walk tree starting at . --dont-parse= Don't parse . - -d, --debug Display debugging output. - -h, --help, --version Display this help and exit. + -d, --debug Display debugging output. + -h, --help, --version Display this help and exit. If an absolute path is passed to --dont_XXX then this path is skipped. If a single filename is passed then this file/directory will be skipped when @@ -117,8 +123,9 @@ EOM } GetOptions( - 'dont-walk=s' => \@dont_walk, - 'dont-parse=s' => \@dont_parse, + 'dont-walk=s' => \@dont_walk, + 'dont-parse=s' => \@dont_parse, + 'bit-size=i' => \$bit_size, 'd|debug' => \$debug, 'h|help' => \$help, 'version' => \$help @@ -126,6 +133,10 @@ GetOptions( help(0) if ($help); +if ($bit_size != 64 && $bit_size != 32) { + help(1); +} + push_to_global(); parse_dmesg(); @@ -168,6 +179,7 @@ sub push_to_global push_in_abs_any(\@dont_parse, \@skip_parse_files_abs, \@skip_parse_files_any); } +# NOT updated for 32-bit kernel addresses yet sub is_false_positive { my ($match) = @_; @@ -183,6 +195,7 @@ sub is_false_positive return 1; } +# TODO - skip the 'root=UUID=<...>' line as well return 0; } @@ -190,7 +203,8 @@ sub is_false_positive sub may_leak_address { my ($line) = @_; - my $address = '\b(0x)?ffff[[:xdigit:]]{12}\b'; + my $address64 = '\b(0x)?ffff[[:xdigit:]]{12}\b'; + my $address32 = '\b(0x)?[[:xdigit:]]{8}\b'; # Signal masks. if ($line =~ '^SigBlk:' or @@ -202,11 +216,23 @@ sub may_leak_address $line =~ '\b[[:xdigit:]]{14} [[:xdigit:]]{16} [[:xdigit:]]{16}\b') { return 0; } - - while (/($address)/g) { + + if ($bit_size == 64) { + while (/($address64)/g) { if (!is_false_positive($1)) { return 1; } + } + } elsif ($bit_size == 32) { + while (/($address32)/g) { + my $addr32 = eval hex($1); + if ($addr32 < $PAGE_OFFSET_32BIT) { + return 0; + } + if (!is_false_positive($addr32)) { + return 1; + } + } } return 0;