Added support for ZTS (Zend Thread Safety), including FrankenPHP support#355
Added support for ZTS (Zend Thread Safety), including FrankenPHP support#355ioaniftimesei wants to merge 172 commits intomainfrom
Conversation
…readability and performance in multiple files
…ion, so destroy the stats map after RequestProcessor to prevent use-after-free.
…ensure proper cleanup and prevent use-after-free issues.
… and enhance shell execution statistics
… zts extension binaries in rpm
- Updated RequestProcessor to manage instances with thread safety, supporting both NTS and ZTS modes. - Introduced CreateInstance and DestroyInstance functions for instance management. - Refactored existing function pointers to accept instance pointers, ensuring proper context handling. - Improved logging and error handling during initialization and configuration updates. - Added mutex locks to prevent race conditions in concurrent environments. - Adjusted various function signatures to accommodate instance pointers for better encapsulation of state.
…y-request-processor
…TS mode. The ZTS tests mirrors NTS tests(without apache-mod-php).
… from Dockerfiles
…ation in workflows
.github/workflows/build.yml
Outdated
| @@ -104,10 +104,61 @@ jobs: | |||
|
|
|||
| - name: Check PHP setup | |||
| run: | | |||
| which php | |||
| php -v | |||
| php -i | |||
| php -m | grep -E 'curl|mysqli' || (echo "Required extensions missing" && php -m && exit 1) | |||
| php -v | grep -v "ZTS" > /dev/null || (echo "ERROR: PHP is ZTS, expected NTS!" && php -v && exit 1) | |||
|
|
|||
|
|
|||
| - name: Build extension | |||
| run: | | |||
| rm -rf build | |||
| mkdir build | |||
| cd lib/php-extension | |||
| phpize | |||
| cd ../../build | |||
| CXX=g++ CXXFLAGS="-fPIC -g -O2 -I../lib/php-extension/include" LDFLAGS="-lstdc++" ../lib/php-extension/configure | |||
| make -j"$(nproc)" | |||
|
|
|||
| - name: Version Aikido extension | |||
| run: | | |||
| cd ./build/modules | |||
| mv aikido.so ${{ env.AIKIDO_ARTIFACT }}-nts.so | |||
|
|
|||
| - name: Archive build artifacts | |||
| uses: actions/upload-artifact@v4 | |||
| if: always() | |||
| with: | |||
| name: ${{ env.AIKIDO_ARTIFACT }}-nts-${{ env.ARCH }} | |||
| if-no-files-found: error | |||
| path: | | |||
| ${{ github.workspace }}/build/modules/${{ env.AIKIDO_ARTIFACT }}-nts.so | |||
| ${{ github.workspace }}/tests/*.diff | |||
|
|
|||
| build_php_extension_zts: | |||
| name: Build php${{ matrix.php_version }} extension ZTS ${{ matrix.arch == '' && 'x86_64' || 'arm' }} | |||
| runs-on: ubuntu-24.04${{ matrix.arch }} | |||
| container: ghcr.io/aikidosec/firewall-php-build-extension-zts:${{ matrix.php_version }}-v1 | |||
| strategy: | |||
| matrix: | |||
| php_version: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] | |||
| arch: [ '', '-arm' ] | |||
| fail-fast: false | |||
|
|
|||
| steps: | |||
| - name: Checkout repository | |||
| uses: actions/checkout@v4 | |||
|
|
|||
| - name: Get Arch | |||
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | |||
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
| uname -a | ||
| cat /etc/centos-release || cat /etc/redhat-release || echo "CentOS/Stream detected" | ||
| php -v | ||
| nginx -v || true | ||
| which php-fpm && php-fpm -v || true | ||
|
|
||
| - name: Verify ZTS is enabled | ||
| run: | | ||
| php -v | grep -q "ZTS" || (echo "ERROR: ZTS not enabled!" && exit 1) | ||
| php -v | ||
|
|
||
| - name: Install and start MySQL | ||
| run: | | ||
| mkdir -p /var/lib/mysql | ||
| mysqld --initialize-insecure --datadir=/var/lib/mysql | ||
| mysqld -u root --datadir=/var/lib/mysql --socket=/var/lib/mysql/mysql.sock & | ||
| sleep 10 | ||
| mysql -u root -e "CREATE DATABASE IF NOT EXISTS db;" | ||
| mysql -u root -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'pwd'; FLUSH PRIVILEGES;" | ||
|
|
||
| - name: Test MySQL connection with mysqli | ||
| run: | | ||
| php -r ' | ||
| $mysqli = new mysqli("localhost", "root", "pwd", "db"); | ||
| if ($mysqli->connect_error) { | ||
| echo "MySQL connection failed: " . $mysqli->connect_error . "\n"; | ||
| exit(1); | ||
| } else { | ||
| echo "MySQL connection successful\n"; | ||
| $mysqli->close(); | ||
| } | ||
| ' | ||
|
|
||
| - name: Get Arch | ||
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | ||
|
|
||
| - name: Check PHP setup | ||
| run: | | ||
| uname -m | ||
| php -v | ||
| php -i | head -20 | ||
|
|
||
| - name: Get Aikido version | ||
| run: | | ||
| AIKIDO_VERSION=$(grep '#define PHP_AIKIDO_VERSION' lib/php-extension/include/php_aikido.h | awk -F'"' '{print $2}') | ||
| echo $AIKIDO_VERSION | ||
| echo "AIKIDO_VERSION=$AIKIDO_VERSION" >> $GITHUB_ENV | ||
| echo "AIKIDO_RPM=aikido-php-firewall.${{ env.ARCH }}.rpm" >> $GITHUB_ENV | ||
|
|
||
| - name: Download artifacts | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| pattern: | | ||
| ${{ env.AIKIDO_RPM }} | ||
|
|
||
| - name: Install RPM | ||
| run: | | ||
| rpm -Uvh --oldpackage ${{ env.AIKIDO_RPM }}/${{ env.AIKIDO_RPM }} | ||
|
|
||
| - name: Run CLI tests | ||
| run: | | ||
| export TEST_PHP_EXECUTABLE=/usr/local/bin/php | ||
| php lib/php-extension/run-tests.php ./tests/cli | ||
|
|
||
| - name: Run ${{ matrix.server }} server tests | ||
| run: | |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 22 days ago
To fix this, explicitly restrict the GITHUB_TOKEN permissions for the workflow so it doesn’t inherit potentially read‑write defaults. The best way, without changing behavior, is to add a workflow‑level permissions: block granting only contents: read, which is sufficient for typical read operations (e.g., checking out code). Since we are only allowed to modify the shown .github/workflows/build.yml snippet and there is no global permissions: block visible, we will add permissions: contents: read to each of the relevant jobs. Concretely:
- In
.github/workflows/build.yml, for each job definition in the shown snippet that lackspermissions:, add apermissions:mapping immediately under the job header (afterruns-onorneeds/strategykeys, but still within the job). - For the
test_php_ubuntu,test_php_ubuntu_zts,test_php_centos, andtest_php_centos_ztsjobs shown or referenced, add:
permissions:
contents: readThese jobs only run commands in containers and download artifacts, so restricting to contents: read will not remove any required capability.
| @@ -382,6 +382,8 @@ | ||
| test_php_centos: | ||
| name: CentOS NTS php-${{ matrix.php_version }} ${{ matrix.server }} ${{ matrix.arch == '' && 'x86_64' || 'arm' }} | ||
| runs-on: ubuntu-24.04${{ matrix.arch }} | ||
| permissions: | ||
| contents: read | ||
| container: | ||
| image: ghcr.io/aikidosec/firewall-php-test-centos-nts:${{ matrix.php_version }}-v2 | ||
| options: --privileged | ||
| @@ -471,6 +473,8 @@ | ||
| test_php_ubuntu: | ||
| name: Ubuntu NTS php-${{ matrix.php_version }} ${{ matrix.server }} ${{ matrix.arch == '' && 'x86_64' || 'arm' }} | ||
| runs-on: ubuntu-24.04${{ matrix.arch }} | ||
| permissions: | ||
| contents: read | ||
| container: | ||
| image: ghcr.io/aikidosec/firewall-php-test-ubuntu-nts:${{ matrix.php_version }}-v2 | ||
| options: --privileged | ||
| @@ -540,6 +544,8 @@ | ||
| test_php_ubuntu_zts: | ||
| name: Ubuntu ZTS php-${{ matrix.php_version }} ${{ matrix.server }} ${{ matrix.arch == '' && 'x86_64' || 'arm' }} | ||
| runs-on: ubuntu-24.04${{ matrix.arch }} | ||
| permissions: | ||
| contents: read | ||
| container: | ||
| image: ghcr.io/aikidosec/firewall-php-test-ubuntu-zts:${{ matrix.php_version }}-v2 | ||
| options: --privileged |
.github/workflows/build.yml
Outdated
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 22 days ago
To fix the problem, the workflow should explicitly set minimal GITHUB_TOKEN permissions instead of inheriting repository defaults. The simplest and safest approach is to add a permissions: block at the top (root) level of .github/workflows/build.yml, right under name: Build and before the on: section. This root-level block will apply to all jobs in the workflow that do not define their own permissions: block, which is the case for the jobs shown (including test_php_ubuntu_zts at line 540). Because the jobs use actions/checkout and actions/download-artifact and do not need to write to the repository or manage issues, we can limit permissions to contents: read, which is compatible with both of those actions.
Concretely:
- Edit
.github/workflows/build.yml. - Insert a root-level
permissions:mapping after line 1 (name: Build) and before the existingon:block. - Set
contents: readinside this block to grant only read access to the repository contents. - No other file or line changes are required; no new imports or actions are needed.
| @@ -1,5 +1,8 @@ | ||
| name: Build | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| on: | ||
| push: | ||
| branches: |
| } | ||
| tid := inst.GetThreadID() | ||
| // Create new event context if it doesn't exist | ||
| newCtx := &EventContextData{} |
11b99c1 to
ce92b16
Compare
…ssignment and update SSRF test cases to utilize context instances
… update context handling in request processor (no more global maps)
Summary by Aikido
🚀 New Features
⚡ Enhancements
🔧 Refactors
More info