mirror of
https://github.com/gravitational/teleport.git
synced 2026-08-28 21:12:20 +08:00
support disk events on Linux kernel 7.0+ by conditionally hooking do_file_open (#67650)
* support disk events on Linux kernel 7.0+ by conditionally hooking do_file_open * default to do_file_open
This commit is contained in:
@@ -114,12 +114,12 @@ int BPF_PROG(security_file_open, struct file *f)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// do_filp_open is called for all file open syscalls, but we aren't
|
||||
// do_file_open is called for all file open syscalls, but we aren't
|
||||
// able to get a resolved path here. If opening failed early,
|
||||
// security_file_open will not be called so we fall back to using the
|
||||
// unresolved path in the emitted event.
|
||||
SEC("fexit/do_filp_open")
|
||||
int BPF_PROG(do_filp_open_exit, int dfd, struct filename *pathname, const struct open_flags *op, struct file *ret)
|
||||
SEC("fexit/do_file_open")
|
||||
int BPF_PROG(do_file_open_exit, int dfd, struct filename *pathname, const struct open_flags *op, struct file *ret)
|
||||
{
|
||||
struct task_struct *task = bpf_get_current_task_btf();
|
||||
u32 session_id = task->sessionid;
|
||||
|
||||
+50
-3
@@ -22,10 +22,12 @@ package bpf
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/cilium/ebpf"
|
||||
"github.com/cilium/ebpf/btf"
|
||||
"github.com/cilium/ebpf/link"
|
||||
"github.com/cilium/ebpf/ringbuf"
|
||||
"github.com/cilium/ebpf/rlimit"
|
||||
@@ -36,6 +38,11 @@ import (
|
||||
"github.com/gravitational/teleport/lib/observability/metrics"
|
||||
)
|
||||
|
||||
const (
|
||||
doFilpOpenName = "do_filp_open"
|
||||
doFileOpenName = "do_file_open"
|
||||
)
|
||||
|
||||
var lostDiskEvents = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: teleport.MetricLostDiskEvents,
|
||||
@@ -71,9 +78,28 @@ func startOpen(bufferSize int) (*open, error) {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
// The disk eBPF program hooks do_file_open by default, which was
|
||||
// renamed from do_filp_open in 7.0. Check if do_file_open is available
|
||||
// and use do_filp_open otherwise; don't rely on the kernel version.
|
||||
attachTarget, err := findOpenAttachTarget()
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
var objs diskObjects
|
||||
if err := loadDiskObjects(&objs, nil); err != nil {
|
||||
return nil, trace.Wrap(err, "loading disk objects: %v", err)
|
||||
spec, err := loadDisk()
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "reading disk objects")
|
||||
}
|
||||
|
||||
p, ok := spec.Programs["do_file_open_exit"]
|
||||
if !ok {
|
||||
return nil, trace.NotFound("do_file_open_exit not found in disk objects")
|
||||
}
|
||||
p.AttachTo = attachTarget
|
||||
|
||||
if err := spec.LoadAndAssign(&objs, nil); err != nil {
|
||||
return nil, trace.Wrap(err, "loading disk objects")
|
||||
}
|
||||
|
||||
lostCtr, err := NewCounter(objs.LostCounter, objs.LostDoorbell, lostDiskEvents)
|
||||
@@ -91,7 +117,7 @@ func startOpen(bufferSize int) (*open, error) {
|
||||
attachType: ebpf.AttachTraceFEntry,
|
||||
},
|
||||
{
|
||||
prog: objs.DoFilpOpenExit,
|
||||
prog: objs.DoFileOpenExit,
|
||||
attachType: ebpf.AttachTraceFExit,
|
||||
},
|
||||
}
|
||||
@@ -124,6 +150,27 @@ func startOpen(bufferSize int) (*open, error) {
|
||||
return o, nil
|
||||
}
|
||||
|
||||
func findOpenAttachTarget() (string, error) {
|
||||
kspec, err := btf.LoadKernelSpec()
|
||||
if err != nil {
|
||||
return "", trace.Wrap(err, "loading kernel BTF spec")
|
||||
}
|
||||
|
||||
for _, target := range []string{doFileOpenName, doFilpOpenName} {
|
||||
var fn *btf.Func
|
||||
if err := kspec.TypeByName(target, &fn); err != nil {
|
||||
if errors.Is(err, btf.ErrNotFound) {
|
||||
continue
|
||||
}
|
||||
return "", trace.Wrap(err, "finding %s", target)
|
||||
}
|
||||
|
||||
return target, nil
|
||||
}
|
||||
|
||||
return "", trace.NotFound("do_file_open and do_filp_open not found in kernel BTF spec")
|
||||
}
|
||||
|
||||
func (o *open) startSession(auditSessionID uint32) error {
|
||||
o.mtx.Lock()
|
||||
defer o.mtx.Unlock()
|
||||
|
||||
@@ -67,7 +67,7 @@ type diskSpecs struct {
|
||||
//
|
||||
// It can be passed ebpf.CollectionSpec.Assign.
|
||||
type diskProgramSpecs struct {
|
||||
DoFilpOpenExit *ebpf.ProgramSpec `ebpf:"do_filp_open_exit"`
|
||||
DoFileOpenExit *ebpf.ProgramSpec `ebpf:"do_file_open_exit"`
|
||||
SecurityFileOpen *ebpf.ProgramSpec `ebpf:"security_file_open"`
|
||||
}
|
||||
|
||||
@@ -137,13 +137,13 @@ type diskVariables struct {
|
||||
//
|
||||
// It can be passed to loadDiskObjects or ebpf.CollectionSpec.LoadAndAssign.
|
||||
type diskPrograms struct {
|
||||
DoFilpOpenExit *ebpf.Program `ebpf:"do_filp_open_exit"`
|
||||
DoFileOpenExit *ebpf.Program `ebpf:"do_file_open_exit"`
|
||||
SecurityFileOpen *ebpf.Program `ebpf:"security_file_open"`
|
||||
}
|
||||
|
||||
func (p *diskPrograms) Close() error {
|
||||
return _DiskClose(
|
||||
p.DoFilpOpenExit,
|
||||
p.DoFileOpenExit,
|
||||
p.SecurityFileOpen,
|
||||
)
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -67,7 +67,7 @@ type diskSpecs struct {
|
||||
//
|
||||
// It can be passed ebpf.CollectionSpec.Assign.
|
||||
type diskProgramSpecs struct {
|
||||
DoFilpOpenExit *ebpf.ProgramSpec `ebpf:"do_filp_open_exit"`
|
||||
DoFileOpenExit *ebpf.ProgramSpec `ebpf:"do_file_open_exit"`
|
||||
SecurityFileOpen *ebpf.ProgramSpec `ebpf:"security_file_open"`
|
||||
}
|
||||
|
||||
@@ -137,13 +137,13 @@ type diskVariables struct {
|
||||
//
|
||||
// It can be passed to loadDiskObjects or ebpf.CollectionSpec.LoadAndAssign.
|
||||
type diskPrograms struct {
|
||||
DoFilpOpenExit *ebpf.Program `ebpf:"do_filp_open_exit"`
|
||||
DoFileOpenExit *ebpf.Program `ebpf:"do_file_open_exit"`
|
||||
SecurityFileOpen *ebpf.Program `ebpf:"security_file_open"`
|
||||
}
|
||||
|
||||
func (p *diskPrograms) Close() error {
|
||||
return _DiskClose(
|
||||
p.DoFilpOpenExit,
|
||||
p.DoFileOpenExit,
|
||||
p.SecurityFileOpen,
|
||||
)
|
||||
}
|
||||
|
||||
Binary file not shown.
+1
-2
@@ -1343,7 +1343,6 @@ func runCommand(t *testing.T, srv Server, bpfSrv bpf.BPF, command string, expect
|
||||
scx.execRequest.SetCommand(command)
|
||||
|
||||
clientChan, serverChan := newMockSSHChannel(t)
|
||||
clientChan.Drain()
|
||||
|
||||
t.Logf("running %q", command)
|
||||
|
||||
@@ -1399,7 +1398,7 @@ func runCommand(t *testing.T, srv Server, bpfSrv bpf.BPF, command string, expect
|
||||
|
||||
stdout := make([]byte, 1024)
|
||||
for {
|
||||
_, err := serverChan.Read(stdout)
|
||||
_, err := clientChan.Read(stdout)
|
||||
if err != nil {
|
||||
if errors.Is(err, io.EOF) {
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user