mirror of
https://github.com/systemd/systemd.git
synced 2025-01-25 10:04:04 +03:00
core: check size before mmap
The data type off_t can be 64 on 32 bit systems if they have large file support. Since mmap expects a size_t with 32 bits as second argument truncation could occur. At worst these huge files could lead to mmaps smaller than the previous check for small files. This in turn shouldn't have a lot of impact because mmap allocates at page size boundaries. This also made the PAGE_ALIGN call in open_mmap unneeded. In fact it was neither in sync with other mmap calls nor with its own munmap counterpart in error path. If such large files are encountered, which is very unlikely in these code paths, treat them with the same error as if they are too small.
This commit is contained in:
parent
94ce42bcb6
commit
1a823cdeb9
@ -110,6 +110,12 @@ typedef enum ReadLineFlags {
|
||||
|
||||
int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret);
|
||||
|
||||
static inline bool file_offset_beyond_memory_size(off_t x) {
|
||||
if (x < 0) /* off_t is signed, filter that out */
|
||||
return false;
|
||||
return (uint64_t) x > (uint64_t) SIZE_MAX;
|
||||
}
|
||||
|
||||
static inline int read_line(FILE *f, size_t limit, char **ret) {
|
||||
return read_line_full(f, limit, 0, ret);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "dirent-util.h"
|
||||
#include "env-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "hashmap.h"
|
||||
#include "locale-util.h"
|
||||
#include "path-util.h"
|
||||
@ -112,6 +113,9 @@ static int add_locales_from_archive(Set *locales) {
|
||||
if (st.st_size < (off_t) sizeof(struct locarhead))
|
||||
return -EBADMSG;
|
||||
|
||||
if (file_offset_beyond_memory_size(st.st_size))
|
||||
return -EFBIG;
|
||||
|
||||
p = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (p == MAP_FAILED)
|
||||
return -errno;
|
||||
|
@ -219,7 +219,7 @@ static int get_file_version(int fd, char **v) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "EFI binary is not a regular file: %m");
|
||||
|
||||
if (st.st_size < 27) {
|
||||
if (st.st_size < 27 || file_offset_beyond_memory_size(st.st_size)) {
|
||||
*v = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "hashmap.h"
|
||||
#include "hwdb-internal.h"
|
||||
#include "nulstr-util.h"
|
||||
@ -312,6 +313,9 @@ _public_ int sd_hwdb_new(sd_hwdb **ret) {
|
||||
if (hwdb->st.st_size < (off_t) offsetof(struct trie_header_f, strings_len) + 8)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EIO),
|
||||
"File %s is too short: %m", hwdb_bin_path);
|
||||
if (file_offset_beyond_memory_size(hwdb->st.st_size))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EFBIG),
|
||||
"File %s is too long: %m", hwdb_bin_path);
|
||||
|
||||
hwdb->map = mmap(0, hwdb->st.st_size, PROT_READ, MAP_SHARED, fileno(hwdb->f), 0);
|
||||
if (hwdb->map == MAP_FAILED)
|
||||
|
@ -521,10 +521,10 @@ static int open_mmap(const char *database, int *_fd, struct stat *_st, void **_p
|
||||
if (fstat(fd, &st) < 0)
|
||||
return -errno;
|
||||
|
||||
if (st.st_size < (off_t) sizeof(CatalogHeader))
|
||||
if (st.st_size < (off_t) sizeof(CatalogHeader) || file_offset_beyond_memory_size(st.st_size))
|
||||
return -EINVAL;
|
||||
|
||||
p = mmap(NULL, PAGE_ALIGN(st.st_size), PROT_READ, MAP_SHARED, fd, 0);
|
||||
p = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (p == MAP_FAILED)
|
||||
return -errno;
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "alloc-util.h"
|
||||
#include "compress.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "io-util.h"
|
||||
#include "journal-def.h"
|
||||
#include "macro.h"
|
||||
@ -807,6 +808,9 @@ int decompress_stream_lz4(int in, int out, uint64_t max_bytes) {
|
||||
if (fstat(in, &st) < 0)
|
||||
return log_debug_errno(errno, "fstat() failed: %m");
|
||||
|
||||
if (file_offset_beyond_memory_size(st.st_size))
|
||||
return -EFBIG;
|
||||
|
||||
buf = malloc(LZ4_BUFSIZE);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
Loading…
x
Reference in New Issue
Block a user