Skip to content

Commit

Permalink
[CWS] Add accept syscall (#32433)
Browse files Browse the repository at this point in the history
  • Loading branch information
kovagsm authored Jan 7, 2025
1 parent 00e6276 commit 2c0aedb
Show file tree
Hide file tree
Showing 29 changed files with 870 additions and 13 deletions.
47 changes: 47 additions & 0 deletions docs/cloud-workload-security/backend_linux.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,20 @@ CSM Threats event for Linux systems have the following JSON schema:
],
"description": "AWSSecurityCredentialsSerializer serializes the security credentials from an AWS IMDS request"
},
"AcceptEvent": {
"properties": {
"addr": {
"$ref": "#/$defs/IPPortFamily",
"description": "Bound address (if any)"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"addr"
],
"description": "AcceptEventSerializer serializes a bind event to JSON"
},
"AgentContext": {
"properties": {
"rule_id": {
Expand Down Expand Up @@ -1772,6 +1786,9 @@ CSM Threats event for Linux systems have the following JSON schema:
"imds": {
"$ref": "#/$defs/IMDSEvent"
},
"accept": {
"$ref": "#/$defs/AcceptEvent"
},
"bind": {
"$ref": "#/$defs/BindEvent"
},
Expand Down Expand Up @@ -1828,6 +1845,7 @@ CSM Threats event for Linux systems have the following JSON schema:
| `splice` | $ref | Please see [SpliceEvent](#spliceevent) |
| `dns` | $ref | Please see [DNSEvent](#dnsevent) |
| `imds` | $ref | Please see [IMDSEvent](#imdsevent) |
| `accept` | $ref | Please see [AcceptEvent](#acceptevent) |
| `bind` | $ref | Please see [BindEvent](#bindevent) |
| `connect` | $ref | Please see [ConnectEvent](#connectevent) |
| `mount` | $ref | Please see [MountEvent](#mountevent) |
Expand Down Expand Up @@ -1920,6 +1938,35 @@ CSM Threats event for Linux systems have the following JSON schema:
| `expiration` | expiration is the expiration date of the credentials |


## `AcceptEvent`


{{< code-block lang="json" collapsible="true" >}}
{
"properties": {
"addr": {
"$ref": "#/$defs/IPPortFamily",
"description": "Bound address (if any)"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"addr"
],
"description": "AcceptEventSerializer serializes a bind event to JSON"
}

{{< /code-block >}}

| Field | Description |
| ----- | ----------- |
| `addr` | Bound address (if any) |

| References |
| ---------- |
| [IPPortFamily](#ipportfamily) |

## `AgentContext`


Expand Down
17 changes: 17 additions & 0 deletions docs/cloud-workload-security/backend_linux.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,20 @@
],
"description": "AWSSecurityCredentialsSerializer serializes the security credentials from an AWS IMDS request"
},
"AcceptEvent": {
"properties": {
"addr": {
"$ref": "#/$defs/IPPortFamily",
"description": "Bound address (if any)"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"addr"
],
"description": "AcceptEventSerializer serializes a bind event to JSON"
},
"AgentContext": {
"properties": {
"rule_id": {
Expand Down Expand Up @@ -1761,6 +1775,9 @@
"imds": {
"$ref": "#/$defs/IMDSEvent"
},
"accept": {
"$ref": "#/$defs/AcceptEvent"
},
"bind": {
"$ref": "#/$defs/BindEvent"
},
Expand Down
36 changes: 28 additions & 8 deletions docs/cloud-workload-security/linux_expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Triggers are events that correspond to types of activity seen by the system. The

| SECL Event | Type | Definition | Agent Version |
| ---------- | ---- | ---------- | ------------- |
| `accept` | Network | An accept was executed | 7.60 |
| `bind` | Network | A bind was executed | 7.37 |
| `bpf` | Kernel | A BPF command was executed | 7.33 |
| `capset` | Process | A process changed its capacity set | 7.27 |
Expand Down Expand Up @@ -382,6 +383,18 @@ The *file.rights* attribute can now be used in addition to *file.mode*. *file.mo
| [`process.user_session.k8s_uid`](#common-usersessioncontext-k8s_uid-doc) | Kubernetes UID of the user that executed the process |
| [`process.user_session.k8s_username`](#common-usersessioncontext-k8s_username-doc) | Kubernetes username of the user that executed the process |

### Event `accept`

An accept was executed

| Property | Definition |
| -------- | ------------- |
| [`accept.addr.family`](#accept-addr-family-doc) | Address family |
| [`accept.addr.ip`](#common-ipportcontext-ip-doc) | IP address |
| [`accept.addr.is_public`](#common-ipportcontext-is_public-doc) | Whether the IP address belongs to a public network |
| [`accept.addr.port`](#common-ipportcontext-port-doc) | Port number |
| [`accept.retval`](#common-syscallevent-retval-doc) | Return value of the syscall |

### Event `bind`

A bind was executed
Expand Down Expand Up @@ -2157,8 +2170,8 @@ Type: IP/CIDR

Definition: IP address

`*.ip` has 6 possible prefixes:
`bind.addr` `connect.addr` `network.destination` `network.source` `packet.destination` `packet.source`
`*.ip` has 7 possible prefixes:
`accept.addr` `bind.addr` `connect.addr` `network.destination` `network.source` `packet.destination` `packet.source`


### `*.is_exec` {#common-process-is_exec-doc}
Expand All @@ -2184,8 +2197,8 @@ Type: bool

Definition: Whether the IP address belongs to a public network

`*.is_public` has 6 possible prefixes:
`bind.addr` `connect.addr` `network.destination` `network.source` `packet.destination` `packet.source`
`*.is_public` has 7 possible prefixes:
`accept.addr` `bind.addr` `connect.addr` `network.destination` `network.source` `packet.destination` `packet.source`


### `*.is_thread` {#common-process-is_thread-doc}
Expand Down Expand Up @@ -2381,8 +2394,8 @@ Type: int

Definition: Port number

`*.port` has 6 possible prefixes:
`bind.addr` `connect.addr` `network.destination` `network.source` `packet.destination` `packet.source`
`*.port` has 7 possible prefixes:
`accept.addr` `bind.addr` `connect.addr` `network.destination` `network.source` `packet.destination` `packet.source`


### `*.ppid` {#common-process-ppid-doc}
Expand All @@ -2399,8 +2412,8 @@ Type: int

Definition: Return value of the syscall

`*.retval` has 23 possible prefixes:
`bind` `bpf` `chdir` `chmod` `chown` `connect` `link` `load_module` `mkdir` `mmap` `mount` `mprotect` `open` `ptrace` `removexattr` `rename` `rmdir` `setxattr` `signal` `splice` `unlink` `unload_module` `utimes`
`*.retval` has 24 possible prefixes:
`accept` `bind` `bpf` `chdir` `chmod` `chown` `connect` `link` `load_module` `mkdir` `mmap` `mount` `mprotect` `open` `ptrace` `removexattr` `rename` `rmdir` `setxattr` `signal` `splice` `unlink` `unload_module` `utimes`

Constants: [Error constants](#error-constants)

Expand Down Expand Up @@ -2499,6 +2512,13 @@ Definition: Version of the cgroup API
`cgroup` `exec.cgroup` `exit.cgroup` `process.ancestors.cgroup` `process.cgroup` `process.parent.cgroup` `ptrace.tracee.ancestors.cgroup` `ptrace.tracee.cgroup` `ptrace.tracee.parent.cgroup` `signal.target.ancestors.cgroup` `signal.target.cgroup` `signal.target.parent.cgroup`


### `accept.addr.family` {#accept-addr-family-doc}
Type: int

Definition: Address family



### `bind.addr.family` {#bind-addr-family-doc}
Type: int

Expand Down
50 changes: 50 additions & 0 deletions docs/cloud-workload-security/secl_linux.json
Original file line number Diff line number Diff line change
Expand Up @@ -1319,6 +1319,40 @@
}
]
},
{
"name": "accept",
"definition": "An accept was executed",
"type": "Network",
"from_agent_version": "7.60",
"experimental": false,
"properties": [
{
"name": "accept.addr.family",
"definition": "Address family",
"property_doc_link": "accept-addr-family-doc"
},
{
"name": "accept.addr.ip",
"definition": "IP address",
"property_doc_link": "common-ipportcontext-ip-doc"
},
{
"name": "accept.addr.is_public",
"definition": "Whether the IP address belongs to a public network",
"property_doc_link": "common-ipportcontext-is_public-doc"
},
{
"name": "accept.addr.port",
"definition": "Port number",
"property_doc_link": "common-ipportcontext-port-doc"
},
{
"name": "accept.retval",
"definition": "Return value of the syscall",
"property_doc_link": "common-syscallevent-retval-doc"
}
]
},
{
"name": "bind",
"definition": "A bind was executed",
Expand Down Expand Up @@ -8433,6 +8467,7 @@
"type": "IP/CIDR",
"definition": "IP address",
"prefixes": [
"accept.addr",
"bind.addr",
"connect.addr",
"network.destination",
Expand Down Expand Up @@ -8494,6 +8529,7 @@
"type": "bool",
"definition": "Whether the IP address belongs to a public network",
"prefixes": [
"accept.addr",
"bind.addr",
"connect.addr",
"network.destination",
Expand Down Expand Up @@ -9189,6 +9225,7 @@
"type": "int",
"definition": "Port number",
"prefixes": [
"accept.addr",
"bind.addr",
"connect.addr",
"network.destination",
Expand Down Expand Up @@ -9228,6 +9265,7 @@
"type": "int",
"definition": "Return value of the syscall",
"prefixes": [
"accept",
"bind",
"bpf",
"chdir",
Expand Down Expand Up @@ -9535,6 +9573,18 @@
"constants_link": "",
"examples": []
},
{
"name": "accept.addr.family",
"link": "accept-addr-family-doc",
"type": "int",
"definition": "Address family",
"prefixes": [
"accept"
],
"constants": "",
"constants_link": "",
"examples": []
},
{
"name": "bind.addr.family",
"link": "bind-addr-family-doc",
Expand Down
1 change: 1 addition & 0 deletions pkg/security/ebpf/c/include/constants/enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ enum event_type
EVENT_DNS,
EVENT_NET_DEVICE,
EVENT_VETH_PAIR,
EVENT_ACCEPT,
EVENT_BIND,
EVENT_CONNECT,
EVENT_UNSHARE_MNTNS,
Expand Down
9 changes: 9 additions & 0 deletions pkg/security/ebpf/c/include/constants/offsets/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ __attribute__((always_inline)) u16 get_family_from_sock_common(struct sock_commo
return family;
}

__attribute__((always_inline)) struct sock* get_sock_from_socket(struct socket *socket) {
u64 socket_sock_offset;
LOAD_CONSTANT("socket_sock_offset", socket_sock_offset);

struct sock *sk = NULL;
bpf_probe_read(&sk, sizeof(sk), (void *)socket + socket_sock_offset);
return sk;
}

__attribute__((always_inline)) u64 get_flowi4_saddr_offset() {
u64 flowi4_saddr_offset;
LOAD_CONSTANT("flowi4_saddr_offset", flowi4_saddr_offset);
Expand Down
12 changes: 12 additions & 0 deletions pkg/security/ebpf/c/include/events_definition.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ struct invalidate_dentry_event_t {
u32 padding;
};

struct accept_event_t {
struct kevent_t event;
struct process_context_t process;
struct span_context_t span;
struct container_context_t container;
struct syscall_t syscall;

u64 addr[2];
u16 family;
u16 port;
};

struct bind_event_t {
struct kevent_t event;
struct process_context_t process;
Expand Down
1 change: 1 addition & 0 deletions pkg/security/ebpf/c/include/hooks/all.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "on_demand.h"
#include "chdir.h"

#include "network/accept.h"
#include "network/bind.h"
#include "network/connect.h"

Expand Down
45 changes: 45 additions & 0 deletions pkg/security/ebpf/c/include/hooks/network/accept.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#ifndef _HOOKS_ACCEPT_H_
#define _HOOKS_ACCEPT_H_

#include "constants/offsets/network.h"

int __attribute__((always_inline)) read_sock_and_send_event(ctx_t * ctx, struct sock * sock) {
if(sock == NULL) {
return 0;
}

struct accept_event_t event = {0};

// Extract family from the socket
struct sock_common *sockcommon = (void *)sock;
event.family = get_family_from_sock_common(sockcommon);
// Only handle AF_INET and AF_INET6
if (event.family != AF_INET && event.family != AF_INET6) {
return 0;
}

// Read the listening port and source address
bpf_probe_read(&event.port, sizeof(event.port), &sockcommon->skc_num);
event.port = htons(event.port);

if (event.family == AF_INET) {
bpf_probe_read(&event.addr[0], sizeof(event.addr[0]), &sockcommon->skc_daddr);
} else if (event.family == AF_INET6) {
bpf_probe_read((void*)&event.addr, sizeof(sockcommon->skc_v6_daddr), &sockcommon->skc_v6_daddr);
}

struct proc_cache_t *entry = fill_process_context(&event.process);
fill_container_context(entry, &event.container);
fill_span_context(&event.span);
send_event(ctx, EVENT_ACCEPT, event);

return 0;
}

HOOK_EXIT("inet_csk_accept")
int hook_accept(ctx_t *ctx) {
struct sock *sock = (struct sock*)CTX_PARMRET(ctx);
return read_sock_and_send_event(ctx, sock);
}

#endif /* _HOOKS_ACCEPT_H_ */
6 changes: 6 additions & 0 deletions pkg/security/ebpf/c/include/structs/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,12 @@ struct syscall_cache_t {
u16 protocol;
} connect;

struct {
u64 addr[2];
u16 family;
u16 port;
} accept;

struct {
struct dentry *dentry;
struct path *path;
Expand Down
Loading

0 comments on commit 2c0aedb

Please sign in to comment.