diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2018-05-24 13:47:50 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2018-05-24 13:47:50 +0200 |
commit | b001c227fdf02e3ed1e87161cbc1dec4a1184203 (patch) | |
tree | cf2135c91a76a9642d497b77e41857add4d6a496 /src/gdbmopen.c | |
parent | e01d90f2cdebaa2a3543aa651b92e9d397a3bf77 (diff) | |
download | gdbm-b001c227fdf02e3ed1e87161cbc1dec4a1184203.tar.gz gdbm-b001c227fdf02e3ed1e87161cbc1dec4a1184203.tar.bz2 |
More input checking fixes
* src/gdbmdefs.h (gdbm_avail_block_valid_p): Minimal capacity
of an avail_block is 1 (one entry is stored in the block itself).
* src/gdbmopen.c (gdbm_avail_table_valid_p): New function.
(validate_header): Fix verification of dir_size and dir_bits.
Verify avail.size.
* src/falloc.c (pop_avail_block): Use gdbm_avail_table_valid_p
* src/gdbmtool.c (_gdbm_print_avail_list): Likewise.
Diffstat (limited to 'src/gdbmopen.c')
-rw-r--r-- | src/gdbmopen.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/src/gdbmopen.c b/src/gdbmopen.c index b84ad63..52b2739 100644 --- a/src/gdbmopen.c +++ b/src/gdbmopen.c @@ -56,6 +56,12 @@ bucket_element_count (gdbm_file_header const *hdr) / sizeof (bucket_element) + 1; } +int +gdbm_avail_table_valid_p (GDBM_FILE dbf, avail_block const *av) +{ + return gdbm_avail_block_valid_p (av) && av->size <= dbf->header->avail.size; +} + static int validate_header (gdbm_file_header const *hdr, struct stat const *st) { @@ -100,7 +106,10 @@ validate_header (gdbm_file_header const *hdr, struct stat const *st) return GDBM_BAD_HEADER; compute_directory_size (hdr->block_size, &dir_size, &dir_bits); - if (hdr->dir_size != dir_size || hdr->dir_bits != dir_bits) + if (!(hdr->dir_size >= dir_size)) + return GDBM_BAD_HEADER; + compute_directory_size (hdr->dir_size, &dir_size, &dir_bits); + if (hdr->dir_bits != dir_bits) return GDBM_BAD_HEADER; if (!(hdr->bucket_size > 0 && hdr->bucket_size > sizeof(hash_bucket))) @@ -112,6 +121,10 @@ validate_header (gdbm_file_header const *hdr, struct stat const *st) /* Validate the avail block */ if (!gdbm_avail_block_valid_p (&hdr->avail)) return GDBM_BAD_HEADER; + + if (((hdr->block_size - sizeof (gdbm_file_header)) / sizeof(avail_elem) + 1) + != hdr->avail.size) + return GDBM_BAD_HEADER; return 0; } |