From owner-svn-src-head@FreeBSD.ORG Sat Mar 28 06:30:43 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A65DF106566B; Sat, 28 Mar 2009 06:30:43 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7A4068FC0A; Sat, 28 Mar 2009 06:30:43 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n2S6UhDb086989; Sat, 28 Mar 2009 06:30:43 GMT (envelope-from delphij@svn.freebsd.org) Received: (from delphij@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n2S6Uhrr086987; Sat, 28 Mar 2009 06:30:43 GMT (envelope-from delphij@svn.freebsd.org) Message-Id: <200903280630.n2S6Uhrr086987@svn.freebsd.org> From: Xin LI Date: Sat, 28 Mar 2009 06:30:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r190491 - head/lib/libc/db/hash X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 28 Mar 2009 06:30:44 -0000 Author: delphij Date: Sat Mar 28 06:30:43 2009 New Revision: 190491 URL: http://svn.freebsd.org/changeset/base/190491 Log: Fix a crash when iterating over a hash and removing its elements. Obtained from: OpenBSD Modified: head/lib/libc/db/hash/hash.c head/lib/libc/db/hash/hash_page.c Modified: head/lib/libc/db/hash/hash.c ============================================================================== --- head/lib/libc/db/hash/hash.c Sat Mar 28 06:25:33 2009 (r190490) +++ head/lib/libc/db/hash/hash.c Sat Mar 28 06:30:43 2009 (r190491) @@ -539,8 +539,7 @@ hash_put(const DB *dbp, DBT *key, const hashp = (HTAB *)dbp->internal; if (flag && flag != R_NOOVERWRITE) { - hashp->error = EINVAL; - errno = EINVAL; + hashp->error = errno = EINVAL; return (ERROR); } if ((hashp->flags & O_ACCMODE) == O_RDONLY) { @@ -719,7 +718,7 @@ hash_seq(const DB *dbp, DBT *key, DBT *d hashp->cndx = 1; hashp->cpage = NULL; } - + next_bucket: for (bp = NULL; !bp || !bp[0]; ) { if (!(bufp = hashp->cpage)) { for (bucket = hashp->cbucket; @@ -738,8 +737,18 @@ hash_seq(const DB *dbp, DBT *key, DBT *d hashp->cbucket = -1; return (ABNORMAL); } - } else + } else { bp = (u_int16_t *)hashp->cpage->page; + if (flag == R_NEXT) { + hashp->cndx += 2; + if (hashp->cndx > bp[0]) { + hashp->cpage = NULL; + hashp->cbucket++; + hashp->cndx = 1; + goto next_bucket; + } + } + } #ifdef DEBUG assert(bp); @@ -767,13 +776,6 @@ hash_seq(const DB *dbp, DBT *key, DBT *d key->size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZE) - bp[ndx]; data->data = (u_char *)hashp->cpage->page + bp[ndx + 1]; data->size = bp[ndx] - bp[ndx + 1]; - ndx += 2; - if (ndx > bp[0]) { - hashp->cpage = NULL; - hashp->cbucket++; - hashp->cndx = 1; - } else - hashp->cndx = ndx; } return (SUCCESS); } Modified: head/lib/libc/db/hash/hash_page.c ============================================================================== --- head/lib/libc/db/hash/hash_page.c Sat Mar 28 06:25:33 2009 (r190490) +++ head/lib/libc/db/hash/hash_page.c Sat Mar 28 06:30:43 2009 (r190491) @@ -155,6 +155,14 @@ __delpair(HTAB *hashp, BUFHEAD *bufp, in bp[i - 1] = bp[i + 1] + pairlen; } } + if (ndx == hashp->cndx) { + /* + * We just removed pair we were "pointing" to. + * By moving back the cndx we ensure subsequent + * hash_seq() calls won't skip over any entries. + */ + hashp->cndx -= 2; + } } /* Finally adjust the page data */ bp[n] = OFFSET(bp) + pairlen;