From: drh Date: Fri, 21 May 2010 13:16:18 +0000 (+0000) Subject: Fix the wal-index header read routine so that it correctly detects a zero X-Git-Tag: version-3.7.2~354 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f0b20f8801e1a2e203aa26104cddaf522f935145;p=thirdparty%2Fsqlite.git Fix the wal-index header read routine so that it correctly detects a zero header as being malformed and in need of a wal-index rebuild. FossilOrigin-Name: 1a4eb3a3efe86c7caff4d9a5894953bce378f841 --- diff --git a/manifest b/manifest index 4b9430e5b6..5a581f39da 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Add\sa\snew\sxShmBarrier\smethod\sto\sthe\sVFS\s-\sa\sshared-memory\sfence\soperation.\nImplement\sthe\ssame\sin\sboth\sunix\sand\swin32.\s\sUse\sit\sto\smake\sthe\sWAL\ssubsystem\nmore\srobust. -D 2010-05-20T23:51:07 +C Fix\sthe\swal-index\sheader\sread\sroutine\sso\sthat\sit\scorrectly\sdetects\sa\szero\nheader\sas\sbeing\smalformed\sand\sin\sneed\sof\sa\swal-index\srebuild. +D 2010-05-21T13:16:19 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -227,7 +227,7 @@ F src/vdbeblob.c 5327132a42a91e8b7acfb60b9d2c3b1c5c863e0e F src/vdbemem.c 2a82f455f6ca6f78b59fb312f96054c04ae0ead1 F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2 F src/vtab.c a0f8a40274e4261696ef57aa806de2776ab72cda -F src/wal.c 2352dd3a2bb271e5c76c9c4407f6590ae5e3768c +F src/wal.c 1c3abceacad9659ecd1558be75a2114d953d3b7e F src/wal.h 434f76f51225bb614e43ccb6bd2341541ba6a06e F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c 75fee9e255b62f773fcadd1d1f25b6f63ac7a356 @@ -816,14 +816,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 9580ecb7e3beb1949a71784a3dcd1823a88e4a9d -R 6169e39cb99c7a86e9c9e7505a7068ac +P 1bd011c9fed5ef29fb616b4d0a52df3b82221b1f +R b1aca10baf167dbb95ab7e54f5a950e6 U drh -Z b1a49e07405386f7203bad3d085615ae +Z 69b1bc82a1680c243dd4a43f4faa2d67 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFL9cruoxKgR168RlERAkAFAJ9xRzU75gC9SA4GXt3kPWkhCqvfpACdF9xG -lxuM43sIwrUxctG6rY11InI= -=HHWB +iD8DBQFL9oenoxKgR168RlERAhg+AJ9n9qywdfuiNJpDkY+WtSlKP+eZVgCffwF8 +SmDbNBLJmDSM4k/xfAbThXY= +=j0sy -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 767cd5e0f2..b7c453becd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1bd011c9fed5ef29fb616b4d0a52df3b82221b1f \ No newline at end of file +1a4eb3a3efe86c7caff4d9a5894953bce378f841 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 65c711d8f1..a320d25e99 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1126,7 +1126,7 @@ int sqlite3WalClose( */ int walIndexTryHdr(Wal *pWal, int *pChanged){ u32 aCksum[2]; /* Checksum on the header content */ - WalIndexHdr hdr1, hdr2; /* Two copies of the header content */ + WalIndexHdr h1, h2; /* Two copies of the header content */ WalIndexHdr *aHdr; /* Header in shared memory */ assert( pWal->pWiData ); @@ -1142,25 +1142,31 @@ int walIndexTryHdr(Wal *pWal, int *pChanged){ ** (WRITE, PENDING, CHECKPOINT or RECOVER) lock on the wal-index ** file, meaning it is possible that an inconsistent snapshot is read ** from the file. If this happens, return non-zero. + ** + ** There are two copies of the header at the beginning of the wal-index. + ** When reading, read [0] first then [1]. Writes are in the reverse order. + ** Memory barriers are used to prevent the compiler or the hardware from + ** reordering the reads and writes. */ aHdr = (WalIndexHdr*)pWal->pWiData; - memcpy(&hdr1, &aHdr[0], sizeof(hdr1)); + memcpy(&h1, &aHdr[0], sizeof(h1)); sqlite3OsShmBarrier(pWal->pDbFd); - memcpy(&hdr2, &aHdr[1], sizeof(hdr2)); + memcpy(&h2, &aHdr[1], sizeof(h2)); - if( memcmp(&hdr1, &hdr2, sizeof(hdr1))!=0 ){ - /* Dirty read */ - return 1; + if( memcmp(&h1, &h2, sizeof(h1))!=0 ){ + return 1; /* Dirty read */ } - walChecksumBytes((u8*)&hdr1, sizeof(hdr1)-sizeof(hdr1.aCksum), 0, aCksum); - if( aCksum[0]!=hdr1.aCksum[0] || aCksum[1]!=hdr1.aCksum[1] ){ - /* Malformed header */ - return 1; + if( h1.szPage==0 ){ + return 1; /* Malformed header - probably all zeros */ + } + walChecksumBytes((u8*)&h1, sizeof(h1)-sizeof(h1.aCksum), 0, aCksum); + if( aCksum[0]!=h1.aCksum[0] || aCksum[1]!=h1.aCksum[1] ){ + return 1; /* Checksum does not match */ } - if( memcmp(&pWal->hdr, &hdr1, sizeof(WalIndexHdr)) ){ + if( memcmp(&pWal->hdr, &h1, sizeof(WalIndexHdr)) ){ *pChanged = 1; - memcpy(&pWal->hdr, &hdr1, sizeof(WalIndexHdr)); + memcpy(&pWal->hdr, &h1, sizeof(WalIndexHdr)); pWal->szPage = pWal->hdr.szPage; }