added file and segment lengths to checksum.c

This commit is contained in:
Andreas Steffen
2009-07-21 22:23:51 +02:00
parent 8ce8e19068
commit e1089f5906
3 changed files with 59 additions and 21 deletions
+10 -3
View File
@@ -44,11 +44,15 @@ int main(int argc, char* argv[])
printf("#include <library.h>\n"); printf("#include <library.h>\n");
printf("\n"); printf("\n");
printf("integrity_checksum_t checksums[] = {\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++) for (i = 1; i < argc; i++)
{ {
char *name, *path, *sname = NULL; char *name, *path, *sname = NULL;
void *handle, *symbol; void *handle, *symbol;
u_int32_t fsum, ssum; u_int32_t fsum, ssum;
size_t fsize = 0;
size_t ssize = 0;
path = argv[i]; path = argv[i];
@@ -79,7 +83,7 @@ int main(int argc, char* argv[])
continue; continue;
} }
fsum = integrity->build_file(integrity, path); fsum = integrity->build_file(integrity, path, &fsize);
ssum = 0; ssum = 0;
if (sname) if (sname)
{ {
@@ -89,7 +93,7 @@ int main(int argc, char* argv[])
symbol = dlsym(handle, sname); symbol = dlsym(handle, sname);
if (symbol) if (symbol)
{ {
ssum = integrity->build_segment(integrity, symbol); ssum = integrity->build_segment(integrity, symbol, &ssize);
} }
else else
{ {
@@ -102,7 +106,10 @@ int main(int argc, char* argv[])
fprintf(stderr, "dlopen failed: %s\n", dlerror()); 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); free(name);
} }
printf("};\n"); printf("};\n");
+34 -8
View File
@@ -60,7 +60,8 @@ struct private_integrity_checker_t {
/** /**
* Implementation of integrity_checker_t.build_file * 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; u_int32_t checksum;
chunk_t contents; chunk_t contents;
@@ -90,6 +91,7 @@ static u_int32_t build_file(private_integrity_checker_t *this, char *file)
return 0; return 0;
} }
*len = sb.st_size;
contents = chunk_create(addr, sb.st_size); contents = chunk_create(addr, sb.st_size);
checksum = chunk_hash(contents); checksum = chunk_hash(contents);
@@ -136,7 +138,8 @@ static int callback(struct dl_phdr_info *dlpi, size_t size, Dl_info *dli)
/** /**
* Implementation of integrity_checker_t.build_segment * 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; chunk_t segment;
Dl_info dli; Dl_info dli;
@@ -154,6 +157,7 @@ static u_int32_t build_segment(private_integrity_checker_t *this, void *sym)
} }
segment = chunk_create(dli.dli_fbase, dli.dli_saddr - dli.dli_fbase); segment = chunk_create(dli.dli_fbase, dli.dli_saddr - dli.dli_fbase);
*len = segment.len;
return chunk_hash(segment); return chunk_hash(segment);
} }
@@ -183,6 +187,7 @@ static bool check_file(private_integrity_checker_t *this,
{ {
integrity_checksum_t *cs; integrity_checksum_t *cs;
u_int32_t sum; u_int32_t sum;
size_t len = 0;
cs = find_checksum(this, name); cs = find_checksum(this, name);
if (!cs) if (!cs)
@@ -190,8 +195,18 @@ static bool check_file(private_integrity_checker_t *this,
DBG1(" '%s' file checksum not found", name); DBG1(" '%s' file checksum not found", name);
return FALSE; return FALSE;
} }
sum = build_file(this, file); sum = build_file(this, file, &len);
if (!sum || cs->file != sum) 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", DBG1(" invalid '%s' file checksum: %08x, expected %08x",
name, sum, cs->file); name, sum, cs->file);
@@ -209,6 +224,7 @@ static bool check_segment(private_integrity_checker_t *this,
{ {
integrity_checksum_t *cs; integrity_checksum_t *cs;
u_int32_t sum; u_int32_t sum;
size_t len = 0;
cs = find_checksum(this, name); cs = find_checksum(this, name);
if (!cs) if (!cs)
@@ -216,8 +232,18 @@ static bool check_segment(private_integrity_checker_t *this,
DBG1(" '%s' segment checksum not found", name); DBG1(" '%s' segment checksum not found", name);
return FALSE; return FALSE;
} }
sum = build_segment(this, sym); sum = build_segment(this, sym, &len);
if (!sum || cs->segment != sum) 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", DBG1(" invalid '%s' segment checksum: %08x, expected %08x",
name, sum, cs->segment); 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); 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.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.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.check = (bool(*)(integrity_checker_t*, char *name, void *sym))check;
this->public.destroy = (void(*)(integrity_checker_t*))destroy; this->public.destroy = (void(*)(integrity_checker_t*))destroy;
+8 -3
View File
@@ -33,8 +33,12 @@ typedef struct integrity_checksum_t integrity_checksum_t;
struct integrity_checksum_t { struct integrity_checksum_t {
/* name of the checksum */ /* name of the checksum */
char *name; char *name;
/* size in bytes of the file on disk */
size_t file_len;
/* checksum of the file on disk */ /* checksum of the file on disk */
u_int32_t file; u_int32_t file;
/* size in bytes of executable segment in memory */
size_t segment_len;
/* checksum of the executable segment in memory */ /* checksum of the executable segment in memory */
u_int32_t segment; u_int32_t segment;
}; };
@@ -60,9 +64,10 @@ struct integrity_checker_t {
* Build the integrity checksum of a file on disk. * Build the integrity checksum of a file on disk.
* *
* @param file path to file * @param file path to file
* @param len return length in bytes of file
* @return checksum, 0 on error * @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. * Check the integrity of the code segment in memory.
@@ -72,14 +77,14 @@ struct integrity_checker_t {
* @return TRUE if integrity tested successfully * @return TRUE if integrity tested successfully
*/ */
bool (*check_segment)(integrity_checker_t *this, char *name, void *sym); bool (*check_segment)(integrity_checker_t *this, char *name, void *sym);
/** /**
* Build the integrity checksum of a code segment in memory. * Build the integrity checksum of a code segment in memory.
* *
* @param sym a symbol in the segment to check * @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 * @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. * Check both, on disk file integrity and loaded segment.