]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Fix unaligned accesses in bt_split.c
authorTom Yu <tlyu@mit.edu>
Wed, 7 Sep 2016 21:28:34 +0000 (17:28 -0400)
committerTom Yu <tlyu@mit.edu>
Thu, 8 Sep 2016 18:53:52 +0000 (14:53 -0400)
In the libdb2 btree back end, splitting a page at an overflow key
could result in an unaligned access, causing a crash (and data
corruption) on platforms with strict alignment.  This probably occurs
only rarely in practice.

ticket: 8493 (new)
target_version: 1.14-next
target_version: 1.13-next
tags: pullup

src/plugins/kdb/db2/libdb2/btree/bt_split.c

index 2460aa54f83bb7ca4634cd5c815651310122e817..c5f151d813b5e1d86eeb10026c8c5b2faa6af8bb 100644 (file)
@@ -245,9 +245,12 @@ __bt_split(t, sp, key, data, flags, ilen, argskip)
                        WR_BINTERNAL(dest, nksize ? nksize : bl->ksize,
                            rchild->pgno, bl->flags & P_BIGKEY);
                        memmove(dest, bl->bytes, nksize ? nksize : bl->ksize);
-                       if (bl->flags & P_BIGKEY &&
-                           bt_preserve(t, *(db_pgno_t *)bl->bytes) == RET_ERROR)
-                               goto err1;
+                       if (bl->flags & P_BIGKEY) {
+                               db_pgno_t pgno;
+                               memcpy(&pgno, bl->bytes, sizeof(pgno));
+                               if (bt_preserve(t, pgno) == RET_ERROR)
+                                       goto err1;
+                       }
                        break;
                case P_RINTERNAL:
                        /*
@@ -568,9 +571,12 @@ bt_broot(t, h, l, r)
                 * If the key is on an overflow page, mark the overflow chain
                 * so it isn't deleted when the leaf copy of the key is deleted.
                 */
-               if (bl->flags & P_BIGKEY &&
-                   bt_preserve(t, *(db_pgno_t *)bl->bytes) == RET_ERROR)
-                       return (RET_ERROR);
+               if (bl->flags & P_BIGKEY) {
+                       db_pgno_t pgno;
+                       memcpy(&pgno, bl->bytes, sizeof(pgno));
+                       if (bt_preserve(t, pgno) == RET_ERROR)
+                               return (RET_ERROR);
+               }
                break;
        case P_BINTERNAL:
                bi = GETBINTERNAL(r, 0);