From 38684d8f39bde7aa41c61df12f7ef84c9c8ab7b7 Mon Sep 17 00:00:00 2001 From: Leonardo Di Giovanna Date: Tue, 19 Nov 2024 10:53:11 +0100 Subject: [PATCH] feat(decl/syscalls): add kill system call test step Signed-off-by: Leonardo Di Giovanna Co-authored-by: Aldo Lacuku --- pkg/test/field/field.go | 4 ++ pkg/test/loader/loader.go | 5 ++- pkg/test/step/syscall/base/base.go | 12 ++++++ pkg/test/step/syscall/base/consts.go | 37 ++++++++++++++++ pkg/test/step/syscall/builder/builder.go | 3 ++ pkg/test/step/syscall/kill/doc.go | 17 ++++++++ pkg/test/step/syscall/kill/kill.go | 54 ++++++++++++++++++++++++ pkg/test/step/syscall/syscall.go | 2 + 8 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 pkg/test/step/syscall/kill/doc.go create mode 100644 pkg/test/step/syscall/kill/kill.go diff --git a/pkg/test/field/field.go b/pkg/test/field/field.go index e6cb6ef0..76ba1691 100644 --- a/pkg/test/field/field.go +++ b/pkg/test/field/field.go @@ -79,6 +79,10 @@ const ( TypeSocketProtocol Type = "socket_protocol" // TypeSendFlags specifies that the field contains the sendto system call flags. TypeSendFlags Type = "send_flags" + // TypePID specifies that the field contains a process identifier. + TypePID Type = "pid" + // TypeSignal specifies that the field contains a signal. + TypeSignal Type = "signal" ) const ( diff --git a/pkg/test/loader/loader.go b/pkg/test/loader/loader.go index 9660f62e..c3d9fd98 100644 --- a/pkg/test/loader/loader.go +++ b/pkg/test/loader/loader.go @@ -676,6 +676,8 @@ const ( SyscallNameSocket SyscallName = "socket" // SyscallNameSendTo specifies the name of the sendto system call. SyscallNameSendTo SyscallName = "sendto" + // SyscallNameKill specifies the name of the kill system call. + SyscallNameKill SyscallName = "kill" ) // UnmarshalYAML populates the SyscallName instance by unmarshalling the content of the provided YAML node. @@ -687,7 +689,8 @@ func (s *SyscallName) UnmarshalYAML(node *yaml.Node) error { switch SyscallName(value) { case SyscallNameWrite, SyscallNameRead, SyscallNameOpen, SyscallNameOpenAt, SyscallNameOpenAt2, SyscallNameSymLink, SyscallNameSymLinkAt, SyscallNameLink, SyscallNameLinkAt, SyscallNameInitModule, SyscallNameFinitModule, - SyscallNameDup, SyscallNameDup2, SyscallNameDup3, SyscallNameConnect, SyscallNameSocket, SyscallNameSendTo: + SyscallNameDup, SyscallNameDup2, SyscallNameDup3, SyscallNameConnect, SyscallNameSocket, SyscallNameSendTo, + SyscallNameKill: default: return fmt.Errorf("unknown syscall %q", value) } diff --git a/pkg/test/step/syscall/base/base.go b/pkg/test/step/syscall/base/base.go index 5fc8e07b..daffacd3 100644 --- a/pkg/test/step/syscall/base/base.go +++ b/pkg/test/step/syscall/base/base.go @@ -235,6 +235,18 @@ func setArgFieldValue(argField *field.Field, value string) error { return fmt.Errorf("cannot parse value as send flags: %w", err) } argFieldValue.SetInt(int64(sendFlags)) + case field.TypePID: + pid, err := strconv.Atoi(value) + if err != nil { + return fmt.Errorf("cannot parse value as PID: %w", err) + } + argFieldValue.SetInt(int64(pid)) + case field.TypeSignal: + signal, err := parseSingleValue(value, signals) + if err != nil { + return fmt.Errorf("cannot parse value as signal: %w", err) + } + argFieldValue.SetInt(int64(signal)) case field.TypeUndefined: return fmt.Errorf("argument field type is undefined") default: diff --git a/pkg/test/step/syscall/base/consts.go b/pkg/test/step/syscall/base/consts.go index 13349483..c7b5a821 100644 --- a/pkg/test/step/syscall/base/consts.go +++ b/pkg/test/step/syscall/base/consts.go @@ -188,3 +188,40 @@ var sendFlags = map[string]int{ "MSG_NOSIGNAL": unix.MSG_NOSIGNAL, "MSG_OOB": unix.MSG_OOB, } + +var signals = map[string]int{ + "SIGABRT": int(unix.SIGABRT), + "SIGALRM": int(unix.SIGALRM), + "SIGBUS": int(unix.SIGBUS), + "SIGCHLD": int(unix.SIGCHLD), + "SIGCLD": int(unix.SIGCLD), + "SIGCONT": int(unix.SIGCONT), + "SIGFPE": int(unix.SIGFPE), + "SIGHUP": int(unix.SIGHUP), + "SIGILL": int(unix.SIGILL), + "SIGINT": int(unix.SIGINT), + "SIGIO": int(unix.SIGIO), + "SIGIOT": int(unix.SIGIOT), + "SIGKILL": int(unix.SIGKILL), + "SIGPIPE": int(unix.SIGPIPE), + "SIGPOLL": int(unix.SIGPOLL), + "SIGPROF": int(unix.SIGPROF), + "SIGPWR": int(unix.SIGPWR), + "SIGQUIT": int(unix.SIGQUIT), + "SIGSEGV": int(unix.SIGSEGV), + "SIGSTKFLT": int(unix.SIGSTKFLT), + "SIGSTOP": int(unix.SIGSTOP), + "SIGTSTP": int(unix.SIGTSTP), + "SIGSYS": int(unix.SIGSYS), + "SIGTERM": int(unix.SIGTERM), + "SIGTRAP": int(unix.SIGTRAP), + "SIGTTIN": int(unix.SIGTTIN), + "SIGTTOU": int(unix.SIGTTOU), + "SIGURG": int(unix.SIGURG), + "SIGUSR1": int(unix.SIGUSR1), + "SIGUSR2": int(unix.SIGUSR2), + "SIGVTALRM": int(unix.SIGVTALRM), + "SIGXCPU": int(unix.SIGXCPU), + "SIGXFSZ": int(unix.SIGXFSZ), + "SIGWINCH": int(unix.SIGWINCH), +} diff --git a/pkg/test/step/syscall/builder/builder.go b/pkg/test/step/syscall/builder/builder.go index 06d508e9..0a47ede5 100644 --- a/pkg/test/step/syscall/builder/builder.go +++ b/pkg/test/step/syscall/builder/builder.go @@ -25,6 +25,7 @@ import ( "github.com/falcosecurity/event-generator/pkg/test/step/syscall/dup3" "github.com/falcosecurity/event-generator/pkg/test/step/syscall/finitmodule" "github.com/falcosecurity/event-generator/pkg/test/step/syscall/initmodule" + "github.com/falcosecurity/event-generator/pkg/test/step/syscall/kill" "github.com/falcosecurity/event-generator/pkg/test/step/syscall/link" "github.com/falcosecurity/event-generator/pkg/test/step/syscall/linkat" "github.com/falcosecurity/event-generator/pkg/test/step/syscall/open" @@ -88,6 +89,8 @@ func (b *builder) Build(name syscall.Name, stepName string, description *syscall return errDecorator(finitmodule.New(stepName, rawArgs, fieldBindings)) case syscall.NameSendTo: return errDecorator(sendto.New(stepName, rawArgs, fieldBindings)) + case syscall.NameKill: + return errDecorator(kill.New(stepName, rawArgs, fieldBindings)) default: return nil, fmt.Errorf("unknown syscall %q", name) } diff --git a/pkg/test/step/syscall/kill/doc.go b/pkg/test/step/syscall/kill/doc.go new file mode 100644 index 00000000..29c68564 --- /dev/null +++ b/pkg/test/step/syscall/kill/doc.go @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (C) 2024 The Falco Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package kill provides the implementation of a kill system call test step. +package kill diff --git a/pkg/test/step/syscall/kill/kill.go b/pkg/test/step/syscall/kill/kill.go new file mode 100644 index 00000000..beae8db7 --- /dev/null +++ b/pkg/test/step/syscall/kill/kill.go @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (C) 2024 The Falco Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package kill + +import ( + "context" + "reflect" + + "golang.org/x/sys/unix" + + "github.com/falcosecurity/event-generator/pkg/test/step" + "github.com/falcosecurity/event-generator/pkg/test/step/syscall" + "github.com/falcosecurity/event-generator/pkg/test/step/syscall/base" +) + +type killSyscall struct { + // args represents arguments that can be provided by value or by binding. + args struct { + Sig unix.Signal `field_type:"signal"` + } + // bindOnlyArgs represents arguments that can only be provided by binding. + bindOnlyArgs struct { + PID int `field_type:"pid"` + } + // Return value is neither set nor bindable. +} + +// New creates a new kill system call test step. +func New(name string, rawArgs map[string]string, + fieldBindings []*step.FieldBinding) (syscall.Syscall, error) { + k := &killSyscall{} + argsContainer := reflect.ValueOf(&k.args).Elem() + bindOnlyArgsContainer := reflect.ValueOf(&k.bindOnlyArgs).Elem() + retValContainer := reflect.ValueOf(k).Elem() + return base.New(name, rawArgs, fieldBindings, argsContainer, bindOnlyArgsContainer, retValContainer, nil, k.run, + nil) +} + +func (k *killSyscall) run(_ context.Context) error { + return unix.Kill(k.bindOnlyArgs.PID, k.args.Sig) +} diff --git a/pkg/test/step/syscall/syscall.go b/pkg/test/step/syscall/syscall.go index 626ac77a..20674c59 100644 --- a/pkg/test/step/syscall/syscall.go +++ b/pkg/test/step/syscall/syscall.go @@ -68,6 +68,8 @@ const ( NameSocket = "socket" // NameSendTo specifies the name of the sendto system call test step. NameSendTo = "sendto" + // NameKill specifies the name of the kill system call test step. + NameKill = "kill" ) // Description contains information to build a new Syscall test step.