From 657ddf182bd42e8cf2e12ea410c09e35061dc200 Mon Sep 17 00:00:00 2001 From: Nikolai Nosov Date: Wed, 6 May 2020 11:49:22 +0400 Subject: [PATCH] Implement range of memory access validation instead of pointer and use it. Export new validator to users. Various small fixes --- include/libpst-types.h | 2 +- include/libpst.h | 11 +++++++++-- src/common.c | 12 ++++++------ src/common.h | 2 +- src/dwarf/dwarf_call_site.c | 2 +- src/dwarf/dwarf_function.c | 3 ++- src/dwarf/dwarf_parameter.c | 11 ++++++----- src/dwarf/dwarf_stack.h | 2 +- 8 files changed, 27 insertions(+), 18 deletions(-) diff --git a/include/libpst-types.h b/include/libpst-types.h index 4914847..2add1df 100644 --- a/include/libpst-types.h +++ b/include/libpst-types.h @@ -31,7 +31,7 @@ typedef struct { unw_word_t lowpc; ///< offset to start of the function against base address unw_word_t highpc; ///< offset to the next address after the end of the function against base address unw_word_t sp; ///< SP register in function's frame - unw_word_t cfa; ///< CFA (Canonical Frame Address) of the function. !!! Don't use CFA provided by libunwind, it's not valid !!! + unw_word_t cfa; ///< CFA (Canonical Frame Address) of the function pst_fun_flags flags; ///< flags of various function options } pst_function_info; diff --git a/include/libpst.h b/include/libpst.h index 0518502..1b5760d 100644 --- a/include/libpst.h +++ b/include/libpst.h @@ -27,8 +27,8 @@ typedef struct pst_parameter pst_parameter; /** * @brief allocate libpst handler and initialize the library * @param context context of process given to signal handler of a program. If NULL, then we are not in signal handler - * @param buff pointer to buffer by libpst custom allocator(i.e. no malloc() will beused). if NULL, then standard allocator will be used - * @param size of 'buff' + * @param buff pointer to buffer for libpst custom allocator(i.e. no malloc()/free() will be used). if NULL, then standard allocator will be used + * @param size of 'buff'. recommended size is not less than 4Kb * * @return pointer to handler to be used for all other operations. NULL in case of error */ @@ -83,6 +83,13 @@ const pst_function_info* pst_get_function_info(pst_function* function); */ int pst_get_register(pst_function* function, int regno, unw_word_t* val); +/** + * @brief Check memory range of process to validity (i.e. that process has access to this range) + * @param p pointer to start of range + * @param size size of range to check + */ +int pst_pointer_valid(void *p, uint32_t size); + /** * @brief Get next parameter's handle in function * @param function Function's handler obtained by pst_get_next_function() diff --git a/src/common.c b/src/common.c index 4856ed3..cffa8ab 100644 --- a/src/common.c +++ b/src/common.c @@ -7,6 +7,10 @@ #include #include +#include +#include +#include + #include "context.h" int32_t decode_sleb128(uint8_t *sleb128) @@ -116,11 +120,7 @@ unsigned getSLEB128Size(int64_t Value) return Size; } -#include -#include -#include - -int pst_pointer_valid(void *p) +int pst_pointer_valid(void *p, uint32_t size) { long page_size = sysconf(_SC_PAGESIZE); if(page_size < 0) { @@ -130,7 +130,7 @@ int pst_pointer_valid(void *p) void *aligned = (void *)((((long)p) / page_size) * page_size); //void *aligned = (void *)((uintptr_t)p & ~(page_size - 1)); - if(msync(aligned, page_size, MS_ASYNC) == 0) { + if(msync(aligned, size, MS_ASYNC) == 0) { return 0; } diff --git a/src/common.h b/src/common.h index 8a8487a..70d3fea 100644 --- a/src/common.h +++ b/src/common.h @@ -21,6 +21,6 @@ int32_t decode_sleb128(uint8_t *sleb128); uint32_t decode_uleb128(uint8_t *uleb128); -int pst_pointer_valid(void *p); +int pst_pointer_valid(void *p, uint32_t size); #endif // __PST_COMMON_H__ diff --git a/src/dwarf/dwarf_call_site.c b/src/dwarf/dwarf_call_site.c index 918e71a..353d7e8 100644 --- a/src/dwarf/dwarf_call_site.c +++ b/src/dwarf/dwarf_call_site.c @@ -147,7 +147,7 @@ void pst_call_site_init(pst_call_site* site, pst_context* c, uint64_t tgt, const site->target = tgt; if(orn) { - site->origin = strdup(orn); + site->origin = pst_strdup(orn); } else { site->origin = NULL; } diff --git a/src/dwarf/dwarf_function.c b/src/dwarf/dwarf_function.c index 0412404..1e79201 100644 --- a/src/dwarf/dwarf_function.c +++ b/src/dwarf/dwarf_function.c @@ -429,13 +429,14 @@ void pst_function_init(pst_function* fn, pst_context* _ctx, pst_function* _paren fn->info.pc = 0; fn->info.lowpc = 0; fn->info.highpc = 0; - bzero(&fn->context, sizeof(fn->context)); fn->info.name = NULL; fn->info.line = -1; fn->info.file = NULL; fn->info.sp = 0; + fn->info.flags = 0; // internal fields + bzero(&fn->context, sizeof(fn->context)); fn->die = NULL; list_head_init(&fn->params); pst_call_site_storage_init(&fn->call_sites, _ctx); diff --git a/src/dwarf/dwarf_parameter.c b/src/dwarf/dwarf_parameter.c index 6779a96..e7639f8 100644 --- a/src/dwarf/dwarf_parameter.c +++ b/src/dwarf/dwarf_parameter.c @@ -332,6 +332,8 @@ bool parameter_handle_type(pst_parameter* param, Dwarf_Die* result) case DW_ATE_decimal_float: parameter_add_type(param, type_name, PARAM_TYPE_FLOAT); break; + default: + pst_log(SEVERITY_WARNING, "Unknown parameter base type encodings 0x%lX", enc_type); } } @@ -379,6 +381,9 @@ bool parameter_handle_type(pst_parameter* param, Dwarf_Die* result) case DW_TAG_volatile_type: parameter_add_type(param, NULL, PARAM_VOLATILE); break; + case DW_TAG_string_type: + pst_log(SEVERITY_DEBUG, "String type, skipping"); + break; default: pst_log(SEVERITY_WARNING, "Unknown 0x%X tag type", dwarf_tag(&ret_die)); break; @@ -445,14 +450,10 @@ bool parameter_handle_dwarf(pst_parameter* param, Dwarf_Die* result, pst_functio pst_log(SEVERITY_WARNING, "Unknown form '0x%X' of attribute for Constant value", dwarf_whatform(attr)); param->info.flags &= ~PARAM_HAS_VALUE; } - - if(param->info.flags & PARAM_HAS_VALUE) { - pst_log(SEVERITY_DEBUG, "Parameter constant value: 0x%lX", param->info.value); - } } // check pointer validity - if((param->info.flags & (PARAM_TYPE_POINTER | PARAM_TYPE_FUNCPTR)) && pst_pointer_valid((void*)param->info.value)) { + if((param->info.flags & (PARAM_TYPE_POINTER | PARAM_TYPE_FUNCPTR)) && pst_pointer_valid((void*)param->info.value, sizeof((void*)param->info.size))) { param->info.flags |= PARAM_INVALID; } diff --git a/src/dwarf/dwarf_stack.h b/src/dwarf/dwarf_stack.h index e0c996c..ab019e1 100644 --- a/src/dwarf/dwarf_stack.h +++ b/src/dwarf/dwarf_stack.h @@ -58,7 +58,7 @@ typedef union { void* ptr; } pst_sized_value; -typedef struct __pst_dwarf_value { +typedef struct { list_node node; // uplink // fields