有没有安全的方法可以将非公共方法用作信号处理程序?

时间:2019-05-02 21:36:16

标签: php

我正在用PHP实现一个前叉式tcp套接字服务器,可处理多个子进程,共享内存,信号量和各种信号。

我目前正在为信号处理程序使用受保护的方法。

不幸的是,这有时会因“无法访问受保护的方法”错误而失败。

我很确定在代码处于其他类(例如共享内存类)的方法中时传递信号时会发生这种情况。

我宁愿使用受保护的方法,因为这些方法实际上不应从任何其他用户区号中调用。

我的问题是:有没有安全的方法可以将非公共方法用作信号处理程序?

1 个答案:

答案 0 :(得分:1)

简短的答案:否。使用非公共方法作为信号处理程序并不安全。

更长的答案(为什么): 尽管我不是PHP内部专家,但是多年来,我已经编写了许多自定义PHP扩展,并对内部结构有所了解,因此我决定通过查看所涉及的实际PHP函数来研究此问题。

操作系统实际上并未调用用户陆地信号处理程序。

pcntl_signal()函数将表示用户陆地信号处理程序的结构添加到内部列表中,然后(通过其他一些调用)设置 pcntl_signal_handler()内部函数作为指定信号的实际处理程序。

传递信号时,操作系统调用 pcntl_signal_handler(),该命令修改内部信号处理程序表并将全局 pending_signals 标志设置为1。如果启用了异步信号,则还会将全局 vm_interrupt 标志设置为1。

之后,PHP将调用 pcntl_signal_dispatch()的内部版本,该版本会进行一些完整性检查和内部整理,并最终调用 call_user_function()内部函数

据我所知, call_user_function()每当在PHP内部调用可调用用户时都会使用 call_user_function()实际上是一个调用_call_user_function_ex())的宏。

_call_user_function_ex()函数设置一个结构,然后调用 zend_call_function()

z end_call_function()最终调用 zend_is_callable_ex(),这将进行大量检查,以查看用户土地函数是否可调用,包括当前范围,以及该检查如果在应用程序正在交付信号处理程序的类以外的任何范围内执行应用程序时交付信号,则失败,例如,用户陆地数据库抽象方法或记录器。

所以不,使用非公共方法作为信号处理程序并不安全。