File Coverage

pl_sandbox.c
Criterion Covered Total %
statement 58 66 87.8
branch 26 32 81.2
condition n/a
subroutine n/a
pod n/a
total 84 98 85.7


line stmt bran cond sub pod time code
1             #include
2             #include
3             #include "pl_util.h"
4             #include "pl_sandbox.h"
5              
6             #define SANDBOX_DEBUG_MEMORY 0
7             #define SANDBOX_DEBUG_RUNTIME 0
8              
9             #if defined(SANDBOX_DEBUG_MEMORY) && SANDBOX_DEBUG_MEMORY > 0
10             #define SANDBOX_DUMP_MEMORY(duk) do { sandbox_dump_memstate(duk); } while (0)
11             #else
12             #define SANDBOX_DUMP_MEMORY(duk) do {} while (0)
13             #endif
14              
15             #if defined(SANDBOX_DEBUG_RUNTIME) && SANDBOX_DEBUG_RUNTIME > 0
16             #define SANDBOX_DUMP_RUNTIME(duk) do { sandbox_dump_timestate(duk); } while (0)
17             #else
18             #define SANDBOX_DUMP_RUNTIME(duk) do {} while (0)
19             #endif
20              
21             /*
22             * Memory allocator which backs to standard library memory functions but keeps
23             * a small header to track current allocation size.
24             */
25              
26             typedef struct {
27             /*
28             * The double value in the union is there to ensure alignment is good for
29             * IEEE doubles too. In many 32-bit environments 4 bytes would be
30             * sufficiently aligned and the double value is unnecessary.
31             */
32             union {
33             size_t sz;
34             double d;
35             } u;
36             } alloc_hdr;
37              
38 15           static void sandbox_error(size_t size, const char* func)
39             {
40             dTHX;
41 15           PerlIO_printf(PerlIO_stderr(), "duktape sandbox maximum allocation size reached, %ld requested in %s\n",
42             (long) size, func);
43 15           }
44              
45             #if defined(SANDBOX_DEBUG_MEMORY) && SANDBOX_DEBUG_MEMORY > 0
46             static void sandbox_dump_memstate(Duk* duk)
47             {
48             dTHX;
49             PerlIO_printf(PerlIO_stderr(), "duktape total allocated: %ld\n",
50             (long) duk->total_allocated_bytes);
51             }
52             #endif
53              
54             #if defined(SANDBOX_DEBUG_RUNTIME) && SANDBOX_DEBUG_RUNTIME > 0
55             static void sandbox_dump_timestate(Duk* duk)
56             {
57             dTHX;
58             PerlIO_printf(PerlIO_stderr(), "duktape timeout has happened, limit is %f us\n",
59             duk->max_timeout_us);
60             }
61             #endif
62              
63 54863194           void* pl_sandbox_alloc(void* udata, duk_size_t size)
64             {
65             alloc_hdr* hdr;
66              
67 54863194           Duk* duk = (Duk*) udata;
68              
69 54863194 50         if (size == 0) {
70 0           return NULL;
71             }
72              
73 54863194 100         if (duk->max_allocated_bytes > 0 &&
74 8729 100         duk->total_allocated_bytes + size > duk->max_allocated_bytes) {
75 15           sandbox_error(size, "pl_sandbox_alloc");
76 15           return NULL;
77             }
78              
79 54863179           hdr = (alloc_hdr*) malloc(size + sizeof(alloc_hdr));
80 54863179 50         if (!hdr) {
81 0           return NULL;
82             }
83 54863179           hdr->u.sz = size;
84 54863179           duk->total_allocated_bytes += size;
85             SANDBOX_DUMP_MEMORY(duk);
86 54863179           return (void*) (hdr + 1);
87             }
88              
89 12077181           void* pl_sandbox_realloc(void* udata, void* ptr, duk_size_t size)
90             {
91             alloc_hdr* hdr;
92             size_t old_size;
93             void* t;
94              
95 12077181           Duk* duk = (Duk*) udata;
96              
97 12077181 100         if (ptr) {
98 4012643           hdr = (alloc_hdr*) (((char*) ptr) - sizeof(alloc_hdr));
99 4012643           old_size = hdr->u.sz;
100              
101 4012643 100         if (size == 0) {
102 4           duk->total_allocated_bytes -= old_size;
103 4           free((void*) hdr);
104             SANDBOX_DUMP_MEMORY(duk);
105 4           return NULL;
106             } else {
107 4012639 100         if (duk->max_allocated_bytes > 0 &&
108 34 50         duk->total_allocated_bytes - old_size + size > duk->max_allocated_bytes) {
109 0           sandbox_error(size, "pl_sandbox_realloc");
110 0           return NULL;
111             }
112              
113 4012639           t = realloc((void*) hdr, size + sizeof(alloc_hdr));
114 4012639 50         if (!t) {
115 0           return NULL;
116             }
117 4012639           hdr = (alloc_hdr*) t;
118 4012639           duk->total_allocated_bytes -= old_size;
119 4012639           duk->total_allocated_bytes += size;
120 4012639           hdr->u.sz = size;
121             SANDBOX_DUMP_MEMORY(duk);
122 4012639           return (void*) (hdr + 1);
123             }
124 8064538 100         } else if (size == 0) {
125 6062166           return NULL;
126             } else {
127 2002372 100         if (duk->max_allocated_bytes > 0 &&
128 6 50         duk->total_allocated_bytes + size > duk->max_allocated_bytes) {
129 0           sandbox_error(size, "pl_sandbox_realloc");
130 0           return NULL;
131             }
132              
133 2002372           hdr = (alloc_hdr*) malloc(size + sizeof(alloc_hdr));
134 2002372 50         if (!hdr) {
135 0           return NULL;
136             }
137 2002372           hdr->u.sz = size;
138 2002372           duk->total_allocated_bytes += size;
139             SANDBOX_DUMP_MEMORY(duk);
140 2002372           return (void*) (hdr + 1);
141             }
142             }
143              
144 77089165           void pl_sandbox_free(void* udata, void* ptr)
145             {
146             alloc_hdr* hdr;
147              
148 77089165           Duk* duk = (Duk*) udata;
149              
150 77089165 100         if (!ptr) {
151 20223618           return;
152             }
153 56865547           hdr = (alloc_hdr*) (((char*) ptr) - sizeof(alloc_hdr));
154 56865547           duk->total_allocated_bytes -= hdr->u.sz;
155 56865547           free((void*) hdr);
156             SANDBOX_DUMP_MEMORY(duk);
157             }
158              
159 2002365           int pl_exec_timeout(void *udata)
160             {
161 2002365           Duk* duk = (Duk*) udata;
162 2002365           double elapsed_us = 0;
163 2002365 100         if (duk->max_timeout_us <= 0) {
164 2002360           return 0;
165             }
166              
167 5           elapsed_us = now_us() - duk->eval_start_us;
168 5 100         if (elapsed_us <= duk->max_timeout_us) {
169 4           return 0;
170             }
171              
172             SANDBOX_DUMP_RUNTIME(duk);
173 1           return 1;
174             }