#include "hivex.h"
#include "byte_conversions.h"
+/* These limits are in place to stop really stupid stuff and/or exploits. */
+#define HIVEX_MAX_SUBKEYS 10000
+#define HIVEX_MAX_VALUES 1000
+#define HIVEX_MAX_VALUE_LEN 1000000
+#define HIVEX_MAX_ALLOCATION 1000000
+
static char *windows_utf16_to_utf8 (/* const */ char *input, size_t len);
struct hive_h {
goto ok;
/* Arbitrarily limit the number of subkeys we will ever deal with. */
- if (nr_subkeys_in_nk > 1000000) {
+ if (nr_subkeys_in_nk > HIVEX_MAX_SUBKEYS) {
errno = ERANGE;
goto error;
}
goto ok;
/* Arbitrarily limit the number of values we will ever deal with. */
- if (nr_values > 100000) {
+ if (nr_values > HIVEX_MAX_VALUES) {
errno = ERANGE;
goto error;
}
*len_rtn = len;
/* Arbitrarily limit the length that we will read. */
- if (len > 1000000) {
+ if (len > HIVEX_MAX_VALUE_LEN) {
errno = ERANGE;
return NULL;
}
}
/* Refuse really large allocations. */
- if (seg_len > 1000000) {
+ if (seg_len > HIVEX_MAX_ALLOCATION) {
if (h->msglvl >= 2)
fprintf (stderr, "allocate_block: refusing large allocation (%zu), returning ERANGE\n",
seg_len);
(struct ntreg_hbin_block *) (h->addr + offset);
blockhdr->seg_len = htole32 (- (int32_t) seg_len);
- if (id[0] && id[1] && seg_len >= 6) {
+ if (id[0] && id[1] && seg_len >= sizeof (struct ntreg_hbin_block)) {
blockhdr->id[0] = id[0];
blockhdr->id[1] = id[1];
}
}
if (name_len * 2 > le32toh (nk->max_vk_name_len))
+ /* * 2 for UTF16-LE "reencoding" */
nk->max_vk_name_len = htole32 (name_len * 2);
if (values[i].len > le32toh (nk->max_vk_data_len))
nk->max_vk_data_len = htole32 (values[i].len);