Date: Tue, 17 Mar 2009 17:17:06 GMT From: Nate Eldredge <neldredge@math.ucsd.edu> To: freebsd-gnats-submit@FreeBSD.org Subject: bin/132735: Berkeley db: corrupted file has record with absurd size Message-ID: <200903171717.n2HHH6b6089689@www.freebsd.org> Resent-Message-ID: <200903171720.n2HHK5K1024205@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 132735 >Category: bin >Synopsis: Berkeley db: corrupted file has record with absurd size >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Mar 17 17:20:05 UTC 2009 >Closed-Date: >Last-Modified: >Originator: Nate Eldredge >Release: 7.1-RELEASE-p3 >Organization: >Environment: FreeBSD vulcan.lan 7.1-RELEASE-p3 FreeBSD 7.1-RELEASE-p3 #1: Mon Feb 23 14:45:27 PST 2009 root@vulcan.lan:/usr/obj/usr/src/sys/VULCAN amd64 >Description: Hi, I have a Berkeley db file that is corrupted somehow, and when read with the db routines (dbopen(3)) from libc, returns bogus data that results in a crash. The file is available at http://www.math.ucsd.edu/~neldredg/testcase.db . It was produced by the recovery mechanism of vi(1), possibly while the system was crashing (I was working on a kernel bug at the time). Is this normal behavior for db when the input file is corrupted, or is it supposed to be more robust? >How-To-Repeat: I wrote the following test program: #include <sys/types.h> #include <db.h> #include <fcntl.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> void dump_dbt(const DBT *dbt) { printf("(%zu)", dbt->size); size_t i; unsigned char *p = dbt->data; for (i = 0; i < dbt->size; i++) printf(" %02x", p[i]); printf("\n"); } int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "Usage: %s filename\n", argv[0]); exit(2); } setvbuf(stdout, NULL, _IONBF, 0); DB *db = dbopen(argv[1], O_RDONLY, 0, DB_BTREE, NULL); if (!db) { perror("dbopen"); exit(1); } int ret; DBT key, data; while ((ret = db->seq(db, &key, &data, R_NEXT)) == 0) { printf("Key: "); dump_dbt(&key); printf("Data: "); dump_dbt(&data); } if (ret != 1) { perror("db->seq"); if (ret != -1) { fprintf(stderr, "Unexpected ret == %d\n", ret); } exit(1); } return 0; } When run on testcase.db, the output is: Key: (3) 00 00 00 Data: (757739264) 00 00 00 00 00 [...] followed by a segfault, since there obviously aren't 757739264 bytes of data in the file. >Fix: >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903171717.n2HHH6b6089689>