bin/132735: Berkeley db: corrupted file has record with absurd size
Nate Eldredge
neldredge at math.ucsd.edu
Tue Mar 17 10:20:07 PDT 2009
>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 at 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:
More information about the freebsd-bugs
mailing list