aboutsummaryrefslogtreecommitdiff
path: root/src/common/sandbox.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2014-04-16 12:45:34 -0400
committerNick Mathewson <nickm@torproject.org>2014-04-16 22:03:09 -0400
commit5aaac938a94fc0b5d7dc63cac92e78d3125f08c8 (patch)
treeb0559e8143f78c6ac91525e7f360224daad0144d /src/common/sandbox.c
parentf268101a612bd637e270914365271d08fc5813db (diff)
downloadtor-5aaac938a94fc0b5d7dc63cac92e78d3125f08c8.tar
tor-5aaac938a94fc0b5d7dc63cac92e78d3125f08c8.tar.gz
Have sandbox string protection include multi-valued parmeters.
Diffstat (limited to 'src/common/sandbox.c')
-rw-r--r--src/common/sandbox.c103
1 files changed, 64 insertions, 39 deletions
diff --git a/src/common/sandbox.c b/src/common/sandbox.c
index 85a2f23c9..8cbcd04fa 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),