diff options
author | Nick Mathewson <nickm@torproject.org> | 2014-04-16 12:45:34 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2014-04-16 22:03:09 -0400 |
commit | 5aaac938a94fc0b5d7dc63cac92e78d3125f08c8 (patch) | |
tree | b0559e8143f78c6ac91525e7f360224daad0144d /src/common/sandbox.c | |
parent | f268101a612bd637e270914365271d08fc5813db (diff) | |
download | tor-5aaac938a94fc0b5d7dc63cac92e78d3125f08c8.tar.gz tor-5aaac938a94fc0b5d7dc63cac92e78d3125f08c8.zip |
Have sandbox string protection include multi-valued parmeters.
Diffstat (limited to 'src/common/sandbox.c')
-rw-r--r-- | src/common/sandbox.c | 103 |
1 files changed, 64 insertions, 39 deletions
diff --git a/src/common/sandbox.c b/src/common/sandbox.c index 85a2f23c92..8cbcd04fa6 100644 --- a/src/common/sandbox.c +++ b/src/common/sandbox.c @@ -862,7 +862,7 @@ static sandbox_filter_func_t filter_func[] = { sb_socketpair }; -const char* +const char * sandbox_intern_string(const char *str) { sandbox_cfg_t *elem; @@ -873,8 +873,13 @@ sandbox_intern_string(const char *str) for (elem = filter_dynamic; elem != NULL; elem = elem->next) { smp_param_t *param = elem->param; - if (param->prot && !strcmp(str, (char*)(param->value))) { - return (char*)(param->value); + if (param->prot) { + if (!strcmp(str, (char*)(param->value))) { + return (char*)param->value; + } + if (param->value2 && !strcmp(str, (char*)param->value2)) { + return (char*)param->value2; + } } } @@ -882,6 +887,50 @@ sandbox_intern_string(const char *str) return str; } +/** DOCDOC */ +static int +prot_strings_helper(strmap_t *locations, + char **pr_mem_next_p, + size_t *pr_mem_left_p, + intptr_t *value_p) +{ + char *param_val; + size_t param_size; + void *location; + + if (*value_p == 0) + return 0; + + param_val = (char*) *value_p; + param_size = strlen(param_val) + 1; + location = strmap_get(locations, param_val); + + if (location) { + // We already interned this string. + tor_free(param_val); + *value_p = (intptr_t) location; + return 0; + } else if (*pr_mem_left_p >= param_size) { + // copy to protected + location = *pr_mem_next_p; + memcpy(location, param_val, param_size); + + // re-point el parameter to protected + tor_free(param_val); + *value_p = (intptr_t) location; + + strmap_set(locations, location, location); /* good real estate advice */ + + // move next available protected memory + *pr_mem_next_p += param_size; + *pr_mem_left_p -= param_size; + return 0; + } else { + log_err(LD_BUG,"(Sandbox) insufficient protected memory!"); + return -1; + } +} + /** * Protects all the strings in the sandbox's parameter list configuration. It * works by calculating the total amount of memory required by the parameter @@ -900,7 +949,8 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg) // get total number of bytes required to mmap. (Overestimate.) for (el = cfg; el != NULL; el = el->next) { pr_mem_size += strlen((char*) el->param->value) + 1; - + if (el->param->value2) + pr_mem_size += strlen((char*) el->param->value2) + 1; } // allocate protected memory with MALLOC_MP_LIM canary @@ -920,42 +970,17 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg) // change el value pointer to protected for (el = cfg; el != NULL; el = el->next) { - char *param_val = (char*)(el->param)->value; - size_t param_size = strlen(param_val) + 1; - - void *location = strmap_get(locations, param_val); - - if (location) { - // We already interned this string. - { - void *old_val = (void *) el->param->value; - tor_free(old_val); - } - el->param->value = (intptr_t) location; - el->param->prot = 1; - - } else if (pr_mem_left >= param_size) { - // copy to protected - memcpy(pr_mem_next, param_val, param_size); - - // re-point el parameter to protected - { - void *old_val = (void *) el->param->value; - tor_free(old_val); - } - el->param->value = (intptr_t) pr_mem_next; - el->param->prot = 1; - - strmap_set(locations, pr_mem_next, pr_mem_next); - - // move next available protected memory - pr_mem_next += param_size; - pr_mem_left -= param_size; - } else { - log_err(LD_BUG,"(Sandbox) insufficient protected memory!"); + if (prot_strings_helper(locations, &pr_mem_next, &pr_mem_left, + &el->param->value) < 0) { + ret = -2; + goto out; + } + if (prot_strings_helper(locations, &pr_mem_next, &pr_mem_left, + &el->param->value2) < 0) { ret = -2; goto out; } + el->param->prot = 1; } // protecting from writes @@ -995,7 +1020,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg) * There is a restriction on how much you can mprotect with R|W up to the * size of the canary. */ - ret = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 2, + ret = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 3, SCMP_CMP(0, SCMP_CMP_LT, (intptr_t) pr_mem_base), SCMP_CMP(1, SCMP_CMP_LE, MALLOC_MP_LIM), SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE)); @@ -1004,7 +1029,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg) return ret; } - ret = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 2, + ret = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 3, SCMP_CMP(0, SCMP_CMP_GT, (intptr_t) pr_mem_base + pr_mem_size + MALLOC_MP_LIM), SCMP_CMP(1, SCMP_CMP_LE, MALLOC_MP_LIM), |