From owner-freebsd-bugs@FreeBSD.ORG Sun Aug 10 15:10:17 2003 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id BFA9237B401 for ; Sun, 10 Aug 2003 15:10:17 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id AF57043F85 for ; Sun, 10 Aug 2003 15:10:16 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.9/8.12.9) with ESMTP id h7AMAGUp038743 for ; Sun, 10 Aug 2003 15:10:16 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id h7AMAGmf038742; Sun, 10 Aug 2003 15:10:16 -0700 (PDT) Resent-Date: Sun, 10 Aug 2003 15:10:16 -0700 (PDT) Resent-Message-Id: <200308102210.h7AMAGmf038742@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Robert Watson Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D9E3937B404 for ; Sun, 10 Aug 2003 15:02:59 -0700 (PDT) Received: from fledge.watson.org (fledge.watson.org [204.156.12.50]) by mx1.FreeBSD.org (Postfix) with ESMTP id D5FDB43FAF for ; Sun, 10 Aug 2003 15:02:58 -0700 (PDT) (envelope-from robert@fledge.watson.org) Received: from fledge.watson.org (localhost [127.0.0.1]) by fledge.watson.org (8.12.9/8.12.9) with ESMTP id h7AM2eAL090297 for ; Sun, 10 Aug 2003 18:02:40 -0400 (EDT) (envelope-from robert@fledge.watson.org) Received: (from robert@localhost) by fledge.watson.org (8.12.9/8.12.9/Submit) id h7AM2eLG090296; Sun, 10 Aug 2003 18:02:40 -0400 (EDT) Message-Id: <200308102202.h7AM2eLG090296@fledge.watson.org> Date: Sun, 10 Aug 2003 18:02:40 -0400 (EDT) From: Robert Watson To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: bin/55448: dbm_nextkey() misbehaves after dbm_store() in dbm(3) X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Robert Watson List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Aug 2003 22:10:18 -0000 >Number: 55448 >Category: bin >Synopsis: dbm_nextkey() misbehaves after dbm_store() in dbm(3) >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Aug 10 15:10:16 PDT 2003 >Closed-Date: >Last-Modified: >Originator: Robert Watson >Release: FreeBSD 4.8-STABLE i386 >Organization: >Environment: System: FreeBSD fledge.watson.org 4.8-STABLE FreeBSD 4.8-STABLE #4: Mon Aug 4 00:26:28 EDT 2003 robert@fledge.watson.org:/home/data/obj/home/data/fbsd-stable/src/sys/FLEDGE i386 >Description: dbm(3) provides a simply database API based on db(3). It appears to be possible to create database corruption through the use of dbm_nextkey() and dbm_store() in the event that an entry in the database undergoes a size change. In particular, if you perform a dbm_fetch() on a key returned by dbm_nextkey(), and then dbm_store() a larger value than the data returned by dbm_fetch(), the next return from dbm_query() may point into the newly updated value of the previous entry. >How-To-Repeat: We have a local DBM database with two types of entries: old entries that have a data size of an int, and new entries, with a data size of two ints. During a sweep of the database, the software may decide to update fields from the old entry type to the new entry. Typically, this uses the above-described sequence: struct ipdata { int int1; int int2; }; key = dbm_firstkey(dbm); while (key.dptr != NULL) { data = dbm_fetch(dbm, key); switch (data.dsize) { case sizeof(int): /* fake up the new structure. */ break; case sizeof(id): id = *(struct ipdata *)data.dptr; break; default: /* panic */ } /* Perform data updates. */ data.dptr = (void *)&id; data.dsize = sizeof(id); if (dbm_store(dbm, key, data, DBM_REPLACE) == -1) perror("dbm_store"); key = dbm_nextkey(dbm); } When an entry is upgraded, the next call to dbm_nextkey() returns the second int in the new ipdata structure written, rather than the next field, suggesting that the iterator isn't updated for write changes to the database. >Fix: >Release-Note: >Audit-Trail: >Unformatted: