pstore/ram: Correctly calculate usable PRZ bytes
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 commit70ad35db33
("pstore: Convert console write to use ->write_buf") Reported-by: Joel Fernandes <joel@joelfernandes.org> Fixes:b0aad7a99c
("pstore: Add compression support to pstore") Signed-off-by: Kees Cook <keescook@chromium.org> Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
This commit is contained in:
parent
1227daa43b
commit
89d328f637
@ -816,17 +816,14 @@ static int ramoops_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
cxt->pstore.data = cxt;
|
cxt->pstore.data = cxt;
|
||||||
/*
|
/*
|
||||||
* Console can handle any buffer size, so prefer LOG_LINE_MAX. If we
|
* Since bufsize is only used for dmesg crash dumps, it
|
||||||
* have to handle dumps, we must have at least record_size buffer. And
|
* must match the size of the dprz record (after PRZ header
|
||||||
* for ftrace, bufsize is irrelevant (if bufsize is 0, buf will be
|
* and ECC bytes have been accounted for).
|
||||||
* ZERO_SIZE_PTR).
|
|
||||||
*/
|
*/
|
||||||
if (cxt->console_size)
|
cxt->pstore.bufsize = cxt->dprzs[0]->buffer_size;
|
||||||
cxt->pstore.bufsize = 1024; /* LOG_LINE_MAX */
|
cxt->pstore.buf = kzalloc(cxt->pstore.bufsize, GFP_KERNEL);
|
||||||
cxt->pstore.bufsize = max(cxt->record_size, cxt->pstore.bufsize);
|
|
||||||
cxt->pstore.buf = kmalloc(cxt->pstore.bufsize, GFP_KERNEL);
|
|
||||||
if (!cxt->pstore.buf) {
|
if (!cxt->pstore.buf) {
|
||||||
pr_err("cannot allocate pstore buffer\n");
|
pr_err("cannot allocate pstore crash dump buffer\n");
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto fail_clear;
|
goto fail_clear;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,10 @@ struct pstore_record {
|
|||||||
*
|
*
|
||||||
* @buf_lock: spinlock to serialize access to @buf
|
* @buf_lock: spinlock to serialize access to @buf
|
||||||
* @buf: preallocated crash dump buffer
|
* @buf: preallocated crash dump buffer
|
||||||
* @bufsize: size of @buf available for crash dump writes
|
* @bufsize: size of @buf available for crash dump bytes (must match
|
||||||
|
* smallest number of bytes available for writing to a
|
||||||
|
* backend entry, since compressed bytes don't take kindly
|
||||||
|
* to being truncated)
|
||||||
*
|
*
|
||||||
* @read_mutex: serializes @open, @read, @close, and @erase callbacks
|
* @read_mutex: serializes @open, @read, @close, and @erase callbacks
|
||||||
* @flags: bitfield of frontends the backend can accept writes for
|
* @flags: bitfield of frontends the backend can accept writes for
|
||||||
|
Loading…
Reference in New Issue
Block a user