This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | namespace PHPDaemon\Thread; |
||
3 | |||
4 | use PHPDaemon\Core\AppInstance; |
||
5 | use PHPDaemon\Core\Daemon; |
||
6 | use PHPDaemon\Core\EventLoop; |
||
7 | use PHPDaemon\FS\FileSystem; |
||
8 | use PHPDaemon\FS\FileWatcher; |
||
9 | |||
10 | /** |
||
11 | * Implementation of the IPC thread |
||
12 | * |
||
13 | * @package Core |
||
14 | * |
||
15 | * @author Vasily Zorin <[email protected]> |
||
16 | */ |
||
17 | // @TODO: respawning IPCThread on unexpected failures |
||
18 | class IPC extends Generic |
||
19 | { |
||
20 | /** |
||
21 | * Event base |
||
22 | * @var EventLoop |
||
23 | */ |
||
24 | public $loop; |
||
25 | |||
26 | /** |
||
27 | * Break main loop? |
||
28 | * @var boolean |
||
29 | */ |
||
30 | protected $breakMainLoop = false; |
||
31 | |||
32 | /** |
||
33 | * Reload ready? |
||
34 | * @var boolean |
||
35 | */ |
||
36 | protected $reloadReady = false; |
||
37 | |||
38 | /** |
||
39 | * Update? |
||
40 | * @var boolean |
||
41 | */ |
||
42 | public $update = false; |
||
43 | |||
44 | |||
45 | /** |
||
46 | * If true, we do not register signals automatically at start |
||
47 | * @var boolean |
||
48 | */ |
||
49 | protected $delayedSigReg = true; |
||
50 | |||
51 | /** |
||
52 | * Instances count |
||
53 | * @var array |
||
54 | */ |
||
55 | public $instancesCount = []; |
||
56 | |||
57 | /** |
||
58 | * File watcher |
||
59 | * @var FileWatcher |
||
60 | */ |
||
61 | public $fileWatcher; |
||
62 | |||
63 | /** |
||
64 | * If true, we do not register signals automatically at start |
||
65 | * @var boolean |
||
66 | */ |
||
67 | public $reload = false; |
||
68 | |||
69 | /** @var */ |
||
70 | public $IPCManager; |
||
71 | |||
72 | /** |
||
73 | * Runtime of Worker process. |
||
74 | * @return void |
||
75 | */ |
||
76 | protected function run() |
||
77 | { |
||
78 | if (Daemon::$process instanceof Master) { |
||
79 | Daemon::$process->unregisterSignals(); |
||
0 ignored issues
–
show
|
|||
80 | } |
||
81 | EventLoop::init(); |
||
82 | Daemon::$process = $this; |
||
83 | if (Daemon::$logpointerAsync) { |
||
84 | Daemon::$logpointerAsync->fd = null; |
||
85 | Daemon::$logpointerAsync = null; |
||
86 | } |
||
87 | class_exists('Timer'); |
||
88 | |||
89 | if (Daemon::$config->autogc->value > 0) { |
||
90 | gc_enable(); |
||
91 | } else { |
||
92 | gc_disable(); |
||
93 | } |
||
94 | $this->prepareSystemEnv(); |
||
95 | $this->registerEventSignals(); |
||
96 | FileSystem::init(); // re-init |
||
97 | FileSystem::initEvent(); |
||
98 | Daemon::openLogs(); |
||
99 | |||
100 | $this->fileWatcher = new FileWatcher(); |
||
101 | $this->IPCManager = Daemon::$appResolver->getInstanceByAppName('\PHPDaemon\IPCManager\IPCManager'); |
||
102 | if (!$this->IPCManager) { |
||
103 | $this->log('cannot instantiate IPCManager'); |
||
104 | } |
||
105 | |||
106 | EventLoop::$instance->run(); |
||
107 | } |
||
108 | |||
109 | /** |
||
110 | * Setup settings on start. |
||
111 | * @return void |
||
112 | */ |
||
113 | protected function prepareSystemEnv() |
||
114 | { |
||
115 | proc_nice(Daemon::$config->ipcthreadpriority->value); |
||
116 | |||
117 | register_shutdown_function(function () { |
||
118 | $this->shutdown(); |
||
119 | }); |
||
120 | |||
121 | $this->setTitle( |
||
122 | Daemon::$runName . ': IPC process' |
||
123 | . (Daemon::$config->pidfile->value !== Daemon::$config->defaultpidfile->value |
||
124 | ? ' (' . Daemon::$config->pidfile->value . ')' : '') |
||
125 | ); |
||
126 | |||
127 | if (isset(Daemon::$config->group->value)) { |
||
128 | $sg = posix_getgrnam(Daemon::$config->group->value); |
||
129 | } |
||
130 | |||
131 | if (isset(Daemon::$config->user->value)) { |
||
132 | $su = posix_getpwnam(Daemon::$config->user->value); |
||
133 | } |
||
134 | |||
135 | if (Daemon::$config->chroot->value !== '/') { |
||
136 | View Code Duplication | if (posix_getuid() != 0) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
137 | $this->log('You must have the root privileges to change root.'); |
||
138 | exit(0); |
||
139 | } elseif (!chroot(Daemon::$config->chroot->value)) { |
||
140 | Daemon::log('Couldn\'t change root to \'' . Daemon::$config->chroot->value . '\'.'); |
||
141 | exit(0); |
||
142 | } |
||
143 | } |
||
144 | |||
145 | View Code Duplication | if (isset(Daemon::$config->group->value)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
146 | if ($sg === false) { |
||
147 | $this->log('Couldn\'t change group to \'' . Daemon::$config->group->value . '\'. You must replace config-variable \'group\' with existing group.'); |
||
148 | exit(0); |
||
149 | } elseif (($sg['gid'] != posix_getgid()) && (!posix_setgid($sg['gid']))) { |
||
0 ignored issues
–
show
The variable
$sg does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
150 | $this->log('Couldn\'t change group to \'' . Daemon::$config->group->value . "'. Error (" . ($errno = posix_get_last_error()) . '): ' . posix_strerror($errno)); |
||
151 | exit(0); |
||
152 | } |
||
153 | } |
||
154 | |||
155 | View Code Duplication | if (isset(Daemon::$config->user->value)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
156 | if ($su === false) { |
||
157 | $this->log('Couldn\'t change user to \'' . Daemon::$config->user->value . '\', user not found. You must replace config-variable \'user\' with existing username.'); |
||
158 | exit(0); |
||
159 | } elseif (($su['uid'] != posix_getuid()) && (!posix_setuid($su['uid']))) { |
||
0 ignored issues
–
show
The variable
$su does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
160 | $this->log('Couldn\'t change user to \'' . Daemon::$config->user->value . "'. Error (" . ($errno = posix_get_last_error()) . '): ' . posix_strerror($errno)); |
||
161 | exit(0); |
||
162 | } |
||
163 | } |
||
164 | |||
165 | View Code Duplication | if (Daemon::$config->cwd->value !== '.') { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
166 | if (!@chdir(Daemon::$config->cwd->value)) { |
||
167 | $this->log('Couldn\'t change directory to \'' . Daemon::$config->cwd->value . '.'); |
||
168 | } |
||
169 | } |
||
170 | } |
||
171 | |||
172 | /** |
||
173 | * Log something |
||
174 | * @param string - Message. |
||
175 | * @param string $message |
||
176 | * @return void |
||
177 | */ |
||
178 | public function log($message) |
||
179 | { |
||
180 | Daemon::log('I#' . $this->pid . ' ' . $message); |
||
181 | } |
||
182 | |||
183 | /** |
||
184 | * Reloads additional config-files on-the-fly. |
||
185 | * @return void |
||
186 | */ |
||
187 | protected function update() |
||
188 | { |
||
189 | FileSystem::updateConfig(); |
||
190 | foreach (Daemon::$appInstances as $app) { |
||
191 | foreach ($app as $appInstance) { |
||
192 | $appInstance->handleStatus(AppInstance::EVENT_CONFIG_UPDATED); |
||
193 | } |
||
194 | } |
||
195 | } |
||
196 | |||
197 | /** |
||
198 | * Shutdown thread |
||
199 | * @param boolean - Hard? If hard, we shouldn't wait for graceful shutdown of the running applications. |
||
200 | * @return boolean|null - Ready? |
||
201 | */ |
||
202 | public function shutdown($hard = false) |
||
203 | { |
||
204 | $error = error_get_last(); |
||
205 | View Code Duplication | if ($error) { |
|
0 ignored issues
–
show
The expression
$error of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
206 | if ($error['type'] === E_ERROR) { |
||
207 | $this->log('crashed by error \'' . $error['message'] . '\' at ' . $error['file'] . ':' . $error['line']); |
||
208 | } |
||
209 | } |
||
210 | |||
211 | if (Daemon::$config->throwexceptiononshutdown->value) { |
||
212 | throw new \Exception('event shutdown'); |
||
213 | } |
||
214 | |||
215 | @ob_flush(); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||
216 | |||
217 | View Code Duplication | if ($this->terminated === true) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
218 | if ($hard) { |
||
219 | posix_kill(getmypid(), SIGKILL); |
||
220 | exit(0); |
||
221 | } |
||
222 | |||
223 | return; |
||
224 | } |
||
225 | |||
226 | $this->terminated = true; |
||
227 | if ($hard) { |
||
228 | posix_kill(getmypid(), SIGKILL); |
||
229 | exit(0); |
||
230 | } |
||
231 | FileSystem::waitAllEvents(); // ensure that all I/O events completed before suicide |
||
232 | posix_kill(posix_getppid(), SIGCHLD); // praying to Master |
||
233 | posix_kill(getmypid(), SIGKILL); |
||
234 | exit(0); // R.I.P. |
||
235 | } |
||
236 | |||
237 | /** |
||
238 | * Handler of the SIGINT (hard shutdown) signal in worker process. |
||
239 | * @return void |
||
240 | */ |
||
241 | protected function sigint() |
||
242 | { |
||
243 | if (Daemon::$config->logsignals->value) { |
||
244 | $this->log('caught SIGINT.'); |
||
245 | } |
||
246 | |||
247 | $this->shutdown(true); |
||
248 | } |
||
249 | |||
250 | /** |
||
251 | * Handler of the SIGTERM (graceful shutdown) signal in worker process. |
||
252 | * @return void |
||
253 | */ |
||
254 | protected function sigterm() |
||
255 | { |
||
256 | if (Daemon::$config->logsignals->value) { |
||
257 | $this->log('caught SIGTERM.'); |
||
258 | } |
||
259 | |||
260 | $this->shutdown(); |
||
261 | } |
||
262 | |||
263 | /** |
||
264 | * Handler of the SIGQUIT (graceful shutdown) signal in worker process. |
||
265 | * @return void |
||
266 | */ |
||
267 | public function sigquit() |
||
268 | { |
||
269 | if (Daemon::$config->logsignals->value) { |
||
270 | $this->log('caught SIGQUIT.'); |
||
271 | } |
||
272 | |||
273 | parent::sigquit(); |
||
274 | } |
||
275 | |||
276 | /** |
||
277 | * Handler of the SIGTSTP (graceful stop) signal in worker process. |
||
278 | * @return void |
||
279 | */ |
||
280 | protected function sigtstp() |
||
281 | { |
||
282 | if (Daemon::$config->logsignals->value) { |
||
283 | $this->log('Caught SIGTSTP (graceful stop all workers).'); |
||
284 | } |
||
285 | |||
286 | $this->shutdown(); |
||
287 | } |
||
288 | |||
289 | /** |
||
290 | * Handler of the SIGHUP (reload config) signal in worker process. |
||
291 | * @return void |
||
292 | */ |
||
293 | View Code Duplication | public function sighup() |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
294 | { |
||
295 | if (Daemon::$config->logsignals->value) { |
||
296 | $this->log('caught SIGHUP (reload config).'); |
||
297 | } |
||
298 | |||
299 | if (isset(Daemon::$config->configfile->value)) { |
||
300 | Daemon::loadConfig(Daemon::$config->configfile->value); |
||
301 | } |
||
302 | |||
303 | $this->update = true; |
||
304 | } |
||
305 | |||
306 | /** |
||
307 | * Handler of the SIGUSR1 (re-open log-file) signal in worker process. |
||
308 | * @return void |
||
309 | */ |
||
310 | public function sigusr1() |
||
311 | { |
||
312 | if (Daemon::$config->logsignals->value) { |
||
313 | $this->log('caught SIGUSR1 (re-open log-file).'); |
||
314 | } |
||
315 | |||
316 | Daemon::openLogs(); |
||
317 | } |
||
318 | |||
319 | /** |
||
320 | * Handler of the SIGUSR2 (graceful shutdown for update) signal in worker process. |
||
321 | * @return void |
||
322 | */ |
||
323 | public function sigusr2() |
||
324 | { |
||
325 | if (Daemon::$config->logsignals->value) { |
||
326 | $this->log('caught SIGUSR2 (graceful shutdown for update).'); |
||
327 | } |
||
328 | } |
||
329 | |||
330 | /** |
||
331 | * Handler of the SIGTTIN signal in worker process. |
||
332 | * @return void |
||
333 | */ |
||
334 | public function sigttin() |
||
335 | { |
||
336 | } |
||
337 | |||
338 | /** |
||
339 | * Handler of the SIGXSFZ signal in worker process. |
||
340 | * @return void |
||
341 | */ |
||
342 | public function sigxfsz() |
||
343 | { |
||
344 | $this->log('SIGXFSZ.'); |
||
345 | } |
||
346 | |||
347 | /** |
||
348 | * Handler of non-known signals. |
||
349 | * @return void |
||
350 | */ |
||
351 | View Code Duplication | public function sigunknown($signo) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
352 | { |
||
353 | if (isset(Generic::$signals[$signo])) { |
||
354 | $sig = Generic::$signals[$signo]; |
||
355 | } else { |
||
356 | $sig = 'UNKNOWN'; |
||
357 | } |
||
358 | |||
359 | $this->log('caught signal #' . $signo . ' (' . $sig . ').'); |
||
360 | } |
||
361 | } |
||
362 |
This check looks for access to methods that are not accessible from the current context.
If you need to make a method accessible to another context you can raise its visibility level in the defining class.