Skip to content

Commit cac3ca4

Browse files
authored
Events: tty_write: properly filter non-echo mode (#147)
1 parent 4a57e91 commit cac3ca4

File tree

8 files changed

+22
-79
lines changed

8 files changed

+22
-79
lines changed

GPL/Events/EbpfEventProto.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,7 @@ struct ebpf_process_tty_write_event {
161161
struct ebpf_tty_dev ctty;
162162
// Destination TTY.
163163
struct ebpf_tty_dev tty;
164-
// The function is not called from
165-
// the syscall but from the driver.
166-
// If driver is true, events can be dropped
167-
// based on terminal flags.
168-
bool driver;
164+
char comm[TASK_COMM_LEN];
169165
} __attribute__((packed));
170166

171167
struct ebpf_process_setgid_event {

GPL/Events/Helpers.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ const volatile int consumer_pid = 0;
125125
#define PTY_TYPE_MASTER 0x0001
126126

127127
// From include/uapi/asm-generic/termbits.h
128-
#define ICANON 0x00002
129128
#define ECHO 0x00008
130129

131130
static bool IS_ERR_OR_NULL(const void *ptr)

GPL/Events/Process/Probe.bpf.c

Lines changed: 18 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
#include "Helpers.h"
1717
#include "PathResolver.h"
18-
#include "State.h"
1918

2019
/* tty_write */
2120
DECL_FUNC_ARG(redirected_tty_write, iter);
@@ -244,19 +243,16 @@ int BPF_KPROBE(kprobe__commit_creds, struct cred *new)
244243

245244
static int tty_write__enter(const char *buf, ssize_t count, struct file *f)
246245
{
247-
bool driver = false;
248-
struct ebpf_events_state *state = ebpf_events_state__get(EBPF_EVENTS_STATE_TTY_WRITE);
249-
if (state) {
250-
ebpf_events_state__del(EBPF_EVENTS_STATE_TTY_WRITE);
251-
driver = true;
252-
}
253-
254246
if (is_consumer())
255247
goto out;
256248

257249
if (count <= 0)
258250
goto out;
259251

252+
struct ebpf_process_tty_write_event *event = bpf_ringbuf_reserve(&ringbuf, sizeof(*event), 0);
253+
if (!event)
254+
goto out;
255+
260256
struct tty_file_private *tfp = (struct tty_file_private *)BPF_CORE_READ(f, private_data);
261257
struct tty_struct *tty = BPF_CORE_READ(tfp, tty);
262258

@@ -265,41 +261,43 @@ static int tty_write__enter(const char *buf, ssize_t count, struct file *f)
265261
// @link: link to another pty (master -> slave and vice versa)
266262
//
267263
// https://elixir.bootlin.com/linux/v5.19.9/source/drivers/tty/tty_io.c#L2643
264+
bool is_master = false;
265+
struct ebpf_tty_dev master = {};
268266
if (BPF_CORE_READ(tty, driver, type) == TTY_DRIVER_TYPE_PTY &&
269267
BPF_CORE_READ(tty, driver, subtype) == PTY_TYPE_MASTER) {
270-
tty = BPF_CORE_READ(tty, link);
268+
struct tty_struct *tmp = BPF_CORE_READ(tty, link);
269+
ebpf_tty_dev__fill(&master, tty);
270+
ebpf_tty_dev__fill(&event->tty, tmp);
271+
is_master = true;
272+
} else {
273+
ebpf_tty_dev__fill(&event->tty, tty);
271274
}
272275

273-
struct ebpf_process_tty_write_event *event = bpf_ringbuf_reserve(&ringbuf, sizeof(*event), 0);
274-
if (!event)
275-
goto out;
276-
277276
event->hdr.type = EBPF_EVENT_PROCESS_TTY_WRITE;
278277
event->hdr.ts = bpf_ktime_get_ns();
279278

280279
u64 len = count > TTY_OUT_MAX ? TTY_OUT_MAX : count;
281280
event->tty_out_len = len;
282281
event->tty_out_truncated = count > TTY_OUT_MAX ? count - TTY_OUT_MAX : 0;
283-
event->driver = driver;
284282

285283
const struct task_struct *task = (struct task_struct *)bpf_get_current_task();
286284
ebpf_pid_info__fill(&event->pids, task);
287285
ebpf_ctty__fill(&event->ctty, task);
288-
ebpf_tty_dev__fill(&event->tty, tty);
286+
bpf_get_current_comm(event->comm, TASK_COMM_LEN);
289287

290-
if (event->driver && (event->tty.termios.c_lflag & ICANON) &&
291-
!(event->tty.termios.c_lflag & ECHO)) {
288+
if (event->tty.major == 0 && event->tty.minor == 0) {
292289
bpf_ringbuf_discard(event, 0);
293290
goto out;
294291
}
295292

296-
if (event->tty.major == 0 && event->tty.minor == 0) {
293+
if (bpf_probe_read_user(event->tty_out, len, (void *)buf)) {
294+
bpf_printk("tty_write__enter: error reading buf\n");
297295
bpf_ringbuf_discard(event, 0);
298296
goto out;
299297
}
300298

301-
if (bpf_probe_read_user(event->tty_out, len, (void *)buf)) {
302-
bpf_printk("tty_write__enter: error reading buf\n");
299+
if ((is_master && !(master.termios.c_lflag & ECHO)) && !(event->tty.termios.c_lflag & ECHO)) {
300+
bpf_printk("tty_write__enter: discarding %s\n", event->tty_out);
303301
bpf_ringbuf_discard(event, 0);
304302
goto out;
305303
}
@@ -370,22 +368,3 @@ int BPF_KPROBE(kprobe__tty_write)
370368
out:
371369
return 0;
372370
}
373-
374-
static int n_tty_write__enter()
375-
{
376-
struct ebpf_events_state state = {.tty_write = {}};
377-
ebpf_events_state__set(EBPF_EVENTS_STATE_TTY_WRITE, &state);
378-
return 0;
379-
}
380-
381-
SEC("fentry/n_tty_write")
382-
int BPF_PROG(fentry__n_tty_write)
383-
{
384-
return n_tty_write__enter();
385-
}
386-
387-
SEC("kprobe/n_tty_write")
388-
int BPF_KPROBE(kprobe__n_tty_write)
389-
{
390-
return n_tty_write__enter();
391-
}

GPL/Events/State.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ enum ebpf_events_state_op {
1616
EBPF_EVENTS_STATE_RENAME = 2,
1717
EBPF_EVENTS_STATE_TCP_V4_CONNECT = 3,
1818
EBPF_EVENTS_STATE_TCP_V6_CONNECT = 4,
19-
EBPF_EVENTS_STATE_TTY_WRITE = 5,
2019
};
2120

2221
struct ebpf_events_key {
@@ -51,18 +50,12 @@ struct ebpf_events_tcp_connect_state {
5150
struct sock *sk;
5251
};
5352

54-
// Store nothing, this state will be used to filter by
55-
// execution context.
56-
struct ebpf_events_tty_write_state {
57-
};
58-
5953
struct ebpf_events_state {
6054
union {
6155
struct ebpf_events_unlink_state unlink;
6256
struct ebpf_events_rename_state rename;
6357
struct ebpf_events_tcp_connect_state tcp_v4_connect;
6458
struct ebpf_events_tcp_connect_state tcp_v6_connect;
65-
struct ebpf_events_tty_write_state tty_write;
6659
};
6760
};
6861

non-GPL/Events/EventsTrace/EventsTrace.c

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <sys/time.h>
1919

2020
#include <arpa/inet.h>
21+
#include <linux/termios.h>
2122
#include <netinet/in.h>
2223

2324
#include <EbpfEvents.h>
@@ -217,11 +218,6 @@ static void out_int(const char *name, const long value)
217218
printf("\"%s\":%ld", name, value);
218219
}
219220

220-
static void out_hex(const char *name, const unsigned int value)
221-
{
222-
printf("\"%s\":\"0x%x\"", name, value);
223-
}
224-
225221
static void out_bool(const char *name, const bool value)
226222
{
227223
printf("\"%s\":\"%s\"", name, value ? "TRUE" : "FALSE");
@@ -274,13 +270,7 @@ static void out_tty_dev(const char *name, struct ebpf_tty_dev *tty_dev)
274270
out_comma();
275271
out_int("winsize_cols", tty_dev->winsize.cols);
276272
out_comma();
277-
out_hex("termios_c_iflag", tty_dev->termios.c_iflag);
278-
out_comma();
279-
out_hex("termios_c_oflag", tty_dev->termios.c_oflag);
280-
out_comma();
281-
out_hex("termios_c_lflag", tty_dev->termios.c_lflag);
282-
out_comma();
283-
out_hex("termios_c_cflag", tty_dev->termios.c_cflag);
273+
out_bool("ECHO", tty_dev->termios.c_lflag & ECHO);
284274

285275
out_object_end();
286276
}
@@ -513,13 +503,11 @@ static void out_process_tty_write(struct ebpf_process_tty_write_event *evt)
513503
out_comma();
514504
out_uint("tty_out_truncated", evt->tty_out_truncated);
515505
out_comma();
516-
out_tty_dev("ctty", &evt->ctty);
517-
out_comma();
518506
out_tty_dev("tty", &evt->tty);
519507
out_comma();
520508
out_string("tty_out", evt->tty_out);
521509
out_comma();
522-
out_bool("driver", evt->driver);
510+
out_string("comm", (const char *)&evt->comm);
523511

524512
out_object_end();
525513
out_newline();

non-GPL/Events/Lib/EbpfEvents.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,12 +248,6 @@ static inline int probe_set_autoload(struct btf *btf, struct EventProbe_bpf *obj
248248
err = err ?: bpf_program__set_autoload(obj->progs.fentry__tty_write, false);
249249
}
250250

251-
if (has_bpf_tramp && BTF_FUNC_EXISTS(btf, n_tty_write)) {
252-
err = err ?: bpf_program__set_autoload(obj->progs.kprobe__n_tty_write, false);
253-
} else {
254-
err = err ?: bpf_program__set_autoload(obj->progs.fentry__n_tty_write, false);
255-
}
256-
257251
// bpf trampolines are only implemented for x86. disable auto-loading of all
258252
// fentry/fexit progs if EBPF_FEATURE_BPF_TRAMP is not in `features` and
259253
// enable the k[ret]probe counterpart.

testing/testrunner/tests.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -381,11 +381,6 @@ func TestTtyWrite(et *EventsTraceInstance) {
381381
AssertInt64Equal(ev.TtyDev.Major, 4)
382382
AssertInt64Equal(ev.TtyDev.WinsizeRows, 0)
383383
AssertInt64Equal(ev.TtyDev.WinsizeCols, 0)
384-
AssertTrue(ev.TtyDev.Termios_C_Iflag != "")
385-
AssertTrue(ev.TtyDev.Termios_C_Oflag != "")
386-
AssertTrue(ev.TtyDev.Termios_C_Lflag != "")
387-
AssertTrue(ev.TtyDev.Termios_C_Cflag != "")
388-
AssertStringsEqual(ev.Driver, "FALSE")
389384
}
390385

391386
func TestTcpv4ConnectionAttempt(et *EventsTraceInstance) {

testing/testrunner/utils.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ type TtyWriteEvent struct {
133133
Truncated int64 `json:"tty_out_truncated"`
134134
Out string `json:"tty_out"`
135135
TtyDev ttyDevInfo `json:"tty"`
136-
Driver string `json:"driver"`
137136
}
138137

139138
type NetConnAttemptEvent struct {

0 commit comments

Comments
 (0)