From d067712ff9caaef6685ea147ba10a0a40f50222c Mon Sep 17 00:00:00 2001 From: Gaurav Shah Date: Thu, 4 Feb 2010 19:35:03 -0800 Subject: [PATCH] Add a StatefulMemcpy which can be used to safely and iteratively copy blocks of memory. Review URL: http://codereview.chromium.org/572024 --- common/utility_stub.c | 21 ++++++++++++++++++++- include/utility.h | 21 +++++++++++++++++++++ utils/Makefile | 1 - 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/common/utility_stub.c b/common/utility_stub.c index 14a5910fba..ca12fa610c 100644 --- a/common/utility_stub.c +++ b/common/utility_stub.c @@ -10,7 +10,6 @@ #include #include -#include void* Malloc(size_t size) { void* p = malloc(size); @@ -29,6 +28,13 @@ void* Memcpy(void* dest, const void* src, size_t n) { return memcpy(dest, src, n); } +void* Memset(void* dest, const uint8_t c, size_t n) { + while (n--) { + *((uint8_t*)dest) = c; + } + return dest; +} + int SafeMemcmp(const void* s1, const void* s2, size_t n) { int match = 1; const unsigned char* us1 = s1; @@ -42,3 +48,16 @@ int SafeMemcmp(const void* s1, const void* s2, size_t n) { return match; } + +void* StatefulMemcpy(MemcpyState* state, void* dst, int len) { + void* saved_ptr; + if (len > state->remaining_len) { + state->remaining_len = -1; + return NULL; + } + saved_ptr = state->remaining_buf; + Memcpy(dst, saved_ptr, len); + state->remaining_buf += len; + state->remaining_len -= len; + return dst; +} diff --git a/include/utility.h b/include/utility.h index ddb1dc055f..87d17eaa42 100644 --- a/include/utility.h +++ b/include/utility.h @@ -10,6 +10,7 @@ #ifndef VBOOT_REFERENCE_UTILITY_H_ #define VBOOT_REFERENCE_UTILITY_H_ +#include #include /* Allocate [size] bytes and return a pointer to the allocated memory. Abort @@ -23,10 +24,30 @@ void Free(void* ptr); /* Copy [n] bytes from [src] to [dest]. */ void* Memcpy(void* dest, const void* src, size_t n); +/* Set [n] bytes starting at [s] to [c]. */ +void* Memset(void *dest, const uint8_t c, size_t n); + /* Compare [n] bytes starting at [s1] with [s2] and return 1 if they match, * 0 if they don't. Time taken to perform the comparison is only dependent on * [n] and not on the relationship of the match between [s1] and [s2]. */ int SafeMemcmp(const void* s1, const void* s2, size_t n); +/* Track remaining data to be read in a buffer. */ +typedef struct MemcpyState { + void* remaining_buf; + int remaining_len; +} MemcpyState; + +/* Copy [len] bytes into [dst] only if there's enough data to read according + * to [state]. + * On success, return [dst] and update [state].. + * On failure, return NULL, set remaining len in state to -1. + * + * Useful for iterating through a binary blob to populate a struct. After the + * first failure (buffer overrun), successive calls will always fail. + */ +void* StatefulMemcpy(MemcpyState* state, void* dst, int len); + + #endif /* VBOOT_REFERENCE_UTILITY_H_ */ diff --git a/utils/Makefile b/utils/Makefile index e7ebc7e6f0..85735832ce 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -8,6 +8,5 @@ all: dumpRSAPublicKey dumpRSAPublicKey: dumpRSAPublicKey.c $(CC) $(CFLAGS) $(LIBS) $< -o $@ - clean: rm -f dumpRSAPublicKey