Merge pull request #314 from haberman/addunknown

Fixed bug in addunknown and added ASAN poisoning.
pull/13171/head
Joshua Haberman 4 years ago committed by GitHub
commit 10fa3a0c77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      tests/bindings/lua/test_upb.lua
  2. 3
      upb/msg.c
  3. 22
      upb/port_def.inc
  4. 3
      upb/port_undef.inc
  5. 14
      upb/upb.c
  6. 20
      upb/upb.h

@ -481,6 +481,13 @@ function test_numeric_map()
end
end
function test_unknown()
local bytes = string.rep("\x38\x00", 10000)
for i=1,1000 do
local msg = upb.decode(test_messages_proto3.TestAllTypesProto3, bytes)
end
end
function test_foo()
local symtab = upb.SymbolTable()
local filename = "external/com_google_protobuf/descriptor_proto-descriptor-set.proto.bin"

@ -36,11 +36,12 @@ bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
in->unknown->len = 0;
} else if (in->unknown->size - in->unknown->len < len) {
size_t need = in->unknown->len + len;
size_t size = in->unknown->size;;
size_t size = in->unknown->size;
while (size < need) size *= 2;
in->unknown = upb_arena_realloc(
arena, in->unknown, in->unknown->size + overhead, size + overhead);
if (!in->unknown) return false;
in->unknown->size = size;
}
memcpy(UPB_PTR_AT(in->unknown + 1, in->unknown->len, char), data, len);
in->unknown->len += len;

@ -181,3 +181,25 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg);
#else
#define UPB_NAN (0.0 / 0.0)
#endif
#if defined(__SANITIZE_ADDRESS__)
#define UPB_ASAN 1
#ifdef __cplusplus
extern "C" {
#endif
void __asan_poison_memory_region(void const volatile *addr, size_t size);
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
#ifdef __cplusplus
} /* extern "C" */
#endif
#define UPB_POISON_MEMORY_REGION(addr, size) \
__asan_poison_memory_region((addr), (size))
#define UPB_UNPOISON_MEMORY_REGION(addr, size) \
__asan_unpoison_memory_region((addr), (size))
#else
#define UPB_ASAN 0
#define UPB_POISON_MEMORY_REGION(addr, size) \
((void)(addr), (void)(size))
#define UPB_UNPOISON_MEMORY_REGION(addr, size) \
((void)(addr), (void)(size))
#endif

@ -26,3 +26,6 @@
#undef _upb_snprintf
#undef _upb_vsnprintf
#undef _upb_va_copy
#undef UPB_POISON_MEMORY_REGION
#undef UPB_UNPOISON_MEMORY_REGION
#undef UPB_ASAN

@ -114,7 +114,7 @@ static void upb_arena_addblock(upb_arena *a, upb_arena *root, void *ptr,
a->head.end = UPB_PTR_AT(block, size, char);
a->cleanups = &block->cleanups;
/* TODO(haberman): ASAN poison. */
UPB_POISON_MEMORY_REGION(a->head.ptr, a->head.end - a->head.ptr);
}
static bool upb_arena_allocblock(upb_arena *a, size_t size) {
@ -127,14 +127,9 @@ static bool upb_arena_allocblock(upb_arena *a, size_t size) {
return true;
}
static bool arena_has(upb_arena *a, size_t size) {
_upb_arena_head *h = (_upb_arena_head*)a;
return (size_t)(h->end - h->ptr) >= size;
}
void *_upb_arena_slowmalloc(upb_arena *a, size_t size) {
if (!upb_arena_allocblock(a, size)) return NULL; /* Out of memory. */
UPB_ASSERT(arena_has(a, size));
UPB_ASSERT(_upb_arenahas(a, size));
return upb_arena_malloc(a, size);
}
@ -229,14 +224,15 @@ void upb_arena_free(upb_arena *a) {
bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) {
cleanup_ent *ent;
if (!a->cleanups || !arena_has(a, sizeof(cleanup_ent))) {
if (!a->cleanups || !_upb_arenahas(a, sizeof(cleanup_ent))) {
if (!upb_arena_allocblock(a, 128)) return false; /* Out of memory. */
UPB_ASSERT(arena_has(a, sizeof(cleanup_ent)));
UPB_ASSERT(_upb_arenahas(a, sizeof(cleanup_ent)));
}
a->head.end -= sizeof(cleanup_ent);
ent = (cleanup_ent*)a->head.end;
(*a->cleanups)++;
UPB_UNPOISON_MEMORY_REGION(ent, sizeof(cleanup_ent));
ent->cleanup = func;
ent->ud = ud;

@ -161,17 +161,35 @@ void *_upb_arena_slowmalloc(upb_arena *a, size_t size);
UPB_INLINE upb_alloc *upb_arena_alloc(upb_arena *a) { return (upb_alloc*)a; }
UPB_INLINE bool _upb_arenahas(upb_arena *a, size_t size) {
_upb_arena_head *h = (_upb_arena_head*)a;
return (size_t)(h->end - h->ptr) >= size;
}
UPB_INLINE void *upb_arena_malloc(upb_arena *a, size_t size) {
_upb_arena_head *h = (_upb_arena_head*)a;
void* ret;
size = UPB_ALIGN_MALLOC(size);
if (UPB_UNLIKELY((size_t)(h->end - h->ptr) < size)) {
if (UPB_UNLIKELY(!_upb_arenahas(a, size))) {
return _upb_arena_slowmalloc(a, size);
}
ret = h->ptr;
h->ptr += size;
UPB_UNPOISON_MEMORY_REGION(ret, size);
#if UPB_ASAN
{
size_t guard_size = 32;
if (_upb_arenahas(a, guard_size)) {
h->ptr += guard_size;
} else {
h->ptr = h->end;
}
}
#endif
return ret;
}

Loading…
Cancel
Save