php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
sljitProtExecAllocatorPosix.c
Go to the documentation of this file.
1/*
2 * Stack-less Just-In-Time compiler
3 *
4 * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without modification, are
7 * permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice, this list of
10 * conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
13 * of conditions and the following disclaimer in the documentation and/or other materials
14 * provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19 * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#define SLJIT_HAS_CHUNK_HEADER
28#define SLJIT_HAS_EXECUTABLE_OFFSET
29
30struct sljit_chunk_header {
31 void *executable;
32};
33
34#include <sys/stat.h>
35#include <fcntl.h>
36#include <stdio.h>
37#include <string.h>
38
39#ifndef O_NOATIME
40#define O_NOATIME 0
41#endif
42
43/* this is a linux extension available since kernel 3.11 */
44#ifndef O_TMPFILE
45#define O_TMPFILE 0x404000
46#endif
47
48#ifndef _GNU_SOURCE
49char *secure_getenv(const char *name);
50int mkostemp(char *template, int flags);
51#endif
52
53static SLJIT_INLINE int create_tempfile(void)
54{
55 int fd;
56 char tmp_name[256];
57 size_t tmp_name_len = 0;
58 char *dir;
59 struct stat st;
60#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
62#endif
63
64#ifdef HAVE_MEMFD_CREATE
65 /* this is a GNU extension, make sure to use -D_GNU_SOURCE */
66 fd = memfd_create("sljit", MFD_CLOEXEC);
67 if (fd != -1) {
68 fchmod(fd, 0);
69 return fd;
70 }
71#endif
72
73 dir = secure_getenv("TMPDIR");
74
75 if (dir) {
76 size_t len = strlen(dir);
77 if (len > 0 && len < sizeof(tmp_name)) {
78 if ((stat(dir, &st) == 0) && S_ISDIR(st.st_mode)) {
79 memcpy(tmp_name, dir, len + 1);
80 tmp_name_len = len;
81 }
82 }
83 }
84
85#ifdef P_tmpdir
86 if (!tmp_name_len) {
87 tmp_name_len = strlen(P_tmpdir);
88 if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name))
89 strcpy(tmp_name, P_tmpdir);
90 }
91#endif
92 if (!tmp_name_len) {
93 strcpy(tmp_name, "/tmp");
94 tmp_name_len = 4;
95 }
96
97 SLJIT_ASSERT(tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name));
98
99 if (tmp_name_len > 1 && tmp_name[tmp_name_len - 1] == '/')
100 tmp_name[--tmp_name_len] = '\0';
101
102 fd = open(tmp_name, O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, 0);
103 if (fd != -1)
104 return fd;
105
106 if (tmp_name_len >= sizeof(tmp_name) - 7)
107 return -1;
108
109 strcpy(tmp_name + tmp_name_len, "/XXXXXX");
110#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
111 mode = umask(0777);
112#endif
114#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
115 umask(mode);
116#else
117 fchmod(fd, 0);
118#endif
119
120 if (fd == -1)
121 return -1;
122
123 if (unlink(tmp_name)) {
124 close(fd);
125 return -1;
126 }
127
128 return fd;
129}
130
131static SLJIT_INLINE struct sljit_chunk_header* alloc_chunk(sljit_uw size)
132{
134 int fd;
135
136 fd = create_tempfile();
137 if (fd == -1)
138 return NULL;
139
140 if (ftruncate(fd, (off_t)size)) {
141 close(fd);
142 return NULL;
143 }
144
145 retval = (struct sljit_chunk_header *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
146
147 if (retval == MAP_FAILED) {
148 close(fd);
149 return NULL;
150 }
151
152 retval->executable = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0);
153
154 if (retval->executable == MAP_FAILED) {
155 munmap((void *)retval, size);
156 close(fd);
157 return NULL;
158 }
159
160 close(fd);
161 return retval;
162}
163
164static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
165{
166 struct sljit_chunk_header *header = ((struct sljit_chunk_header *)chunk) - 1;
167
168 munmap(header->executable, size);
169 munmap((void *)header, size);
170}
171
size_t len
Definition apprentice.c:174
umask(?int $mask=null)
unlink(string $filename, $context=null)
ftruncate($stream, int $size)
dir(string $directory, $context=null)
header(string $header, bool $replace=true, int $response_code=0)
stat(string $filename)
new_type size
Definition ffi.c:4365
memcpy(ptr1, ptr2, size)
#define O_CLOEXEC
Definition file.h:144
char * mode
#define NULL
Definition gdcache.h:45
unsigned short mode_t
Definition ioutil.h:72
#define P_tmpdir
int fd
Definition phpdbg.h:282
#define PROT_READ
Definition phpdbg_win.h:26
#define PROT_WRITE
Definition phpdbg_win.h:27
unsigned int sljit_uw
#define SLJIT_ASSERT(x)
#define SLJIT_INLINE
char * secure_getenv(const char *name)
#define O_TMPFILE
#define O_NOATIME
int mkostemp(char *template, int flags)
#define close(a)
#define MAP_FAILED
Definition zend_alloc.c:98
strlen(string $string)
#define S_ISDIR(mode)
zval retval
zend_string * tmp_name
zend_string * name