Implement range of memory access validation instead of pointer and use

it. Export new validator to users.
Various small fixes
This commit is contained in:
2020-05-06 11:49:22 +04:00
parent f483155e07
commit 657ddf182b
8 changed files with 27 additions and 18 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ typedef struct {
unw_word_t lowpc; ///< offset to start of the function against base address 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 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 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_fun_flags flags; ///< flags of various function options
} pst_function_info; } pst_function_info;
+9 -2
View File
@@ -27,8 +27,8 @@ typedef struct pst_parameter pst_parameter;
/** /**
* @brief allocate libpst handler and initialize the library * @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 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 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' * @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 * @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); 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 * @brief Get next parameter's handle in function
* @param function Function's handler obtained by pst_get_next_function() * @param function Function's handler obtained by pst_get_next_function()
+6 -6
View File
@@ -7,6 +7,10 @@
#include <inttypes.h> #include <inttypes.h>
#include <stdbool.h> #include <stdbool.h>
#include <sys/mman.h>
#include <unistd.h>
#include <errno.h>
#include "context.h" #include "context.h"
int32_t decode_sleb128(uint8_t *sleb128) int32_t decode_sleb128(uint8_t *sleb128)
@@ -116,11 +120,7 @@ unsigned getSLEB128Size(int64_t Value)
return Size; return Size;
} }
#include <sys/mman.h> int pst_pointer_valid(void *p, uint32_t size)
#include <unistd.h>
#include <errno.h>
int pst_pointer_valid(void *p)
{ {
long page_size = sysconf(_SC_PAGESIZE); long page_size = sysconf(_SC_PAGESIZE);
if(page_size < 0) { 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 *)((((long)p) / page_size) * page_size);
//void *aligned = (void *)((uintptr_t)p & ~(page_size - 1)); //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; return 0;
} }
+1 -1
View File
@@ -21,6 +21,6 @@
int32_t decode_sleb128(uint8_t *sleb128); int32_t decode_sleb128(uint8_t *sleb128);
uint32_t decode_uleb128(uint8_t *uleb128); 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__ #endif // __PST_COMMON_H__
+1 -1
View File
@@ -147,7 +147,7 @@ void pst_call_site_init(pst_call_site* site, pst_context* c, uint64_t tgt, const
site->target = tgt; site->target = tgt;
if(orn) { if(orn) {
site->origin = strdup(orn); site->origin = pst_strdup(orn);
} else { } else {
site->origin = NULL; site->origin = NULL;
} }
+2 -1
View File
@@ -429,13 +429,14 @@ void pst_function_init(pst_function* fn, pst_context* _ctx, pst_function* _paren
fn->info.pc = 0; fn->info.pc = 0;
fn->info.lowpc = 0; fn->info.lowpc = 0;
fn->info.highpc = 0; fn->info.highpc = 0;
bzero(&fn->context, sizeof(fn->context));
fn->info.name = NULL; fn->info.name = NULL;
fn->info.line = -1; fn->info.line = -1;
fn->info.file = NULL; fn->info.file = NULL;
fn->info.sp = 0; fn->info.sp = 0;
fn->info.flags = 0;
// internal fields // internal fields
bzero(&fn->context, sizeof(fn->context));
fn->die = NULL; fn->die = NULL;
list_head_init(&fn->params); list_head_init(&fn->params);
pst_call_site_storage_init(&fn->call_sites, _ctx); pst_call_site_storage_init(&fn->call_sites, _ctx);
+6 -5
View File
@@ -332,6 +332,8 @@ bool parameter_handle_type(pst_parameter* param, Dwarf_Die* result)
case DW_ATE_decimal_float: case DW_ATE_decimal_float:
parameter_add_type(param, type_name, PARAM_TYPE_FLOAT); parameter_add_type(param, type_name, PARAM_TYPE_FLOAT);
break; 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: case DW_TAG_volatile_type:
parameter_add_type(param, NULL, PARAM_VOLATILE); parameter_add_type(param, NULL, PARAM_VOLATILE);
break; break;
case DW_TAG_string_type:
pst_log(SEVERITY_DEBUG, "String type, skipping");
break;
default: default:
pst_log(SEVERITY_WARNING, "Unknown 0x%X tag type", dwarf_tag(&ret_die)); pst_log(SEVERITY_WARNING, "Unknown 0x%X tag type", dwarf_tag(&ret_die));
break; 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)); pst_log(SEVERITY_WARNING, "Unknown form '0x%X' of attribute for Constant value", dwarf_whatform(attr));
param->info.flags &= ~PARAM_HAS_VALUE; 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 // 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; param->info.flags |= PARAM_INVALID;
} }
+1 -1
View File
@@ -58,7 +58,7 @@ typedef union {
void* ptr; void* ptr;
} pst_sized_value; } pst_sized_value;
typedef struct __pst_dwarf_value { typedef struct {
list_node node; // uplink list_node node; // uplink
// fields // fields