diff options
author | Tom Yu <tlyu@mit.edu> | 2016-08-26 15:24:52 -0400 |
---|---|---|
committer | Tom Yu <tlyu@mit.edu> | 2016-09-02 18:32:04 -0400 |
commit | b777b47bf7e24a44ae20065c28382e9a2d3834ef (patch) | |
tree | a113f80a6b19b53c4db1c3339b66055dae502e00 | |
parent | 0039539d64f4b33c170461ceb9e7b4fecff4df40 (diff) | |
download | krb5-b777b47bf7e24a44ae20065c28382e9a2d3834ef.zip krb5-b777b47bf7e24a44ae20065c28382e9a2d3834ef.tar.gz krb5-b777b47bf7e24a44ae20065c28382e9a2d3834ef.tar.bz2 |
Fix btree byte swapping for overflow data
When operating on a btree database file of the opposite endianness,
libdb2 was swapping the wrong bytes if a record had a short key but
overflow data. Fix this bug by not incrementing p when swapping a
P_BIGKEY overflow pointer, and by always skipping the full key size
before swapping a P_BIGDATA overflow pointer (instead of assuming that
a P_BIGKEY pointer always precedes a P_BIGDATA pointer).
(cherry picked from commit b6238a61769ffbf8a8ac653baeed1c3373b961f8)
ticket: 8485
version_fixed: 1.13.7
-rw-r--r-- | src/plugins/kdb/db2/libdb2/btree/bt_conv.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/src/plugins/kdb/db2/libdb2/btree/bt_conv.c b/src/plugins/kdb/db2/libdb2/btree/bt_conv.c index 6cfa216..c0644ed 100644 --- a/src/plugins/kdb/db2/libdb2/btree/bt_conv.c +++ b/src/plugins/kdb/db2/libdb2/btree/bt_conv.c @@ -41,6 +41,7 @@ static char sccsid[] = "@(#)bt_conv.c 8.5 (Berkeley) 8/17/94"; #include <sys/param.h> #include <stdio.h> +#include <string.h> #include "db-int.h" #include "btree.h" @@ -67,6 +68,7 @@ __bt_pgin(t, pg, pp) indx_t i, top; u_char flags; char *p; + u_int32_t ksize; if (!F_ISSET(((BTREE *)t), B_NEEDSWAP)) return; @@ -104,6 +106,7 @@ __bt_pgin(t, pg, pp) M_16_SWAP(h->linp[i]); p = (char *)GETBLEAF(h, i); P_32_SWAP(p); + memcpy(&ksize, p, sizeof(ksize)); p += sizeof(u_int32_t); P_32_SWAP(p); p += sizeof(u_int32_t); @@ -112,11 +115,10 @@ __bt_pgin(t, pg, pp) p += sizeof(u_char); if (flags & P_BIGKEY) { P_32_SWAP(p); - p += sizeof(db_pgno_t); - P_32_SWAP(p); + P_32_SWAP(p + sizeof(db_pgno_t)); } if (flags & P_BIGDATA) { - p += sizeof(u_int32_t); + p += ksize; P_32_SWAP(p); p += sizeof(db_pgno_t); P_32_SWAP(p); @@ -135,6 +137,7 @@ __bt_pgout(t, pg, pp) indx_t i, top; u_char flags; char *p; + u_int32_t ksize; if (!F_ISSET(((BTREE *)t), B_NEEDSWAP)) return; @@ -162,6 +165,7 @@ __bt_pgout(t, pg, pp) } else if ((h->flags & P_TYPE) == P_BLEAF) for (i = 0; i < top; i++) { + ksize = GETBLEAF(h, i)->ksize; p = (char *)GETBLEAF(h, i); P_32_SWAP(p); p += sizeof(u_int32_t); @@ -172,11 +176,10 @@ __bt_pgout(t, pg, pp) p += sizeof(u_char); if (flags & P_BIGKEY) { P_32_SWAP(p); - p += sizeof(db_pgno_t); - P_32_SWAP(p); + P_32_SWAP(p + sizeof(db_pgno_t)); } if (flags & P_BIGDATA) { - p += sizeof(u_int32_t); + p += ksize; P_32_SWAP(p); p += sizeof(db_pgno_t); P_32_SWAP(p); |