diff options
author | Pedro F. Giffuni <pfg@FreeBSD.org> | 2016-09-26 16:06:50 +0000 |
---|---|---|
committer | Pedro F. Giffuni <pfg@FreeBSD.org> | 2016-09-26 16:06:50 +0000 |
commit | 70e7268bd5eb7579eae29ef57830562be34ef21e (patch) | |
tree | 88086cc0b995c30e49212b65910bae6443b61237 /lib/libc/db/hash | |
parent | 7c9a4d09d62bab79293f55898583f7d698a91dbf (diff) | |
download | src-70e7268bd5eb7579eae29ef57830562be34ef21e.tar.gz src-70e7268bd5eb7579eae29ef57830562be34ef21e.zip |
hash(3): protect in-memory page when using cross-endianness.
When writing out pages in the "other endian" format, make a copy
instead of trashing the in-memory one.
Obtained from: NetBSD (CVS rev. 1.29)
Notes
Notes:
svn path=/head/; revision=306349
Diffstat (limited to 'lib/libc/db/hash')
-rw-r--r-- | lib/libc/db/hash/hash_page.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/lib/libc/db/hash/hash_page.c b/lib/libc/db/hash/hash_page.c index a2bb7cfc84d2..ec2d184fe23b 100644 --- a/lib/libc/db/hash/hash_page.c +++ b/lib/libc/db/hash/hash_page.c @@ -572,7 +572,9 @@ __get_page(HTAB *hashp, char *p, u_int32_t bucket, int is_bucket, int is_disk, int __put_page(HTAB *hashp, char *p, u_int32_t bucket, int is_bucket, int is_bitmap) { - int fd, page, size, wsize; + int fd, page, size; + ssize_t wsize; + char pbuf[MAX_BSIZE]; size = hashp->BSIZE; if ((hashp->fp == -1) && open_temp(hashp)) @@ -582,15 +584,18 @@ __put_page(HTAB *hashp, char *p, u_int32_t bucket, int is_bucket, int is_bitmap) if (hashp->LORDER != BYTE_ORDER) { int i, max; + memcpy(pbuf, p, size); if (is_bitmap) { max = hashp->BSIZE >> 2; /* divide by 4 */ for (i = 0; i < max; i++) - M_32_SWAP(((int *)p)[i]); + M_32_SWAP(((int *)pbuf)[i]); } else { - max = ((u_int16_t *)p)[0] + 2; + uint16_t *bp = (uint16_t *)(void *)pbuf; + max = bp[0] + 2; for (i = 0; i <= max; i++) - M_16_SWAP(((u_int16_t *)p)[i]); + M_16_SWAP(bp[i]); } + p = pbuf; } if (is_bucket) page = BUCKET_TO_PAGE(bucket); |