Skip to content

Commit b718d6b

Browse files
keesgregkh
authored andcommitted
pstore/ram: Correctly calculate usable PRZ bytes
[ Upstream commit 89d328f ] The actual number of bytes stored in a PRZ is smaller than the bytes requested by platform data, since there is a header on each PRZ. Additionally, if ECC is enabled, there are trailing bytes used as well. Normally this mismatch doesn't matter since PRZs are circular buffers and the leading "overflow" bytes are just thrown away. However, in the case of a compressed record, this rather badly corrupts the results. This corruption was visible with "ramoops.mem_size=204800 ramoops.ecc=1". Any stored crashes would not be uncompressable (producing a pstorefs "dmesg-*.enc.z" file), and triggering errors at boot: [ 2.790759] pstore: crypto_comp_decompress failed, ret = -22! Backporting this depends on commit 70ad35d ("pstore: Convert console write to use ->write_buf") Reported-by: Joel Fernandes <[email protected]> Fixes: b0aad7a ("pstore: Add compression support to pstore") Signed-off-by: Kees Cook <[email protected]> Reviewed-by: Joel Fernandes (Google) <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent b9c242b commit b718d6b

File tree

2 files changed

+10
-10
lines changed

2 files changed

+10
-10
lines changed

fs/pstore/ram.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -804,17 +804,14 @@ static int ramoops_probe(struct platform_device *pdev)
804804

805805
cxt->pstore.data = cxt;
806806
/*
807-
* Console can handle any buffer size, so prefer LOG_LINE_MAX. If we
808-
* have to handle dumps, we must have at least record_size buffer. And
809-
* for ftrace, bufsize is irrelevant (if bufsize is 0, buf will be
810-
* ZERO_SIZE_PTR).
807+
* Since bufsize is only used for dmesg crash dumps, it
808+
* must match the size of the dprz record (after PRZ header
809+
* and ECC bytes have been accounted for).
811810
*/
812-
if (cxt->console_size)
813-
cxt->pstore.bufsize = 1024; /* LOG_LINE_MAX */
814-
cxt->pstore.bufsize = max(cxt->record_size, cxt->pstore.bufsize);
815-
cxt->pstore.buf = kmalloc(cxt->pstore.bufsize, GFP_KERNEL);
811+
cxt->pstore.bufsize = cxt->dprzs[0]->buffer_size;
812+
cxt->pstore.buf = kzalloc(cxt->pstore.bufsize, GFP_KERNEL);
816813
if (!cxt->pstore.buf) {
817-
pr_err("cannot allocate pstore buffer\n");
814+
pr_err("cannot allocate pstore crash dump buffer\n");
818815
err = -ENOMEM;
819816
goto fail_clear;
820817
}

include/linux/pstore.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,10 @@ struct pstore_record {
9090
*
9191
* @buf_lock: spinlock to serialize access to @buf
9292
* @buf: preallocated crash dump buffer
93-
* @bufsize: size of @buf available for crash dump writes
93+
* @bufsize: size of @buf available for crash dump bytes (must match
94+
* smallest number of bytes available for writing to a
95+
* backend entry, since compressed bytes don't take kindly
96+
* to being truncated)
9497
*
9598
* @read_mutex: serializes @open, @read, @close, and @erase callbacks
9699
* @flags: bitfield of frontends the backend can accept writes for

0 commit comments

Comments
 (0)