From 05ced629dc056c34063a93da564ef586474251e9 Mon Sep 17 00:00:00 2001 From: Eliott Bouhana <47679741+eliottness@users.noreply.github.com> Date: Tue, 19 Dec 2023 11:19:53 +0100 Subject: [PATCH] refactor!: opt-in with the appsec build tag when cgo is disabled (#57) Signed-off-by: Eliott Bouhana Co-authored-by: Julio Guerra --- .github/workflows/test.yml | 6 ++++++ _tools/libddwaf-updater/update.go | 2 +- ctypes_test.go | 2 +- encoder_decoder_test.go | 2 +- internal/lib/lib.go | 2 +- internal/lib/lib_darwin_amd64.go | 2 +- internal/lib/lib_darwin_arm64.go | 2 +- internal/lib/lib_linux_amd64.go | 2 +- internal/lib/lib_linux_arm64.go | 2 +- symbols_linux_purego.go | 2 +- waf_cgo_disabled.go | 14 ++++++++++++ waf_cgo_disabled_test.go | 36 +++++++++++++++++++++++++++++++ waf_dl.go | 2 +- waf_dl_test.go | 2 +- waf_dl_unsupported.go | 2 +- waf_support.go | 6 ++++++ waf_test.go | 2 +- 17 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 waf_cgo_disabled.go create mode 100644 waf_cgo_disabled_test.go diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d7ec2833..8df4ec3c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,6 +20,7 @@ jobs: - '' # Default behavior - 'datadog.no_waf' # Explicitly disabled WAF - 'go1.22' # Too recent go version (purego compatibility uncertain) + - 'appsec' # Legacy build tag to enable appsec when cgo is disabled - 'datadog.no_waf,go1.22' # Explicitly disabled & too recent go version (purego compatibility uncertain) include: # gocheck2 is configured differently in go1.21 than in previous versions @@ -39,6 +40,8 @@ jobs: go-tags: go1.22 - go-version: '1.19' go-tags: datadog.no_waf,go1.22 + - cgo-enabled: 1 + go-tags: "appsec" name: ${{ matrix.runs-on }} go${{ matrix.go-version }} cgo=${{ matrix.cgo-enabled }} tags=${{ matrix.go-tags }} runs-on: ${{ matrix.runs-on }} steps: @@ -78,6 +81,7 @@ jobs: - '' # Default behavior - 'datadog.no_waf' # Explicitly disabled WAF - 'go1.22' # Too recent go version (purego compatibility uncertain) + - 'appsec' # Legacy build tag to enable appsec when cgo is disabled - 'datadog.no_waf,go1.22' # Explicitly disabled & too recent go version (purego compatibility uncertain) include: # gocheck2 is configured differently in go1.21 than in previous versions @@ -105,6 +109,8 @@ jobs: image: amazonlinux:2 - go-version: '1.21' image: amazonlinux:2 + - cgo-enabled: 1 + go-tags: "appsec" name: linux/${{ matrix.arch }} ${{ format(matrix.image, matrix.go-version) }} cgo=${{ matrix.cgo-enabled }} tags=${{ matrix.go-tags }} runs-on: ubuntu-latest steps: diff --git a/_tools/libddwaf-updater/update.go b/_tools/libddwaf-updater/update.go index 43d39fa5..ee63a7dc 100644 --- a/_tools/libddwaf-updater/update.go +++ b/_tools/libddwaf-updater/update.go @@ -282,7 +282,7 @@ func (t target) embedSourceFilename() string { } func (t target) buildConstraintDirective() string { - return fmt.Sprintf("//go:build %s && %s && !%s && !datadog.no_waf", t.os, t.arch, goVersionUnsupported) + return fmt.Sprintf("//go:build %s && %s && !%s && !datadog.no_waf && (cgo || appsec)", t.os, t.arch, goVersionUnsupported) } func (t target) tempFilePatternStatement() string { diff --git a/ctypes_test.go b/ctypes_test.go index e313c0e9..0ee25501 100644 --- a/ctypes_test.go +++ b/ctypes_test.go @@ -4,7 +4,7 @@ // Copyright 2016-present Datadog, Inc. // Purego only works on linux/macOS with amd64 and arm64 from now -//go:build (linux || darwin) && (amd64 || arm64) && !go1.22 && !datadog.no_waf +//go:build (linux || darwin) && (amd64 || arm64) && !go1.22 && !datadog.no_waf && (cgo || appsec) package waf diff --git a/encoder_decoder_test.go b/encoder_decoder_test.go index b321a35e..b9451ac4 100644 --- a/encoder_decoder_test.go +++ b/encoder_decoder_test.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build (amd64 || arm64) && (linux || darwin) && !go1.22 && !datadog.no_waf +//go:build (amd64 || arm64) && (linux || darwin) && !go1.22 && !datadog.no_waf && (cgo || appsec) package waf diff --git a/internal/lib/lib.go b/internal/lib/lib.go index 9d6d9182..de9f2f41 100644 --- a/internal/lib/lib.go +++ b/internal/lib/lib.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build ((darwin && (amd64 || arm64)) || (linux && (amd64 || arm64))) && !go1.22 && !datadog.no_waf +//go:build ((darwin && (amd64 || arm64)) || (linux && (amd64 || arm64))) && !go1.22 && !datadog.no_waf && (cgo || appsec) package lib diff --git a/internal/lib/lib_darwin_amd64.go b/internal/lib/lib_darwin_amd64.go index 89aa4e06..99e21315 100644 --- a/internal/lib/lib_darwin_amd64.go +++ b/internal/lib/lib_darwin_amd64.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build darwin && amd64 && !go1.22 && !datadog.no_waf +//go:build darwin && amd64 && !go1.22 && !datadog.no_waf && (cgo || appsec) package lib diff --git a/internal/lib/lib_darwin_arm64.go b/internal/lib/lib_darwin_arm64.go index c084c7b0..e6077631 100644 --- a/internal/lib/lib_darwin_arm64.go +++ b/internal/lib/lib_darwin_arm64.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build darwin && arm64 && !go1.22 && !datadog.no_waf +//go:build darwin && arm64 && !go1.22 && !datadog.no_waf && (cgo || appsec) package lib diff --git a/internal/lib/lib_linux_amd64.go b/internal/lib/lib_linux_amd64.go index 63a30865..b916b5fd 100644 --- a/internal/lib/lib_linux_amd64.go +++ b/internal/lib/lib_linux_amd64.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build linux && amd64 && !go1.22 && !datadog.no_waf +//go:build linux && amd64 && !go1.22 && !datadog.no_waf && (cgo || appsec) package lib diff --git a/internal/lib/lib_linux_arm64.go b/internal/lib/lib_linux_arm64.go index 583ebdb9..4d65c920 100644 --- a/internal/lib/lib_linux_arm64.go +++ b/internal/lib/lib_linux_arm64.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build linux && arm64 && !go1.22 && !datadog.no_waf +//go:build linux && arm64 && !go1.22 && !datadog.no_waf && (cgo || appsec) package lib diff --git a/symbols_linux_purego.go b/symbols_linux_purego.go index 30d9de42..106418a3 100644 --- a/symbols_linux_purego.go +++ b/symbols_linux_purego.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build !cgo && linux && !go1.22 && !datadog.no_waf +//go:build !cgo && appsec && linux && !go1.22 && !datadog.no_waf package waf diff --git a/waf_cgo_disabled.go b/waf_cgo_disabled.go new file mode 100644 index 00000000..6f1bcd87 --- /dev/null +++ b/waf_cgo_disabled.go @@ -0,0 +1,14 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +// The Go build tag "appsec" was introduced to avoid having CGO_ENABLED=0 breaking changes +// due to purego's dynamic link against libdl.so, which is not expected when CGO is disabled. +//go:build !cgo && !appsec + +package waf + +func init() { + wafSupportErrors = append(wafSupportErrors, CgoDisabledError{}) +} diff --git a/waf_cgo_disabled_test.go b/waf_cgo_disabled_test.go new file mode 100644 index 00000000..fb23f719 --- /dev/null +++ b/waf_cgo_disabled_test.go @@ -0,0 +1,36 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build !cgo && !appsec + +package waf_test + +import ( + "testing" + + waf "github.com/DataDog/go-libddwaf/v2" + "github.com/stretchr/testify/require" +) + +func TestCgoDisabled(t *testing.T) { + t.Run("TestSupportsTarget", func(t *testing.T) { + supported, err := waf.SupportsTarget() + require.False(t, supported) + require.Error(t, err) + require.ErrorIs(t, err, waf.CgoDisabledError{}) + }) + + t.Run("TestLoad", func(t *testing.T) { + ok, err := waf.Load() + require.False(t, ok) + require.Error(t, err) + }) + + t.Run("TestHealth", func(t *testing.T) { + ok, err := waf.Health() + require.False(t, ok) + require.Error(t, err) + }) +} diff --git a/waf_dl.go b/waf_dl.go index d2fb2fe0..55ca5544 100644 --- a/waf_dl.go +++ b/waf_dl.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build (linux || darwin) && (amd64 || arm64) && !go1.22 && !datadog.no_waf +//go:build (linux || darwin) && (amd64 || arm64) && !go1.22 && !datadog.no_waf && (cgo || appsec) package waf diff --git a/waf_dl_test.go b/waf_dl_test.go index f95c9e5c..bbed9618 100644 --- a/waf_dl_test.go +++ b/waf_dl_test.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build (linux || darwin) && (amd64 || arm64) && !go1.22 && !datadog.no_waf +//go:build (linux || darwin) && (amd64 || arm64) && !go1.22 && !datadog.no_waf && (cgo || appsec) package waf diff --git a/waf_dl_unsupported.go b/waf_dl_unsupported.go index e16c1cee..707cdd44 100644 --- a/waf_dl_unsupported.go +++ b/waf_dl_unsupported.go @@ -4,7 +4,7 @@ // Copyright 2016-present Datadog, Inc. // Build when the target OS or architecture are not supported -//go:build (!linux && !darwin) || (!amd64 && !arm64) || go1.22 || datadog.no_waf +//go:build (!linux && !darwin) || (!amd64 && !arm64) || go1.22 || datadog.no_waf || (!cgo && !appsec) package waf diff --git a/waf_support.go b/waf_support.go index e32c2707..c2fb1409 100644 --- a/waf_support.go +++ b/waf_support.go @@ -38,6 +38,12 @@ func (e UnsupportedGoVersionError) Error() string { return fmt.Sprintf("unsupported Go version: %s", runtime.Version()) } +type CgoDisabledError struct{} + +func (e CgoDisabledError) Error() string { + return "go-libddwaf is disabled when cgo is disabled unless you compile with the go build tag `appsec`. It will require libdl.so.2. libpthread.so.0, libc.so.6 and libm.so.6 shared libraries at run time on linux" +} + // ManuallyDisabledError is a wrapper error type helping to handle the error // case of trying to execute this package when the WAF has been manually disabled with // the `datadog.no_waf` go build tag. diff --git a/waf_test.go b/waf_test.go index 1b76b195..89511fc8 100644 --- a/waf_test.go +++ b/waf_test.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build (amd64 || arm64) && (linux || darwin) && !go1.22 && !datadog.no_waf +//go:build (amd64 || arm64) && (linux || darwin) && !go1.22 && !datadog.no_waf && (cgo || appsec) package waf