Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751442AbdCQR1e (ORCPT ); Fri, 17 Mar 2017 13:27:34 -0400 Received: from out02.mta.xmission.com ([166.70.13.232]:36613 "EHLO out02.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751100AbdCQR1V (ORCPT ); Fri, 17 Mar 2017 13:27:21 -0400 From: ebiederm@xmission.com (Eric W. Biederman) To: Xunlei Pang Cc: linux-kernel@vger.kernel.org, kexec@lists.infradead.org, akpm@linux-foundation.org, Dave Young , Baoquan He References: <1489722318-13695-1-git-send-email-xlpang@redhat.com> Date: Fri, 17 Mar 2017 12:22:22 -0500 In-Reply-To: <1489722318-13695-1-git-send-email-xlpang@redhat.com> (Xunlei Pang's message of "Fri, 17 Mar 2017 11:45:18 +0800") Message-ID: <874lyrhl81.fsf@xmission.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-XM-SPF: eid=1covep-0003Pq-9d;;;mid=<874lyrhl81.fsf@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=67.3.234.240;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX19/4eJLN1oTWk4DD8uHULbnG7DuoGslGho= X-SA-Exim-Connect-IP: 67.3.234.240 X-SA-Exim-Mail-From: ebiederm@xmission.com X-Spam-Report: * -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP * 0.7 XMSubLong Long Subject * 0.0 TVD_RCVD_IP Message was received from an IP address * 0.0 T_TM2_M_HEADER_IN_MSG BODY: No description available. * 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% * [score: 0.5000] * -0.0 DCC_CHECK_NEGATIVE Not listed in DCC * [sa06 1397; Body=1 Fuz1=1 Fuz2=1] * 1.0 XM_Sft_Co_L33T No description available. X-Spam-DCC: XMission; sa06 1397; Body=1 Fuz1=1 Fuz2=1 X-Spam-Combo: *;Xunlei Pang X-Spam-Relay-Country: X-Spam-Timing: total 336 ms - load_scoreonly_sql: 0.04 (0.0%), signal_user_changed: 2.8 (0.8%), b_tie_ro: 1.95 (0.6%), parse: 1.07 (0.3%), extract_message_metadata: 5 (1.6%), get_uri_detail_list: 3.4 (1.0%), tests_pri_-1000: 3.4 (1.0%), tests_pri_-950: 1.14 (0.3%), tests_pri_-900: 0.94 (0.3%), tests_pri_-400: 27 (7.9%), check_bayes: 26 (7.6%), b_tokenize: 9 (2.7%), b_tok_get_all: 9 (2.6%), b_comp_prob: 2.6 (0.8%), b_tok_touch_all: 3.6 (1.1%), b_finish: 0.64 (0.2%), tests_pri_0: 281 (83.5%), check_dkim_signature: 0.76 (0.2%), check_dkim_adsp: 3.4 (1.0%), tests_pri_500: 4.6 (1.4%), rewrite_mail: 0.00 (0.0%) Subject: Re: [PATCH v2] kexec: Introduce vmcoreinfo signature verification X-Spam-Flag: No X-SA-Exim-Version: 4.2.1 (built Thu, 05 May 2016 13:38:54 -0600) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4690 Lines: 148 Xunlei Pang writes: > Currently vmcoreinfo data is updated at boot time subsys_initcall(), > it has the risk of being modified by some wrong code during system > is running. > > As a result, vmcore dumped may contain the wrong vmcoreinfo. Later on, > when using "crash" or "makedumpfile"(etc) utility to parse this vmcore, > we probably will get "Segmentation fault" or other unexpected/confusing > errors. If this is a real concern and the previous discussion sounds like it is part of what we need to do is move the variable vmcoreinfo_note out of the kernel's .bss section. And modify the code to regenerate and keep this information in something like the control page. Definitely something like this needs a page all to itself, and ideally far away from any other kernel data structures. I clearly was not watching closely the data someone decided to keep this silly thing in the kernel's .bss section. > As vmcoreinfo is the most fundamental information for vmcore, we better > double check its correctness. Here we generate a signature(using crc32) > after it is saved, then verify it in crash_save_vmcoreinfo() to see if > the signature was broken, if so we have to re-save the vmcoreinfo data > to get the correct vmcoreinfo for kdump as possible as we can. Sigh. We already have a sha256 that is supposed to cover this sort of thing. The bug rather is that apparently it isn't covering this data. That sounds like what we should be fixing. Please let's not invent new mechanisms we have to maintain. Let's reorganize this so this static data is protected like all other static data in the kexec-on-panic path. We have good mechanims and good strategies for avoiding and detecting corruption we just need to use them. Eric > Signed-off-by: Xunlei Pang > --- > v1->v2: > - Keep crash_save_vmcoreinfo_init() because "makedumpfile --mem-usage" > uses the information. > - Add crc32 verification for vmcoreinfo, re-save when failure. > > arch/Kconfig | 1 + > kernel/kexec_core.c | 43 +++++++++++++++++++++++++++++++++++-------- > 2 files changed, 36 insertions(+), 8 deletions(-) > > diff --git a/arch/Kconfig b/arch/Kconfig > index c4d6833..66eb296 100644 > --- a/arch/Kconfig > +++ b/arch/Kconfig > @@ -4,6 +4,7 @@ > > config KEXEC_CORE > bool > + select CRC32 > > config HAVE_IMA_KEXEC > bool > diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c > index bfe62d5..012acbe 100644 > --- a/kernel/kexec_core.c > +++ b/kernel/kexec_core.c > @@ -38,6 +38,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -53,9 +54,10 @@ > > /* vmcoreinfo stuff */ > static unsigned char vmcoreinfo_data[VMCOREINFO_BYTES]; > -u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4]; > +static u32 vmcoreinfo_sig; > size_t vmcoreinfo_size; > size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data); > +u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4]; > > /* Flag to indicate we are going to kexec a new kernel */ > bool kexec_in_progress = false; > @@ -1367,12 +1369,6 @@ static void update_vmcoreinfo_note(void) > final_note(buf); > } > > -void crash_save_vmcoreinfo(void) > -{ > - vmcoreinfo_append_str("CRASHTIME=%ld\n", get_seconds()); > - update_vmcoreinfo_note(); > -} > - > void vmcoreinfo_append_str(const char *fmt, ...) > { > va_list args; > @@ -1402,7 +1398,7 @@ phys_addr_t __weak paddr_vmcoreinfo_note(void) > return __pa_symbol((unsigned long)(char *)&vmcoreinfo_note); > } > > -static int __init crash_save_vmcoreinfo_init(void) > +static void do_crash_save_vmcoreinfo_init(void) > { > VMCOREINFO_OSRELEASE(init_uts_ns.name.release); > VMCOREINFO_PAGESIZE(PAGE_SIZE); > @@ -1474,6 +1470,37 @@ static int __init crash_save_vmcoreinfo_init(void) > #endif > > arch_crash_save_vmcoreinfo(); > +} > + > +static u32 crash_calc_vmcoreinfo_sig(void) > +{ > + return crc32(~0, vmcoreinfo_data, vmcoreinfo_size); > +} > + > +static bool crash_verify_vmcoreinfo(void) > +{ > + if (crash_calc_vmcoreinfo_sig() == vmcoreinfo_sig) > + return true; > + > + return false; > +} > + > +void crash_save_vmcoreinfo(void) > +{ > + /* Re-save if verification fails */ > + if (!crash_verify_vmcoreinfo()) { > + vmcoreinfo_size = 0; > + do_crash_save_vmcoreinfo_init(); > + } > + > + vmcoreinfo_append_str("CRASHTIME=%ld\n", get_seconds()); > + update_vmcoreinfo_note(); > +} > + > +static int __init crash_save_vmcoreinfo_init(void) > +{ > + do_crash_save_vmcoreinfo_init(); > + vmcoreinfo_sig = crash_calc_vmcoreinfo_sig(); > update_vmcoreinfo_note(); > > return 0;