From: Tobias Stoeckmann Date: Tue, 3 Sep 2024 18:28:26 +0000 (+0200) Subject: libkmod: Improve st_size checks on 32 bit systems X-Git-Tag: v34~328 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=97260d9495c3045dfdd4a2e5da64914d2fac1798;p=thirdparty%2Fkmod.git libkmod: Improve st_size checks on 32 bit systems Since off_t can (and most likely will) be 64 bit on 32 bit systems, check its actual value before casting it to 32 bit size_t. Signed-off-by: Tobias Stoeckmann Reviewed-by: Emil Velikov Link: https://github.com/kmod-project/kmod/pull/96 Signed-off-by: Lucas De Marchi --- diff --git a/libkmod/libkmod-builtin.c b/libkmod/libkmod-builtin.c index 88b0deb9..5ae8ef5f 100644 --- a/libkmod/libkmod-builtin.c +++ b/libkmod/libkmod-builtin.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -69,6 +70,11 @@ static struct kmod_builtin_iter *kmod_builtin_iter_new(struct kmod_ctx *ctx) goto fail; } + if (sb.st_size > INTPTR_MAX) { + sv_errno = ENOMEM; + goto fail; + } + iter = malloc(sizeof(*iter)); if (!iter) { sv_errno = ENOMEM; diff --git a/libkmod/libkmod-file.c b/libkmod/libkmod-file.c index f1779346..f15998d5 100644 --- a/libkmod/libkmod-file.c +++ b/libkmod/libkmod-file.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -31,6 +32,9 @@ static int load_reg(struct kmod_file *file) return -errno; file->size = st.st_size; + if ((uintmax_t)file->size > SIZE_MAX) + return -ENOMEM; + file->memory = mmap(NULL, file->size, PROT_READ, MAP_PRIVATE, file->fd, 0); if (file->memory == MAP_FAILED) { diff --git a/libkmod/libkmod-index.c b/libkmod/libkmod-index.c index 469910e0..36b84a83 100644 --- a/libkmod/libkmod-index.c +++ b/libkmod/libkmod-index.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -778,15 +779,20 @@ int index_mm_open(const struct kmod_ctx *ctx, const char *filename, goto fail_open; } - if (fstat(fd, &st) < 0 || (size_t) st.st_size < sizeof(hdr)) { + if (fstat(fd, &st) < 0 || st.st_size < (off_t) sizeof(hdr)) { err = -EINVAL; goto fail_nommap; } + if ((uintmax_t)st.st_size > SIZE_MAX) { + err = -ENOMEM; + goto fail_nommap; + } + idx->mm = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (idx->mm == MAP_FAILED) { - ERR(ctx, "mmap(NULL, %"PRIu64", PROT_READ, %d, MAP_PRIVATE, 0): %m\n", - st.st_size, fd); + ERR(ctx, "mmap(NULL, %"PRIu64", PROT_READ, MAP_PRIVATE, %d, 0): %m\n", + (uint64_t) st.st_size, fd); err = -errno; goto fail_nommap; }