From: Andreas Steffen Date: Tue, 21 Jul 2009 20:23:51 +0000 (+0200) Subject: added file and segment lengths to checksum.c X-Git-Tag: 4.3.4~57 X-Git-Url: https://git.strongswan.org/?p=strongswan.git;a=commitdiff_plain;h=e1089f5906e4e148f5f1659373ff5f71a8dfcba2 added file and segment lengths to checksum.c --- diff --git a/src/checksum/checksum_builder.c b/src/checksum/checksum_builder.c index d2c042d..71cca1d 100644 --- a/src/checksum/checksum_builder.c +++ b/src/checksum/checksum_builder.c @@ -44,12 +44,16 @@ int main(int argc, char* argv[]) printf("#include \n"); printf("\n"); printf("integrity_checksum_t checksums[] = {\n"); + fprintf(stderr, "integrity test data:\n"); + fprintf(stderr, "module name, file size / checksum segment size / checksum\n"); for (i = 1; i < argc; i++) { char *name, *path, *sname = NULL; void *handle, *symbol; u_int32_t fsum, ssum; - + size_t fsize = 0; + size_t ssize = 0; + path = argv[i]; if ((name = strstr(path, "libstrongswan-"))) @@ -79,7 +83,7 @@ int main(int argc, char* argv[]) continue; } - fsum = integrity->build_file(integrity, path); + fsum = integrity->build_file(integrity, path, &fsize); ssum = 0; if (sname) { @@ -89,7 +93,7 @@ int main(int argc, char* argv[]) symbol = dlsym(handle, sname); if (symbol) { - ssum = integrity->build_segment(integrity, symbol); + ssum = integrity->build_segment(integrity, symbol, &ssize); } else { @@ -102,7 +106,10 @@ int main(int argc, char* argv[]) fprintf(stderr, "dlopen failed: %s\n", dlerror()); } } - printf("\t{\"%-20s0x%08x, 0x%08x},\n", name, fsum, ssum); + printf("\t{\"%-20s%7u, 0x%08x, %6u, 0x%08x},\n", + name, fsize, fsum, ssize, ssum); + fprintf(stderr, "\"%-20s%7u / 0x%08x %6u / 0x%08x\n", + name, fsize, fsum, ssize, ssum); free(name); } printf("};\n"); diff --git a/src/libstrongswan/integrity_checker.c b/src/libstrongswan/integrity_checker.c index eb0bc14..32a296d 100644 --- a/src/libstrongswan/integrity_checker.c +++ b/src/libstrongswan/integrity_checker.c @@ -60,7 +60,8 @@ struct private_integrity_checker_t { /** * Implementation of integrity_checker_t.build_file */ -static u_int32_t build_file(private_integrity_checker_t *this, char *file) +static u_int32_t build_file(private_integrity_checker_t *this, char *file, + size_t *len) { u_int32_t checksum; chunk_t contents; @@ -71,13 +72,13 @@ static u_int32_t build_file(private_integrity_checker_t *this, char *file) fd = open(file, O_RDONLY); if (fd == -1) { - DBG1("opening '%s' failed: %s", file, strerror(errno)); + DBG1(" opening '%s' failed: %s", file, strerror(errno)); return 0; } if (fstat(fd, &sb) == -1) { - DBG1("getting file size of '%s' failed: %s", file, strerror(errno)); + DBG1(" getting file size of '%s' failed: %s", file, strerror(errno)); close(fd); return 0; } @@ -85,11 +86,12 @@ static u_int32_t build_file(private_integrity_checker_t *this, char *file) addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) { - DBG1("mapping '%s' failed: %s", file, strerror(errno)); + DBG1(" mapping '%s' failed: %s", file, strerror(errno)); close(fd); return 0; } - + + *len = sb.st_size; contents = chunk_create(addr, sb.st_size); checksum = chunk_hash(contents); @@ -136,24 +138,26 @@ static int callback(struct dl_phdr_info *dlpi, size_t size, Dl_info *dli) /** * Implementation of integrity_checker_t.build_segment */ -static u_int32_t build_segment(private_integrity_checker_t *this, void *sym) +static u_int32_t build_segment(private_integrity_checker_t *this, void *sym, + size_t *len) { chunk_t segment; Dl_info dli; if (dladdr(sym, &dli) == 0) { - DBG1("unable to locate symbol: %s", dlerror()); + DBG1(" unable to locate symbol: %s", dlerror()); return 0; } /* we reuse the Dl_info struct as in/out parameter */ if (!dl_iterate_phdr((void*)callback, &dli)) { - DBG1("executable section not found"); + DBG1(" executable section not found"); return 0; } segment = chunk_create(dli.dli_fbase, dli.dli_saddr - dli.dli_fbase); + *len = segment.len; return chunk_hash(segment); } @@ -183,6 +187,7 @@ static bool check_file(private_integrity_checker_t *this, { integrity_checksum_t *cs; u_int32_t sum; + size_t len = 0; cs = find_checksum(this, name); if (!cs) @@ -190,8 +195,18 @@ static bool check_file(private_integrity_checker_t *this, DBG1(" '%s' file checksum not found", name); return FALSE; } - sum = build_file(this, file); - if (!sum || cs->file != sum) + sum = build_file(this, file, &len); + if (!sum) + { + return FALSE; + } + if (cs->file_len != len) + { + DBG1(" invalid '%s' file size: %u bytes, expected %u bytes", + name, len, cs->file_len); + return FALSE; + } + if (cs->file != sum) { DBG1(" invalid '%s' file checksum: %08x, expected %08x", name, sum, cs->file); @@ -209,6 +224,7 @@ static bool check_segment(private_integrity_checker_t *this, { integrity_checksum_t *cs; u_int32_t sum; + size_t len = 0; cs = find_checksum(this, name); if (!cs) @@ -216,8 +232,18 @@ static bool check_segment(private_integrity_checker_t *this, DBG1(" '%s' segment checksum not found", name); return FALSE; } - sum = build_segment(this, sym); - if (!sum || cs->segment != sum) + sum = build_segment(this, sym, &len); + if (!sum) + { + return FALSE; + } + if (cs->segment_len != len) + { + DBG1(" invalid '%s' segment size: %u bytes, expected %u bytes", + name, len, cs->segment_len); + return FALSE; + } + if (cs->segment != sum) { DBG1(" invalid '%s' segment checksum: %08x, expected %08x", name, sum, cs->segment); @@ -270,9 +296,9 @@ integrity_checker_t *integrity_checker_create(char *checksum_library) private_integrity_checker_t *this = malloc_thing(private_integrity_checker_t); this->public.check_file = (bool(*)(integrity_checker_t*, char *name, char *file))check_file; - this->public.build_file = (u_int32_t(*)(integrity_checker_t*, char *file))build_file; + this->public.build_file = (u_int32_t(*)(integrity_checker_t*, char *file, size_t *len))build_file; this->public.check_segment = (bool(*)(integrity_checker_t*, char *name, void *sym))check_segment; - this->public.build_segment = (u_int32_t(*)(integrity_checker_t*, void *sym))build_segment; + this->public.build_segment = (u_int32_t(*)(integrity_checker_t*, void *sym, size_t *len))build_segment; this->public.check = (bool(*)(integrity_checker_t*, char *name, void *sym))check; this->public.destroy = (void(*)(integrity_checker_t*))destroy; diff --git a/src/libstrongswan/integrity_checker.h b/src/libstrongswan/integrity_checker.h index d10de5b..d078dd6 100644 --- a/src/libstrongswan/integrity_checker.h +++ b/src/libstrongswan/integrity_checker.h @@ -33,8 +33,12 @@ typedef struct integrity_checksum_t integrity_checksum_t; struct integrity_checksum_t { /* name of the checksum */ char *name; + /* size in bytes of the file on disk */ + size_t file_len; /* checksum of the file on disk */ u_int32_t file; + /* size in bytes of executable segment in memory */ + size_t segment_len; /* checksum of the executable segment in memory */ u_int32_t segment; }; @@ -60,9 +64,10 @@ struct integrity_checker_t { * Build the integrity checksum of a file on disk. * * @param file path to file + * @param len return length in bytes of file * @return checksum, 0 on error */ - u_int32_t (*build_file)(integrity_checker_t *this, char *file); + u_int32_t (*build_file)(integrity_checker_t *this, char *file, size_t *len); /** * Check the integrity of the code segment in memory. @@ -72,14 +77,14 @@ struct integrity_checker_t { * @return TRUE if integrity tested successfully */ bool (*check_segment)(integrity_checker_t *this, char *name, void *sym); - /** * Build the integrity checksum of a code segment in memory. * * @param sym a symbol in the segment to check + * @param len return length in bytes of code segment in memory * @return checksum, 0 on error */ - u_int32_t (*build_segment)(integrity_checker_t *this, void *sym); + u_int32_t (*build_segment)(integrity_checker_t *this, void *sym, size_t *len); /** * Check both, on disk file integrity and loaded segment.