diff options
author | Yuxiao Zhang <yuxiaozhang@google.com> | 2023-06-27 13:25:41 -0700 |
---|---|---|
committer | Kees Cook <keescook@chromium.org> | 2023-08-17 15:18:24 -0700 |
commit | 104fd0b5e948157f8e8ac88a20b46ba8641d4e95 (patch) | |
tree | dd88e938e7515d17ef837a470b750599818143b8 /fs/pstore/ram_core.c | |
parent | fe8c3623ab06603eb760444a032d426542212021 (diff) | |
download | lwn-104fd0b5e948157f8e8ac88a20b46ba8641d4e95.tar.gz lwn-104fd0b5e948157f8e8ac88a20b46ba8641d4e95.zip |
pstore: Support record sizes larger than kmalloc() limit
Currently pstore record buffers are allocated using kmalloc() which has
a maximum size based on page size. If a large "pmsg-size" module
parameter is specified, pmsg will fail to copy the contents since
memdup_user() is limited to kmalloc() allocation sizes.
Since we don't need physically contiguous memory for any of the pstore
record buffers, use kvzalloc() to avoid such limitations in the core of
pstore and in the ram backend, and explicitly read from userspace using
vmemdup_user(). This also means that any other backends that want to
(or do already) support larger record sizes will Just Work now.
Signed-off-by: Yuxiao Zhang <yuxiaozhang@google.com>
Link: https://lore.kernel.org/r/20230627202540.881909-2-yuxiaozhang@google.com
Co-developed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
Diffstat (limited to 'fs/pstore/ram_core.c')
-rw-r--r-- | fs/pstore/ram_core.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index eb6df190d752..0eb780b90281 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -17,6 +17,7 @@ #include <linux/slab.h> #include <linux/uaccess.h> #include <linux/vmalloc.h> +#include <linux/mm.h> #include <asm/page.h> #include "ram_internal.h" @@ -301,7 +302,7 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!prz->old_log) { persistent_ram_ecc_old(prz); - prz->old_log = kmalloc(size, GFP_KERNEL); + prz->old_log = kvzalloc(size, GFP_KERNEL); } if (!prz->old_log) { pr_err("failed to allocate buffer\n"); @@ -385,7 +386,7 @@ void *persistent_ram_old(struct persistent_ram_zone *prz) void persistent_ram_free_old(struct persistent_ram_zone *prz) { - kfree(prz->old_log); + kvfree(prz->old_log); prz->old_log = NULL; prz->old_log_size = 0; } |