Skip to content

Commit

Permalink
bpf: fix verification error in bpf_execve_event
Browse files Browse the repository at this point in the history
This patch fixes a verification error in a 4.18.0-477.21.1.el8_8.x86_64
kernel.

The error was reported in issue 1442.

The patch simplifies the code: it eliminates a common expression, and it
changes some values from int to long to avoid generated code for the
implicit casting.

It also fixes a issue. bpf_probe_read_str may return 0, and in this case
the old code will underflow. And even though we mask the size, the size
value would have been wrong in this case:
(gdb) printf "0x%zx\n", (0-1) & 0x7fff
0x7fff

Signed-off-by: Kornilios Kourtis <[email protected]>
  • Loading branch information
kkourt committed Sep 12, 2023
1 parent 8d27aec commit a7205fc
Showing 1 changed file with 17 additions and 16 deletions.
33 changes: 17 additions & 16 deletions bpf/process/data_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static inline __attribute__((always_inline)) long
__do_str(void *ctx, struct msg_data *msg, unsigned long arg, bool *done)
{
size_t size, max = sizeof(msg->arg) - 1;
int err;
long ret;

/* Code movement from clang forces us to inline bounds checks here */
asm volatile("%[max] &= 0x7fff;\n"
Expand All @@ -89,25 +89,25 @@ __do_str(void *ctx, struct msg_data *msg, unsigned long arg, bool *done)
: [max] "+r"(max)
:);

err = probe_read_str(&msg->arg[0], max, (char *)arg);
if (err < 0)
return err;
ret = probe_read_str(&msg->arg[0], max, (char *)arg);
if (ret < 0)
return ret;

*done = err != max;
*done = ret != max;
if (ret == 0)
return 0;
/* cut out the zero byte */
err -= 1;

msg->common.size = offsetof(struct msg_data, arg) + err;

size = err + offsetof(struct msg_data, arg);
ret -= 1;

size = ret + offsetof(struct msg_data, arg);
/* Code movement from clang forces us to inline bounds checks here */
asm volatile("%[size] &= 0x7fff;\n"
:
: [size] "+r"(size)
:);
msg->common.size = size;
perf_event_output(ctx, &tcpmon_map, BPF_F_CURRENT_CPU, msg, size);
return err;
return ret;
}

static inline __attribute__((always_inline)) long
Expand All @@ -116,15 +116,16 @@ do_str(void *ctx, struct msg_data *msg, unsigned long arg,
{
size_t rd_bytes = 0;
bool done = false;
int err, i;
long ret;
int i;

#define __CNT 2
#pragma unroll
for (i = 0; i < __CNT; i++) {
err = __do_str(ctx, msg, arg + rd_bytes, &done);
if (err < 0)
return err;
rd_bytes += err;
ret = __do_str(ctx, msg, arg + rd_bytes, &done);
if (ret < 0)
return ret;
rd_bytes += ret;
if (done)
break;
}
Expand Down

0 comments on commit a7205fc

Please sign in to comment.