mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 22:45:39 +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:
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.
|
4791. [doc] Fixed outdated documentation about export libraries.
|
||||||
[RT #46341]
|
[RT #46341]
|
||||||
|
|
||||||
|
@@ -238,6 +238,16 @@ done
|
|||||||
[ $ret -eq 0 ] || echo "I:failed"
|
[ $ret -eq 0 ] || echo "I:failed"
|
||||||
status=`expr $status + $ret`
|
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.
|
# stomp on the file data so it hashes differently.
|
||||||
# these are small and subtle changes, so that the resulting file
|
# these are small and subtle changes, so that the resulting file
|
||||||
# would appear to be a legitimate map file and would not trigger an
|
# 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.
|
# load because of a SHA1 hash mismatch.
|
||||||
echo "I:checking corrupt map files fail to load (bad node header)"
|
echo "I:checking corrupt map files fail to load (bad node header)"
|
||||||
ret=0
|
ret=0
|
||||||
./named-compilezone -D -f text -F map -o map.5 example.nil baseline.txt > /dev/null
|
|
||||||
cp map.5 badmap
|
cp map.5 badmap
|
||||||
stomp badmap 2754 2 99
|
stomp badmap 2754 2 99
|
||||||
./named-compilezone -D -f map -F text -o text.5 example.nil badmap > /dev/null
|
./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/file.h>
|
||||||
#include <isc/hex.h>
|
#include <isc/hex.h>
|
||||||
#include <isc/mem.h>
|
#include <isc/mem.h>
|
||||||
|
#include <isc/once.h>
|
||||||
#include <isc/platform.h>
|
#include <isc/platform.h>
|
||||||
#include <isc/print.h>
|
#include <isc/print.h>
|
||||||
#include <isc/refcount.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,
|
write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset,
|
||||||
isc_uint64_t crc);
|
isc_uint64_t crc);
|
||||||
|
|
||||||
|
static isc_boolean_t
|
||||||
|
match_header_version(file_header_t *header);
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
|
serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
|
||||||
uintptr_t right, uintptr_t down, uintptr_t parent,
|
uintptr_t right, uintptr_t down, uintptr_t parent,
|
||||||
@@ -483,6 +487,18 @@ dns_rbt_zero_header(FILE *file) {
|
|||||||
return (ISC_R_SUCCESS);
|
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
|
* Write out the real header, including NodeDump version information
|
||||||
* and the offset of the first node.
|
* 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;
|
isc_result_t result;
|
||||||
off_t location;
|
off_t location;
|
||||||
|
|
||||||
if (FILE_VERSION[0] == '\0') {
|
RUNTIME_CHECK(isc_once_do(&once, init_file_version) == ISC_R_SUCCESS);
|
||||||
memset(FILE_VERSION, 0, sizeof(FILE_VERSION));
|
|
||||||
snprintf(FILE_VERSION, sizeof(FILE_VERSION),
|
|
||||||
"RBT Image %s %s", dns_major, dns_mapapi);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&header, 0, sizeof(file_header_t));
|
memset(&header, 0, sizeof(file_header_t));
|
||||||
memmove(header.version1, FILE_VERSION, sizeof(header.version1));
|
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);
|
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
|
static isc_result_t
|
||||||
serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
|
serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
|
||||||
uintptr_t right, uintptr_t down, uintptr_t parent,
|
uintptr_t right, uintptr_t down, uintptr_t parent,
|
||||||
@@ -880,6 +907,10 @@ dns_rbt_deserialize_tree(void *base_address, size_t filesize,
|
|||||||
rbt->mmap_location = base_address;
|
rbt->mmap_location = base_address;
|
||||||
|
|
||||||
header = (file_header_t *)((char *)base_address + header_offset);
|
header = (file_header_t *)((char *)base_address + header_offset);
|
||||||
|
if (!match_header_version(header)) {
|
||||||
|
result = ISC_R_INVALIDFILE;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DNS_RDATASET_FIXED
|
#ifdef DNS_RDATASET_FIXED
|
||||||
if (header->rdataset_fixed != 1) {
|
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 setnsec3parameters(dns_db_t *db, rbtdb_version_t *version);
|
||||||
static void setownercase(rdatasetheader_t *header, const dns_name_t *name);
|
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 */
|
/* Pad to 32 bytes */
|
||||||
static char FILE_VERSION[32] = "\0";
|
static char FILE_VERSION[32] = "\0";
|
||||||
|
|
||||||
@@ -7479,10 +7481,14 @@ deserialize32(void *arg, FILE *f, off_t offset) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
base = isc_file_mmap(NULL, filesize, protect, flags, fd, 0);
|
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);
|
return (ISC_R_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
header = (rbtdb_file_header_t *)(base + offset);
|
header = (rbtdb_file_header_t *)(base + offset);
|
||||||
|
if (!match_header_version(header)) {
|
||||||
|
return (ISC_R_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
if (header->tree != 0) {
|
if (header->tree != 0) {
|
||||||
result = dns_rbt_deserialize_tree(base, filesize,
|
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);
|
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
|
static isc_result_t
|
||||||
serialize(dns_db_t *db, dns_dbversion_t *ver, FILE *rbtfile) {
|
serialize(dns_db_t *db, dns_dbversion_t *ver, FILE *rbtfile) {
|
||||||
rbtdb_version_t *version = (rbtdb_version_t *) ver;
|
rbtdb_version_t *version = (rbtdb_version_t *) ver;
|
||||||
|
Reference in New Issue
Block a user