diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2018-05-19 19:03:11 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2018-05-19 19:03:11 +0300 |
commit | 0f0c3dba3f676bf7a163586855f07ef427da3b4a (patch) | |
tree | 8805fce40824e051b4ccf74b98b95289e4c1563f | |
parent | 625a871bdd3fac33d236d63d6c053e969fdec9d7 (diff) | |
download | gdbm-0f0c3dba3f676bf7a163586855f07ef427da3b4a.tar.gz gdbm-0f0c3dba3f676bf7a163586855f07ef427da3b4a.tar.bz2 |
Catch more errors
* src/gdbmdump.c (_gdbm_dump_ascii): Break on errors
* src/gdbmopen.c (compute_directory_size): Remove unused argument.
(validate_header): Catch dir_size and dir_bits mismatches.
* src/mmap.c (_gdbm_mapped_lseek): Bail out on negative offsets.
* tests/dump03.at: New test.
* tests/dump04.at: New test.
* tests/Makefile.am: Add new tests.
* tests/testsuite.at: Add new tests.
-rw-r--r-- | src/gdbmdump.c | 2 | ||||
-rw-r--r-- | src/gdbmopen.c | 10 | ||||
-rw-r--r-- | src/mmap.c | 6 | ||||
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/dump03.at | 38 | ||||
-rw-r--r-- | tests/dump04.at | 34 | ||||
-rw-r--r-- | tests/testsuite.at | 2 |
7 files changed, 92 insertions, 2 deletions
diff --git a/src/gdbmdump.c b/src/gdbmdump.c index 4b8b041..daf6a43 100644 --- a/src/gdbmdump.c +++ b/src/gdbmdump.c @@ -103,6 +103,8 @@ _gdbm_dump_ascii (GDBM_FILE dbf, FILE *fp) break; } } + else + break; nextkey = gdbm_nextkey (dbf, key); free (key.dptr); free (data.dptr); diff --git a/src/gdbmopen.c b/src/gdbmopen.c index 9b214ad..5d59f65 100644 --- a/src/gdbmopen.c +++ b/src/gdbmopen.c @@ -32,7 +32,7 @@ #endif static void -compute_directory_size (GDBM_FILE dbf, blksize_t block_size, +compute_directory_size (blksize_t block_size, int *ret_dir_size, int *ret_dir_bits) { /* Create the initial hash table directory. */ @@ -59,6 +59,8 @@ bucket_element_count (gdbm_file_header const *hdr) static int validate_header (gdbm_file_header const *hdr, struct stat const *st) { + int dir_size, dir_bits; + /* Is the magic number good? */ if (hdr->header_magic != GDBM_MAGIC) { @@ -97,6 +99,10 @@ validate_header (gdbm_file_header const *hdr, struct stat const *st) && hdr->dir + hdr->dir_size < st->st_size)) 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) + return GDBM_BAD_HEADER; + if (!(hdr->bucket_size > 0 && hdr->bucket_size > sizeof(hash_bucket))) return GDBM_BAD_HEADER; @@ -251,7 +257,7 @@ gdbm_fd_open (int fd, const char *file_name, int block_size, block_size = STATBLKSIZE (file_stat); flags &= ~GDBM_BSEXACT; } - compute_directory_size (dbf, block_size, &dir_size, &dir_bits); + compute_directory_size (block_size, &dir_size, &dir_bits); GDBM_DEBUG (GDBM_DEBUG_OPEN, "%s: computed dir_size=%d, dir_bits=%d", dbf->name, dir_size, dir_bits); /* Check for correct block_size. */ @@ -394,6 +394,12 @@ _gdbm_mapped_lseek (GDBM_FILE dbf, off_t offset, int whence) } } + if (needle < 0) + { + errno = EINVAL; + return -1; + } + if (!_GDBM_IN_MAPPED_REGION_P (dbf, needle)) { _gdbm_mapped_unmap (dbf); diff --git a/tests/Makefile.am b/tests/Makefile.am index fc9fc42..b85110d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -67,6 +67,8 @@ TESTSUITE_AT = \ dump00.at\ dump01.at\ dump02.at\ + dump03.at\ + dump04.at\ create00.at\ delete00.at\ delete01.at\ diff --git a/tests/dump03.at b/tests/dump03.at new file mode 100644 index 0000000..a084246 --- /dev/null +++ b/tests/dump03.at @@ -0,0 +1,38 @@ +# This file is part of GDBM. -*- autoconf -*- +# Copyright (C) 2018 Free Software Foundation, Inc. +# +# GDBM is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# GDBM is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GDBM. If not, see <http://www.gnu.org/licenses/>. */ + +AT_SETUP([Negative bucket offset]) +AT_KEYWORDS([dump]) +AT_CHECK([ +AT_UNPACK([t.db],dnl +[H4sICFRAAFsAA2lkOjAwMDAwMCxzaWc6MTEsc3JjOjAwMDA4NyswMDAwODYsb3A6c3BsaWNlLHJl +cDoxNgDtlztOw0AQhtfCQkkIyEkaaJAxF6CkTM0FuAYFvVNzBEoKrkNNhZAAgQQRdCgF5uFH7M2u +vbO79gzRjhT9mm9nZ35Hft5cnk5YwNjfj6Xaz/Sa2Yl3k837IhjmelLJQ35ZoHsiHgub1+oBH1xB +qNqoK42I+KjqyEIfi5YYS36CCSKlYRXaGpvrsZ0+Q5P9AaCeTwYiDtOZ0cED92ybzNLT+47n2VDp +JVFwhT47OvN5I6/QBo36kR6EdP1QuZdsWcebr7mvUM9wP0X1WVP4qP6gGijWqWuvVb+m2vXYSTt9 +j6D7gmrONp5b8YWiIyI+gOpJ13e7uAwstlqG4M3V1pz11POmurtfTWJsn6saS/iwnM9r+ySysGnU +y9LiUZffO5Vj0FxSCvnHG20epbL4gvVJMP2PkeaKORkjjjvuOHVed0el5NNxx+t4aKY9w/0I6lHw +IcZn2Lb+j14JIl16KtfeYnlcSPgFgf/OqVN99bJU/5O8Pra4XO1JNgXWt8qnEo7lxxp/I+ZneRJS +8bN0RcmP445T44GEd+NnLOFYfhynyB8SWL0m3wTVh5za96PJP0H1ksCy/4h7ukUmfWbd+Vx3/pLA +6tvlU6S5KLyvVL9aMG/bmOMi/g1YZ0xx+S8AAA== +]) +gdbm_dump t.db t +], +[1], +[], +[gdbm_dump: dump error: Malformed bucket header +]) +AT_CLEANUP
\ No newline at end of file diff --git a/tests/dump04.at b/tests/dump04.at new file mode 100644 index 0000000..a37ea03 --- /dev/null +++ b/tests/dump04.at @@ -0,0 +1,34 @@ +# This file is part of GDBM. -*- autoconf -*- +# Copyright (C) 2018 Free Software Foundation, Inc. +# +# GDBM is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# GDBM is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GDBM. If not, see <http://www.gnu.org/licenses/>. */ + +AT_SETUP([Wrong dir_bits in header]) +AT_KEYWORDS([dump]) +AT_CHECK([ +AT_UNPACK([t.db],dnl +[H4sICIxAAFsAA2lkOjAwMDAwMSxzaWc6MTEsc3JjOjAwMDA3OCswMDAwODgsb3A6c3BsaWNlLHJl +cDoyAO2ZUQqCQBRFxyiCfoqEoD/bQUuINtECaiGtowW0gDbSFvpvAQVKpSmFMW8yZ/K9qXtADl6f +etEPhdlvFqEaKHXfVO5x4W3mWR4nylN2KfojQbNFGiHmLuAlvVzXFN4iT5YvUHOxsfGKyI9W3VTH +7vSClpOrUKTv8lR1UPsM9WnbohIAoCa/+LUGAACQcRHz8/1PRHAdC6nhjdkLwDAMwzBs9lBIDxiG +YQ89EdLjnYNi97H+P1X2HOhD9Gpbo/nIMH/OosrXjwh3XdYt53MTrm6C3Lt8zXBf3Ro793NAjlxO +HlaYZ6qGHPm38r6wPsiZ8tKIgD5O84iwtJ7IkX+S3wAsqaqZFzAAAA== +]) +gdbm_dump t.db t +], +[1], +[], +[gdbm_dump: gdbm_open failed: Malformed database file header +]) +AT_CLEANUP
\ No newline at end of file diff --git a/tests/testsuite.at b/tests/testsuite.at index c492e9f..9488245 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -83,5 +83,7 @@ AT_BANNER([Handling invalid input]) m4_include([dump00.at]) m4_include([dump01.at]) m4_include([dump02.at]) +m4_include([dump03.at]) +m4_include([dump04.at]) # End of testsuite.at |