Browse Source

ci: run tests with ASAN and MSAN (#955)

Kévin Dunglas 7 months ago
parent
commit
968176a948
5 changed files with 126 additions and 10 deletions
  1. 110 0
      .github/workflows/sanitizers.yaml
  2. 4 3
      Dockerfile
  3. 4 3
      alpine.Dockerfile
  4. 6 0
      build-static.sh
  5. 2 4
      frankenphp.go

+ 110 - 0
.github/workflows/sanitizers.yaml

@@ -0,0 +1,110 @@
+---
+name: Sanitizers
+on:
+  pull_request:
+    branches:
+      - main
+    paths-ignore:
+      - 'docs/**'
+  push:
+    branches:
+      - main
+    paths-ignore:
+      - 'docs/**'
+permissions:
+  contents: read
+jobs:
+  # Adapted from https://github.com/beberlei/hdrhistogram-php
+  sanitizers:
+    name: ${{ matrix.sanitizer }}
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        sanitizer: ['asan', 'msan']
+    env:
+      CFLAGS: -g -O0 -fsanitize=${{ matrix.sanitizer == 'asan' && 'address' || 'memory' }}  -DZEND_TRACK_ARENA_ALLOC
+      LDFLAGS: -fsanitize=${{ matrix.sanitizer == 'asan' && 'address' || 'memory' }}
+      CC: clang
+      CXX: clang++
+      USE_ZEND_ALLOC: 0
+      LIBRARY_PATH: ${{ github.workspace }}/php/target/lib
+      LD_LIBRARY_PATH: ${{ github.workspace }}/php/target/lib
+    steps:
+      -
+        name: Remove local PHP
+        run: sudo apt-get remove --purge --autoremove 'php*' 'libmemcached*'
+      -
+        uses: actions/checkout@v4
+      -
+        uses: actions/setup-go@v5
+        with:
+          go-version: '1.22'
+          cache-dependency-path: |
+            go.sum 
+            caddy/go.sum
+      -
+        name: Determine PHP version
+        id: determine-php-version
+        run: |
+          curl -fsSL 'https://www.php.net/releases/index.php?json&max=1&version=8.3' -o version.json
+          echo version="$(jq -r 'keys[0]' version.json)" >> "$GITHUB_OUTPUT"
+          echo archive="$(jq -r '.[] .source[] | select(.filename |endswith(".xz")) | "https://www.php.net/distributions/" + .filename' version.json)" >> "$GITHUB_OUTPUT"
+      -
+        name: Cache PHP
+        id: cache-php
+        uses: actions/cache@v4
+        with:
+          path: php/target
+          key: php-sanitizers-${{ matrix.sanitizer }}-${{ runner.arch }}-${{ steps.determine-php-version.outputs.version }}
+      -
+        if: steps.cache-php.outputs.cache-hit != 'true'
+        name: Compile PHP
+        run: |
+          mkdir php/
+          curl -fsSL "${{ steps.determine-php-version.outputs.archive }}" | tar -Jx -C php --strip-components=1
+          cd php/
+          ./configure \
+            CFLAGS="$CFLAGS" \
+            LDFLAGS="$LDFLAGS" \
+            --enable-debug \
+            --enable-embed \
+            --enable-zts \
+            --enable-option-checking=fatal \
+            --disable-zend-signals \
+            --without-sqlite3 \
+            --without-pdo-sqlite \
+            --without-libxml \
+            --disable-dom \
+            --disable-simplexml \
+            --disable-xml \
+            --disable-xmlreader \
+            --disable-xmlwriter \
+            --without-pcre-jit \
+            --disable-opcache-jit \
+            --disable-cli \
+            --disable-cgi \
+            --disable-phpdbg \
+            --without-pear \
+            --disable-mbregex \
+            --enable-werror \
+            ${{ matrix.sanitizer == 'msan' && '--enable-memory-sanitizer' || '' }} \
+            --prefix="$(pwd)/target/"
+          make -j"$(getconf _NPROCESSORS_ONLN)"
+          sudo make install
+      -
+        name: Add PHP to the PATH
+        run: echo "$(pwd)/php/target/bin" >> "$GITHUB_PATH"
+      -
+        name: Set Set CGO flags
+        run: |
+          {
+            echo "CGO_CFLAGS=$CFLAGS $(php-config --includes)"
+            echo "CGO_LDFLAGS=$LDFLAGS $(php-config --ldflags) $(php-config --libs)"
+          } >> "$GITHUB_ENV"
+      -
+        name: Compile tests
+        run: go test -${{ matrix.sanitizer }} -v -x -c
+      -
+        name: Run tests
+        run: ./frankenphp.test -test.v

+ 4 - 3
Dockerfile

@@ -86,9 +86,10 @@ COPY --link caddy caddy
 COPY --link internal internal
 COPY --link testdata testdata
 
-# todo: automate this?
-# see https://github.com/docker-library/php/blob/master/8.2/bookworm/zts/Dockerfile#L57-L59 for PHP values
-ENV CGO_LDFLAGS="-lssl -lcrypto -lreadline -largon2 -lcurl -lonig -lz $PHP_LDFLAGS" CGO_CFLAGS="-DFRANKENPHP_VERSION=$FRANKENPHP_VERSION $PHP_CFLAGS" CGO_CPPFLAGS=$PHP_CPPFLAGS
+# See https://github.com/docker-library/php/blob/master/8.3/bookworm/zts/Dockerfile#L57-L59 for PHP values
+ENV CGO_CFLAGS="-DFRANKENPHP_VERSION=$FRANKENPHP_VERSION $PHP_CFLAGS"
+ENV CGO_CPPFLAGS=$PHP_CPPFLAGS
+ENV CGO_LDFLAGS="-lssl -lcrypto -lreadline -largon2 -lcurl -lonig -lz $PHP_LDFLAGS"
 
 WORKDIR /go/src/app/caddy/frankenphp
 RUN GOBIN=/usr/local/bin go install -ldflags "-w -s -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP $FRANKENPHP_VERSION PHP $PHP_VERSION Caddy'" && \

+ 4 - 3
alpine.Dockerfile

@@ -104,9 +104,10 @@ COPY --link caddy caddy
 COPY --link internal internal
 COPY --link testdata testdata
 
-# todo: automate this?
-# see https://github.com/docker-library/php/blob/master/8.2/bookworm/zts/Dockerfile#L57-L59 for php values
-ENV CGO_LDFLAGS="-lssl -lcrypto -lreadline -largon2 -lcurl -lonig -lz $PHP_LDFLAGS" CGO_CFLAGS="-DFRANKENPHP_VERSION=$FRANKENPHP_VERSION $PHP_CFLAGS" CGO_CPPFLAGS=$PHP_CPPFLAGS
+# See https://github.com/docker-library/php/blob/master/8.3/alpine3.20/zts/Dockerfile#L53-L55
+ENV CGO_CFLAGS="-DFRANKENPHP_VERSION=$FRANKENPHP_VERSION $PHP_CFLAGS"
+ENV CGO_CPPFLAGS=$PHP_CPPFLAGS
+ENV CGO_LDFLAGS="-lssl -lcrypto -lreadline -largon2 -lcurl -lonig -lz $PHP_LDFLAGS"
 
 WORKDIR /go/src/app/caddy/frankenphp
 RUN GOBIN=/usr/local/bin go install -ldflags "-w -s -extldflags '-Wl,-z,stack-size=0x80000' -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP $FRANKENPHP_VERSION PHP $PHP_VERSION Caddy'" && \

+ 6 - 0
build-static.sh

@@ -120,14 +120,20 @@ else
 	./bin/spc build --debug --enable-zts --build-embed ${extraOpts} "${PHP_EXTENSIONS}" --with-libs="${PHP_EXTENSION_LIBS}"
 fi
 
+# See https://github.com/docker-library/php/blob/master/8.3/alpine3.20/zts/Dockerfile#L53-L55
 CGO_CFLAGS="-DFRANKENPHP_VERSION=${FRANKENPHP_VERSION} -I${PWD}/buildroot/include/ $(./buildroot/bin/php-config --includes | sed s#-I/#-I"${PWD}"/buildroot/#g)"
 if [ -n "${DEBUG_SYMBOLS}" ]; then
 	CGO_CFLAGS="-g ${CGO_CFLAGS}"
+else
+	CGO_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 ${CGO_CFLAGS}"
 fi
 export CGO_CFLAGS
+export CGO_CPPFLAGS="${CGO_CFLAGS}"
 
 if [ "${os}" = "mac" ]; then
 	export CGO_LDFLAGS="-framework CoreFoundation -framework SystemConfiguration"
+elif [ "${os}" = "linux" ] && [ -z "${DEBUG_SYMBOLS}" ]; then
+	CGO_LDFLAGS="-Wl,-O1 -pie"
 fi
 
 CGO_LDFLAGS="${CGO_LDFLAGS} ${PWD}/buildroot/lib/libbrotlicommon.a ${PWD}/buildroot/lib/libbrotlienc.a ${PWD}/buildroot/lib/libbrotlidec.a $(./buildroot/bin/php-config --ldflags || true) $(./buildroot/bin/php-config --libs || true)"

+ 2 - 4
frankenphp.go

@@ -13,13 +13,11 @@ package frankenphp
 // We also set these flags for hardening: https://github.com/docker-library/php/blob/master/8.2/bookworm/zts/Dockerfile#L57-L59
 
 // #cgo darwin pkg-config: libxml-2.0
-// #cgo CFLAGS: -Wall -Werror -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
 // #cgo CFLAGS: -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib
 // #cgo linux CFLAGS: -D_GNU_SOURCE
-// #cgo CPPFLAGS: -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
 // #cgo darwin LDFLAGS: -L/opt/homebrew/opt/libiconv/lib -liconv
-// #cgo linux LDFLAGS: -Wl,-O1 -lresolv
-// #cgo LDFLAGS: -pie -L/usr/local/lib -L/usr/lib -lphp -ldl -lm -lutil
+// #cgo linux LDFLAGS: -lresolv
+// #cgo LDFLAGS: -L/usr/local/lib -L/usr/lib -lphp -ldl -lm -lutil
 // #include <stdlib.h>
 // #include <stdint.h>
 // #include <php_variables.h>