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