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 54631497           void* pl_sandbox_alloc(void* udata, duk_size_t size)
65             {
66             alloc_hdr* hdr;
67              
68 54631497           Duk* duk = (Duk*) udata;
69              
70 54631497 50         if (size == 0) {
71 0           return NULL;
72             }
73              
74 54631497 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 54631482           hdr = (alloc_hdr*) malloc(size + sizeof(alloc_hdr));
81 54631482 50         if (!hdr) {
82 0           return NULL;
83             }
84 54631482           hdr->u.sz = size;
85 54631482           duk->total_allocated_bytes += size;
86             SANDBOX_DUMP_MEMORY(duk);
87 54631482           return (void*) (hdr + 1);
88             }
89              
90 12057167           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 12057167           Duk* duk = (Duk*) udata;
97              
98 12057167 100         if (ptr) {
99 4009622           hdr = (alloc_hdr*) (((char*) ptr) - sizeof(alloc_hdr));
100 4009622           old_size = hdr->u.sz;
101              
102 4009622 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 4009618 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 4009618           t = realloc((void*) hdr, size + sizeof(alloc_hdr));
115 4009618 50         if (!t) {
116 0           return NULL;
117             }
118 4009618           hdr = (alloc_hdr*) t;
119 4009618           duk->total_allocated_bytes -= old_size;
120 4009618           duk->total_allocated_bytes += size;
121 4009618           hdr->u.sz = size;
122             SANDBOX_DUMP_MEMORY(duk);
123 4009618           return (void*) (hdr + 1);
124             }
125 8047545 100         } else if (size == 0) {
126 6045592           return NULL;
127             } else {
128 2001953 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 2001953           hdr = (alloc_hdr*) malloc(size + sizeof(alloc_hdr));
135 2001953 50         if (!hdr) {
136 0           return NULL;
137             }
138 2001953           hdr->u.sz = size;
139 2001953           duk->total_allocated_bytes += size;
140             SANDBOX_DUMP_MEMORY(duk);
141 2001953           return (void*) (hdr + 1);
142             }
143             }
144              
145 76793689           void pl_sandbox_free(void* udata, void* ptr)
146             {
147             alloc_hdr* hdr;
148              
149 76793689           Duk* duk = (Duk*) udata;
150              
151 76793689 100         if (!ptr) {
152 20160258           return;
153             }
154 56633431           hdr = (alloc_hdr*) (((char*) ptr) - sizeof(alloc_hdr));
155 56633431           duk->total_allocated_bytes -= hdr->u.sz;
156 56633431           free((void*) hdr);
157             SANDBOX_DUMP_MEMORY(duk);
158             }
159              
160 2001947           int pl_exec_timeout(void *udata)
161             {
162 2001947           Duk* duk = (Duk*) udata;
163 2001947           double elapsed_us = 0;
164 2001947 100         if (duk->max_timeout_us <= 0) {
165 2001942           return 0;
166             }
167              
168 5           elapsed_us = now_us() - duk->eval_start_us;
169 5 100         if (elapsed_us <= duk->max_timeout_us) {
170 4           return 0;
171             }
172              
173             SANDBOX_DUMP_RUNTIME(duk);
174 1           return 1;
175             }