Skip to content

Commit

Permalink
chore: add datadog.no_waf build tag (#47)
Browse files Browse the repository at this point in the history
- [x] Add `datadog.no_waf` build tag in all go:build directives
- [x] Add platform section as an excuse to talk about `datadog.no_waf`
build tag
- [x] Add new file to explain the new reason why the waf could be
disabled
- [x] Run the CI with the disabled build tag on most cases to extend
coverage to the new file
- [x] Rename "Unsupported" with "Disabled" for some identifiers as it
makes more sense now

---------

Signed-off-by: Eliott Bouhana <[email protected]>
Co-authored-by: Julio Guerra <[email protected]>
  • Loading branch information
eliottness and Julio-Guerra authored Nov 17, 2023
1 parent 9a073d0 commit f636cfe
Show file tree
Hide file tree
Showing 26 changed files with 255 additions and 76 deletions.
27 changes: 25 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: false
matrix:
runs-on: [ macos-13, macos-12, macos-11, ubuntu-22.04, ubuntu-20.04, windows-latest ]
runs-on: [ macos-13, macos-12, macos-11, ubuntu-22.04, ubuntu-20.04 ]
go-version: [ "1.21", "1.20", "1.19" ]
cgo_enabled: [ "0", "1" ] # test it compiles with and without cgo
include:
Expand All @@ -30,7 +30,6 @@ jobs:
with:
go-version: ${{ matrix.go-version }}
cache: true

- name: go test
shell: bash
run: |
Expand All @@ -39,6 +38,30 @@ jobs:
# Run the tests with gotestsum
env ${{ matrix.env }} CGO_ENABLED=${{ matrix.cgo_enabled }} ./gotestsum -- -v -count=10 -shuffle=on ./...
disabled:
strategy:
fail-fast: false
matrix:
runs-on: [ windows-latest, ubuntu-latest, macos-13 ]
go-args: [ "-tags datadog.no_waf", "-tags go1.22" ]
include:
- runs-on: windows-latest
go-args: ""
runs-on: ${{ matrix.runs-on }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: 'stable' # get latest stable version from https://github.com/actions/go-versions/blob/main/versions-manifest.json
cache: true
- name: go test
shell: bash
run: |
# Install gotestsum
env GOBIN=$PWD go install gotest.tools/gotestsum@latest
# Run the tests with gotestsum
./gotestsum -- -v ${{ matrix.go-tags }} -shuffle=on ./...
# Same tests but on the official golang container for linux
golang-linux-container:
runs-on: ubuntu-latest
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ But with the appearance of `ddwaf_object` tree like structure,
but also with the intention to build CGO-less bindings, this project size has grown to be a fully integrated brick in the DataDog tracer structure.
Which in turn made it necessary to document the project, to maintain it in an orderly fashion.

## Supported platforms

This library currently support the following platform doublets:

| OS | Arch |
| ----- | ------- |
| Linux | amd64 |
| Linux | aarch64 |
| OSX | amd64 |
| OSX | arm64 |

This means that when the platform is not supported, top-level functions will return a `WafDisabledError` error including the purpose of it.

Note that:
* Linux support include for glibc and musl variants
* OSX under 10.9 is not supported
* A build tag named `datadog.no_waf` can be manually added to force the WAF to be disabled.

## Design

The WAF bindings have multiple moving parts that are necessary to understand:
Expand Down
2 changes: 1 addition & 1 deletion ctypes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
//go:build (linux || darwin) && (amd64 || arm64) && !go1.22 && !datadog.no_waf

package waf

Expand Down
2 changes: 1 addition & 1 deletion encoder_decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
//go:build (amd64 || arm64) && (linux || darwin) && !go1.22 && !datadog.no_waf

package waf

Expand Down
2 changes: 1 addition & 1 deletion handle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

func TestNewHandle(t *testing.T) {
if supported, err := supportsTarget(); !supported || err != nil {
if supported, err := Health(); !supported || err != nil {
t.Skip("target is not supported by the WAF")
return
}
Expand Down
2 changes: 1 addition & 1 deletion internal/lib/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
//go:build ((darwin && (amd64 || arm64)) || (linux && (amd64 || arm64))) && !go1.22 && !datadog.no_waf

package lib

Expand Down
3 changes: 2 additions & 1 deletion internal/lib/lib_darwin_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.

//go:build darwin && amd64 && !go1.22
//go:build darwin && amd64 && !go1.22 && !datadog.no_waf

package lib

import _ "embed" // Needed for go:embed
Expand Down
3 changes: 2 additions & 1 deletion internal/lib/lib_darwin_arm64.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.

//go:build darwin && arm64 && !go1.22
//go:build darwin && arm64 && !go1.22 && !datadog.no_waf

package lib

import _ "embed" // Needed for go:embed
Expand Down
3 changes: 2 additions & 1 deletion internal/lib/lib_linux_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.

//go:build linux && amd64 && !go1.22
//go:build linux && amd64 && !go1.22 && !datadog.no_waf

package lib

import _ "embed" // Needed for go:embed
Expand Down
3 changes: 2 additions & 1 deletion internal/lib/lib_linux_arm64.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.

//go:build linux && arm64 && !go1.22
//go:build linux && arm64 && !go1.22 && !datadog.no_waf

package lib

import _ "embed" // Needed for go:embed
Expand Down
1 change: 0 additions & 1 deletion internal/noopfree/noopfree.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@

TEXT _noop_free_v2(SB), NOSPLIT, $0-0
RET

3 changes: 0 additions & 3 deletions safe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ func TestTryCall(t *testing.T) {
// panic called with an error
err := tryCall(func() error {
panic(myPanicErr)
return myErr
})
require.Error(t, err)
var panicErr *PanicError
Expand All @@ -35,7 +34,6 @@ func TestTryCall(t *testing.T) {
str := "woops"
err := tryCall(func() error {
panic(str)
return myErr
})
require.Error(t, err)
var panicErr *PanicError
Expand All @@ -48,7 +46,6 @@ func TestTryCall(t *testing.T) {
var i int64 = 42
err := tryCall(func() error {
panic(i)
return myErr
})
require.Error(t, err)
var panicErr *PanicError
Expand Down
2 changes: 1 addition & 1 deletion symbols_linux_cgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
//go:build cgo && linux && !go1.22 && !datadog.no_waf

package waf

Expand Down
2 changes: 1 addition & 1 deletion symbols_linux_purego.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
//go:build !cgo && linux && !go1.22 && !datadog.no_waf

package waf

Expand Down
31 changes: 8 additions & 23 deletions waf.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,6 @@ import (
"github.com/hashicorp/go-multierror"
)

// UnsupportedTargetError is a wrapper error type helping to handle the error
// case of trying to execute this package on an unsupported target environment.
type UnsupportedTargetError struct {
error
}

// Unwrap the error and return it.
// Required by errors.Is and errors.As functions.
func (e *UnsupportedTargetError) Unwrap() error {
return e.error
}

// Diagnostics stores the information - provided by the WAF - about WAF rules initialization.
type Diagnostics struct {
Version string
Expand Down Expand Up @@ -138,7 +126,7 @@ var (
// libddwaf's dynamic library handle and entrypoints
wafLib *wafDl
// libddwaf's dlopen error if any
wafErr error
wafLoadErr error
openWafOnce sync.Once
)

Expand All @@ -155,22 +143,19 @@ var (
// to remove temporary files. It is safe to continue using libddwaf in such
// case.
func Load() (ok bool, err error) {
if ok, err = Health(); !ok {
return false, err
}

openWafOnce.Do(func() {
wafLib, wafErr = newWafDl()
if wafErr != nil {
wafLib, wafLoadErr = newWafDl()
if wafLoadErr != nil {
return
}
wafVersion = wafLib.wafGetVersion()
})

return wafLib != nil, wafErr
}

// SupportsTarget returns true and a nil error when the target host environment
// is supported by this package and can be further used.
// Otherwise, it returns false along with an error detailing why.
func SupportsTarget() (bool, error) {
return supportsTarget()
return wafLib != nil, wafLoadErr
}

var wafVersion string
Expand Down
13 changes: 13 additions & 0 deletions waf_disabled_manually.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// 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.

// Manually set datadog.no_waf build tag
//go:build datadog.no_waf

package waf

func init() {
wafManuallyDisabledErr = ManuallyDisabledError{}
}
7 changes: 1 addition & 6 deletions waf_dl.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
//go:build (linux || darwin) && (amd64 || arm64) && !go1.22 && !datadog.no_waf

package waf

Expand Down Expand Up @@ -222,8 +222,3 @@ func resolveWafSymbols(handle uintptr) (symbols wafSymbols, err error) {

return
}

// Implement SupportsTarget()
func supportsTarget() (bool, error) {
return true, nil
}
2 changes: 1 addition & 1 deletion waf_dl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
//go:build (linux || darwin) && (amd64 || arm64) && !go1.22 && !datadog.no_waf

package waf

Expand Down
12 changes: 3 additions & 9 deletions waf_dl_unsupported.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
// Copyright 2016-present Datadog, Inc.

// Build when the target OS or architecture are not supported
//go:build (!linux && !darwin) || (!amd64 && !arm64) || go1.22
//go:build (!linux && !darwin) || (!amd64 && !arm64) || go1.22 || datadog.no_waf

package waf

type wafDl struct{}

func newWafDl() (dl *wafDl, err error) {
return nil, unsupportedTargetErr
_, err = Health()
return nil, err
}

func (waf *wafDl) wafGetVersion() string {
Expand Down Expand Up @@ -49,10 +50,3 @@ func (waf *wafDl) wafObjectFree(obj *wafObject) {
func (waf *wafDl) wafRun(context wafContext, persistentData, ephemeralData *wafObject, result *wafResult, timeout uint64) wafReturnCode {
return wafErrInternal
}

// Implement SupportsTarget()
func supportsTarget() (bool, error) {
// TODO: provide finer-grained unsupported target error message giving the
// exact reason why
return false, unsupportedTargetErr
}
28 changes: 28 additions & 0 deletions waf_manually_disabled_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// 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 datadog.no_waf

package waf_test

import (
"testing"

waf "github.com/DataDog/go-libddwaf/v2"
"github.com/stretchr/testify/require"
)

func TestLoad(t *testing.T) {
ok, err := waf.Load()
require.False(t, ok)
require.Error(t, err)
}

func TestHealth(t *testing.T) {
ok, err := waf.Health()
require.False(t, ok)
require.Error(t, err)
require.ErrorIs(t, err, waf.ManuallyDisabledError{})
}
Loading

0 comments on commit f636cfe

Please sign in to comment.