mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +00:00
[master] check file and tree headers when loading map files
4792. [bug] Fix map file header correctness check. [RT #38418]
This commit is contained in:
parent
89d1777560
commit
5b69d3da83
2
CHANGES
2
CHANGES
@ -1,3 +1,5 @@
|
||||
4792. [bug] Fix map file header correctness check. [RT #38418]
|
||||
|
||||
4791. [doc] Fixed outdated documentation about export libraries.
|
||||
[RT #46341]
|
||||
|
||||
|
@ -238,6 +238,16 @@ done
|
||||
[ $ret -eq 0 ] || echo "I:failed"
|
||||
status=`expr $status + $ret`
|
||||
|
||||
# stomp on the file header
|
||||
echo "I:checking corrupt map files fail to load (bad file header)"
|
||||
ret=0
|
||||
./named-compilezone -D -f text -F map -o map.5 example.nil baseline.txt > /dev/null
|
||||
cp map.5 badmap
|
||||
stomp badmap 0 32 99
|
||||
./named-compilezone -D -f map -F text -o text.5 example.nil badmap > /dev/null
|
||||
[ $? = 1 ] || ret=1
|
||||
[ $ret -eq 0 ] || echo "I:failed"
|
||||
status=`expr $status + $ret`
|
||||
# stomp on the file data so it hashes differently.
|
||||
# these are small and subtle changes, so that the resulting file
|
||||
# would appear to be a legitimate map file and would not trigger an
|
||||
@ -245,7 +255,6 @@ status=`expr $status + $ret`
|
||||
# load because of a SHA1 hash mismatch.
|
||||
echo "I:checking corrupt map files fail to load (bad node header)"
|
||||
ret=0
|
||||
./named-compilezone -D -f text -F map -o map.5 example.nil baseline.txt > /dev/null
|
||||
cp map.5 badmap
|
||||
stomp badmap 2754 2 99
|
||||
./named-compilezone -D -f map -F text -o text.5 example.nil badmap > /dev/null
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <isc/file.h>
|
||||
#include <isc/hex.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/once.h>
|
||||
#include <isc/platform.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/refcount.h>
|
||||
@ -138,6 +139,9 @@ static isc_result_t
|
||||
write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset,
|
||||
isc_uint64_t crc);
|
||||
|
||||
static isc_boolean_t
|
||||
match_header_version(file_header_t *header);
|
||||
|
||||
static isc_result_t
|
||||
serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
|
||||
uintptr_t right, uintptr_t down, uintptr_t parent,
|
||||
@ -483,6 +487,18 @@ dns_rbt_zero_header(FILE *file) {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_once_t once = ISC_ONCE_INIT;
|
||||
|
||||
static void
|
||||
init_file_version(void) {
|
||||
int n;
|
||||
|
||||
memset(FILE_VERSION, 0, sizeof(FILE_VERSION));
|
||||
n = snprintf(FILE_VERSION, sizeof(FILE_VERSION),
|
||||
"RBT Image %s %s", dns_major, dns_mapapi);
|
||||
INSIST(n > 0 && (unsigned int)n < sizeof(FILE_VERSION));
|
||||
}
|
||||
|
||||
/*
|
||||
* Write out the real header, including NodeDump version information
|
||||
* and the offset of the first node.
|
||||
@ -498,11 +514,7 @@ write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset,
|
||||
isc_result_t result;
|
||||
off_t location;
|
||||
|
||||
if (FILE_VERSION[0] == '\0') {
|
||||
memset(FILE_VERSION, 0, sizeof(FILE_VERSION));
|
||||
snprintf(FILE_VERSION, sizeof(FILE_VERSION),
|
||||
"RBT Image %s %s", dns_major, dns_mapapi);
|
||||
}
|
||||
RUNTIME_CHECK(isc_once_do(&once, init_file_version) == ISC_R_SUCCESS);
|
||||
|
||||
memset(&header, 0, sizeof(file_header_t));
|
||||
memmove(header.version1, FILE_VERSION, sizeof(header.version1));
|
||||
@ -534,6 +546,21 @@ write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset,
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
match_header_version(file_header_t *header) {
|
||||
RUNTIME_CHECK(isc_once_do(&once, init_file_version) == ISC_R_SUCCESS);
|
||||
|
||||
if (memcmp(header->version1, FILE_VERSION,
|
||||
sizeof(header->version1)) != 0 ||
|
||||
memcmp(header->version2, FILE_VERSION,
|
||||
sizeof(header->version1)) != 0)
|
||||
{
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
|
||||
uintptr_t right, uintptr_t down, uintptr_t parent,
|
||||
@ -608,7 +635,7 @@ serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
|
||||
#endif
|
||||
|
||||
isc_crc64_update(crc, (const isc_uint8_t *) &temp_node,
|
||||
sizeof(dns_rbtnode_t));
|
||||
sizeof(dns_rbtnode_t));
|
||||
isc_crc64_update(crc, (const isc_uint8_t *) node_data, datasize);
|
||||
|
||||
cleanup:
|
||||
@ -880,6 +907,10 @@ dns_rbt_deserialize_tree(void *base_address, size_t filesize,
|
||||
rbt->mmap_location = base_address;
|
||||
|
||||
header = (file_header_t *)((char *)base_address + header_offset);
|
||||
if (!match_header_version(header)) {
|
||||
result = ISC_R_INVALIDFILE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#ifdef DNS_RDATASET_FIXED
|
||||
if (header->rdataset_fixed != 1) {
|
||||
|
@ -900,6 +900,8 @@ static void overmem(dns_db_t *db, isc_boolean_t over);
|
||||
static void setnsec3parameters(dns_db_t *db, rbtdb_version_t *version);
|
||||
static void setownercase(rdatasetheader_t *header, const dns_name_t *name);
|
||||
|
||||
static isc_boolean_t match_header_version(rbtdb_file_header_t *header);
|
||||
|
||||
/* Pad to 32 bytes */
|
||||
static char FILE_VERSION[32] = "\0";
|
||||
|
||||
@ -7479,10 +7481,14 @@ deserialize32(void *arg, FILE *f, off_t offset) {
|
||||
#endif
|
||||
|
||||
base = isc_file_mmap(NULL, filesize, protect, flags, fd, 0);
|
||||
if (base == NULL || base == MAP_FAILED)
|
||||
if (base == NULL || base == MAP_FAILED) {
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
header = (rbtdb_file_header_t *)(base + offset);
|
||||
if (!match_header_version(header)) {
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
if (header->tree != 0) {
|
||||
result = dns_rbt_deserialize_tree(base, filesize,
|
||||
@ -7786,6 +7792,21 @@ rbtdb_write_header(FILE *rbtfile, off_t tree_location, off_t nsec_location,
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
match_header_version(rbtdb_file_header_t *header) {
|
||||
RUNTIME_CHECK(isc_once_do(&once, init_file_version) == ISC_R_SUCCESS);
|
||||
|
||||
if (memcmp(header->version1, FILE_VERSION,
|
||||
sizeof(header->version1)) != 0 ||
|
||||
memcmp(header->version2, FILE_VERSION,
|
||||
sizeof(header->version1)) != 0)
|
||||
{
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
serialize(dns_db_t *db, dns_dbversion_t *ver, FILE *rbtfile) {
|
||||
rbtdb_version_t *version = (rbtdb_version_t *) ver;
|
||||
|
Loading…
x
Reference in New Issue
Block a user