/* +0xd0 (208) */
} _packed_attribute;
-#define MAX_IMAGES (((INT_MAX < INT32_MAX) ? INT_MAX : INT32_MAX) - 1)
+/*
+ * Arbitrarily limit the maximum number of images to 65535, to prevent huge
+ * memory allocations when processing fuzzed files. This can be increased if
+ * ever needed (up to INT_MAX - 1).
+ */
+#define MAX_IMAGES 65535
/* In-memory representation of a WIM header. See `struct wim_header_disk' for
* field descriptions. */
* Otherwise, this field is invalid (!filedes_valid(&out_fd)). */
struct filedes out_fd;
+ /* The size of the backing file, or 0 if unknown */
+ u64 file_size;
+
/*
* This is the cached decompressor for this WIM file, or NULL if no
* decompressor is cached yet. Normally, all the compressed data in a
*/
/*
- * Copyright (C) 2012, 2013, 2015 Eric Biggers
+ * Copyright 2012-2023 Eric Biggers
*
* This file is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
get_wim_reshdr(&disk_hdr.boot_metadata_reshdr, &hdr->boot_metadata_reshdr);
hdr->boot_idx = le32_to_cpu(disk_hdr.boot_idx);
get_wim_reshdr(&disk_hdr.integrity_table_reshdr, &hdr->integrity_table_reshdr);
+
+ /*
+ * Prevent huge memory allocations when processing fuzzed files. The
+ * blob table, XML data, and integrity table are all uncompressed, so
+ * they should never be larger than the WIM file itself.
+ */
+ if (wim->file_size > 0 &&
+ (hdr->blob_table_reshdr.uncompressed_size > wim->file_size ||
+ hdr->xml_data_reshdr.uncompressed_size > wim->file_size ||
+ hdr->integrity_table_reshdr.uncompressed_size > wim->file_size))
+ return WIMLIB_ERR_INVALID_HEADER;
+
return 0;
read_error:
*/
/*
- * Copyright (C) 2012, 2013 Eric Biggers
+ * Copyright 2012-2023 Eric Biggers
*
* This file is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
metadata_blob = imd->metadata_blob;
+ /*
+ * Prevent huge memory allocations when processing fuzzed files. The
+ * case of metadata resources is tough, since a metadata resource can
+ * legitimately decompress to many times the size of the WIM file
+ * itself, e.g. in the case of an image containing many empty files with
+ * similar long filenames. Arbitrarily choose 512x as a generous limit.
+ */
+ if (metadata_blob->blob_location == BLOB_IN_WIM &&
+ metadata_blob->rdesc->wim->file_size > 0 &&
+ metadata_blob->size / 512 > metadata_blob->rdesc->wim->file_size)
+ return WIMLIB_ERR_INVALID_METADATA_RESOURCE;
+
/* Read the metadata resource into memory. (It may be compressed.) */
ret = read_blob_into_alloc_buf(metadata_blob, &buf);
if (ret)
*/
/*
- * Copyright (C) 2012-2016 Eric Biggers
+ * Copyright 2012-2023 Eric Biggers
*
* This file is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
+#include <sys/stat.h>
#include <unistd.h>
#include "wimlib.h"
filedes_init(&wim->in_fd, *(const int*)wim_filename_or_fd);
wim->in_fd.is_pipe = 1;
} else {
+ struct stat stbuf;
+
wimfile = wim_filename_or_fd;
ret = open_wim_file(wimfile, &wim->in_fd);
if (ret)
return ret;
+ /* The file size is needed for enforcing some limits later. */
+ if (fstat(wim->in_fd.fd, &stbuf) == 0)
+ wim->file_size = stbuf.st_size;
+
/* The absolute path to the WIM is requested so that
* wimlib_overwrite() still works even if the process changes
* its working directory. This actually happens if a WIM is