aboutsummaryrefslogtreecommitdiff
path: root/src/common/sandbox.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2014-03-28 02:10:19 -0400
committerNick Mathewson <nickm@torproject.org>2014-04-16 22:03:08 -0400
commit3802e32c7d94c599546069d8246636b0d3a4ad10 (patch)
tree9a7c2333c19fe67d6ec1c18dba452400dafdb41a /src/common/sandbox.c
parentae9d6d73f50f6205f0651a627d3bf7b0d99273f1 (diff)
downloadtor-3802e32c7d94c599546069d8246636b0d3a4ad10.tar
tor-3802e32c7d94c599546069d8246636b0d3a4ad10.tar.gz
Only intern one copy of each magic string for the sandbox
If we intern two copies of a string, later calls to sandbox_intern_string will give the wrong one sometimes.
Diffstat (limited to 'src/common/sandbox.c')
-rw-r--r--src/common/sandbox.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/src/common/sandbox.c b/src/common/sandbox.c
index 299c6f20b..363333a03 100644
--- a/src/common/sandbox.c
+++ b/src/common/sandbox.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include "sandbox.h"
+#include "container.h"
#include "torlog.h"
#include "torint.h"
#include "util.h"
@@ -859,8 +860,9 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
size_t pr_mem_size = 0, pr_mem_left = 0;
char *pr_mem_next = NULL, *pr_mem_base;
sandbox_cfg_t *el = NULL;
+ strmap_t *locations = NULL;
- // get total number of bytes required to mmap
+ // get total number of bytes required to mmap. (Overestimate.)
for (el = cfg; el != NULL; el = el->next) {
pr_mem_size += strlen((char*) ((smp_param_t*)el->param)->value) + 1;
}
@@ -878,12 +880,24 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
pr_mem_next = pr_mem_base + MALLOC_MP_LIM;
pr_mem_left = pr_mem_size;
+ locations = strmap_new();
+
// change el value pointer to protected
for (el = cfg; el != NULL; el = el->next) {
char *param_val = (char*)((smp_param_t *)el->param)->value;
size_t param_size = strlen(param_val) + 1;
- if (pr_mem_left >= param_size) {
+ void *location = strmap_get(locations, param_val);
+ if (location) {
+ // We already interned this string.
+ {
+ void *old_val = (void *) ((smp_param_t*)el->param)->value;
+ tor_free(old_val);
+ }
+ ((smp_param_t*)el->param)->value = (intptr_t) location;
+ ((smp_param_t*)el->param)->prot = 1;
+
+ } else if (pr_mem_left >= param_size) {
// copy to protected
memcpy(pr_mem_next, param_val, param_size);
@@ -895,6 +909,8 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
((smp_param_t*)el->param)->value = (intptr_t) pr_mem_next;
((smp_param_t*)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;
@@ -962,7 +978,8 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
}
out:
- return ret;
+ strmap_free(locations, NULL);
+ return ret;
}
/**