]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/5.1.9/pstore-ram-run-without-kernel-crash-dump-region.patch
Linux 5.1.9
[thirdparty/kernel/stable-queue.git] / releases / 5.1.9 / pstore-ram-run-without-kernel-crash-dump-region.patch
1 From 8880fa32c557600f5f624084152668ed3c2ea51e Mon Sep 17 00:00:00 2001
2 From: Kees Cook <keescook@chromium.org>
3 Date: Thu, 30 May 2019 23:37:29 -0700
4 Subject: pstore/ram: Run without kernel crash dump region
5
6 From: Kees Cook <keescook@chromium.org>
7
8 commit 8880fa32c557600f5f624084152668ed3c2ea51e upstream.
9
10 The ram pstore backend has always had the crash dumper frontend enabled
11 unconditionally. However, it was possible to effectively disable it
12 by setting a record_size=0. All the machinery would run (storing dumps
13 to the temporary crash buffer), but 0 bytes would ultimately get stored
14 due to there being no przs allocated for dumps. Commit 89d328f637b9
15 ("pstore/ram: Correctly calculate usable PRZ bytes"), however, assumed
16 that there would always be at least one allocated dprz for calculating
17 the size of the temporary crash buffer. This was, of course, not the
18 case when record_size=0, and would lead to a NULL deref trying to find
19 the dprz buffer size:
20
21 BUG: unable to handle kernel NULL pointer dereference at (null)
22 ...
23 IP: ramoops_probe+0x285/0x37e (fs/pstore/ram.c:808)
24
25 cxt->pstore.bufsize = cxt->dprzs[0]->buffer_size;
26
27 Instead, we need to only enable the frontends based on the success of the
28 prz initialization and only take the needed actions when those zones are
29 available. (This also fixes a possible error in detecting if the ftrace
30 frontend should be enabled.)
31
32 Reported-and-tested-by: Yaro Slav <yaro330@gmail.com>
33 Fixes: 89d328f637b9 ("pstore/ram: Correctly calculate usable PRZ bytes")
34 Cc: stable@vger.kernel.org
35 Signed-off-by: Kees Cook <keescook@chromium.org>
36 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
37
38 ---
39 fs/pstore/platform.c | 3 ++-
40 fs/pstore/ram.c | 36 +++++++++++++++++++++++-------------
41 2 files changed, 25 insertions(+), 14 deletions(-)
42
43 --- a/fs/pstore/platform.c
44 +++ b/fs/pstore/platform.c
45 @@ -608,7 +608,8 @@ int pstore_register(struct pstore_info *
46 return -EINVAL;
47 }
48
49 - allocate_buf_for_compression();
50 + if (psi->flags & PSTORE_FLAGS_DMESG)
51 + allocate_buf_for_compression();
52
53 if (pstore_is_mounted())
54 pstore_get_records(0);
55 --- a/fs/pstore/ram.c
56 +++ b/fs/pstore/ram.c
57 @@ -800,26 +800,36 @@ static int ramoops_probe(struct platform
58
59 cxt->pstore.data = cxt;
60 /*
61 - * Since bufsize is only used for dmesg crash dumps, it
62 - * must match the size of the dprz record (after PRZ header
63 - * and ECC bytes have been accounted for).
64 + * Prepare frontend flags based on which areas are initialized.
65 + * For ramoops_init_przs() cases, the "max count" variable tells
66 + * if there are regions present. For ramoops_init_prz() cases,
67 + * the single region size is how to check.
68 */
69 - cxt->pstore.bufsize = cxt->dprzs[0]->buffer_size;
70 - cxt->pstore.buf = kzalloc(cxt->pstore.bufsize, GFP_KERNEL);
71 - if (!cxt->pstore.buf) {
72 - pr_err("cannot allocate pstore crash dump buffer\n");
73 - err = -ENOMEM;
74 - goto fail_clear;
75 - }
76 -
77 - cxt->pstore.flags = PSTORE_FLAGS_DMESG;
78 + cxt->pstore.flags = 0;
79 + if (cxt->max_dump_cnt)
80 + cxt->pstore.flags |= PSTORE_FLAGS_DMESG;
81 if (cxt->console_size)
82 cxt->pstore.flags |= PSTORE_FLAGS_CONSOLE;
83 - if (cxt->ftrace_size)
84 + if (cxt->max_ftrace_cnt)
85 cxt->pstore.flags |= PSTORE_FLAGS_FTRACE;
86 if (cxt->pmsg_size)
87 cxt->pstore.flags |= PSTORE_FLAGS_PMSG;
88
89 + /*
90 + * Since bufsize is only used for dmesg crash dumps, it
91 + * must match the size of the dprz record (after PRZ header
92 + * and ECC bytes have been accounted for).
93 + */
94 + if (cxt->pstore.flags & PSTORE_FLAGS_DMESG) {
95 + cxt->pstore.bufsize = cxt->dprzs[0]->buffer_size;
96 + cxt->pstore.buf = kzalloc(cxt->pstore.bufsize, GFP_KERNEL);
97 + if (!cxt->pstore.buf) {
98 + pr_err("cannot allocate pstore crash dump buffer\n");
99 + err = -ENOMEM;
100 + goto fail_clear;
101 + }
102 + }
103 +
104 err = pstore_register(&cxt->pstore);
105 if (err) {
106 pr_err("registering with pstore failed\n");