tracee icon indicating copy to clipboard operation
tracee copied to clipboard

[BUG] Entire clsact qdisc is purged when tc hook is destroyed

Open rafaeldtinoco opened this issue 3 years ago • 3 comments
trafficstars

When refactoring network probes from https://github.com/aquasecurity/tracee/pull/1820 I have realized that we should better document clsact qdisc issue on tc probe destruction. I have documented the behavior observed in the current version to show that refactor is not changing the behavior.

Prerequisites

  • [x] This affects latest released version.
  • [x] This affects current development tree (origin/HEAD).
  • [x] There isn't an issue describing the bug.

It depends on https://lore.kernel.org/bpf/CAMy7=ZULTCoSCcjxw=MdhaKmNM9DXKc=t7QScf9smKKUB+L_fQ@mail.gmail.com/T/#t already observed by @yanivagman in a near past.

Bug description

  1. Entire clsact qdisc is purged when tc hook is destroyed: it might destroy existing filters (other eBPF programs) unrelated to tracee.
  2. eBPF TC detach does not work (destroy needs to be used)

This is how I'm executing tracee (cmdline):

$ sudo ./dist/tracee-ebpf -o format:json -o option:parse-arguments -o option:detect-syscall -trace comm=bash -trace follow -trace event=net_packet -trace net=docker0

This is the error I'm getting:

In the current version of tracee, we are deleting the qdisc clsact entirely when destroying our tc hook:

image

First there is no eBPF program attached to docker0 interface. I leave on purpose 2 eBPF programs attached to it. I execute tracee and, when tc hook is destroyed, it deletes all 4 eBPF programs (and not only the 2 that tracee has created) likely because it destroyed clsact qdisc.

Again, but showing qdiscs now:

image

The second picture is the same thing, but showed in tc filter level.

Steps to reproduce

Steps to reproduce the issue:

  1. Have any other eBPF program hooked into an interface clsact.
  2. Execute tracee to trace event=net_packet and hook to same network interface with net=<interface>
  3. Observe all clsact being purged (existing filters) once tracee exits.

Context

Relevant information about my setup:

  • Linux version: any
  • Linux kernel version: any
  • Tracee version (or commit id of your tree): 6499f067
  • LLVM version: any
  • Golang version: any

Additional Information (files, logs, etc)

The Tc detachment should also have worked. Example:

// detach detaches a tcProbe from a given Interface
func (p *tcProbe) detach() error {
	var err error

	if p.tcHook == nil {
		return fmt.Errorf("tcProbe isn't attached")
	}

	// tcOpts := bpf.TcOpts{}
	// err = p.tcHook.Query(&tcOpts)
	// if err != nil {
	// 	return err
	// }

	// err = p.tcHook.Detach(&tcOpts) -> Does not work
	// if err != nil {
	// 	return err
	// }

	if p.tcHook != nil {
		err = p.tcHook.Destroy()
		if err != nil {
			return err
		}
	}

	return err
}

rafaeldtinoco avatar Jun 15 '22 21:06 rafaeldtinoco

This is a known issue, but I'm afraid we don't have much to do in tracee now. Also see my comment here: https://github.com/aquasecurity/tracee/blob/main/pkg/ebpf/tracee.go#L1191

yanivagman avatar Jun 16 '22 06:06 yanivagman

@rafaeldtinoco is it still an open issue after #1820 ?

yanivagman avatar Jul 05 '22 15:07 yanivagman

Yep, we can't destroy the hook without flushing other qdiscs unfortunately. I think there will be work todo in upstream for that to be solved.

rafaeldtinoco avatar Jul 05 '22 16:07 rafaeldtinoco

This is already solved by the new network code AND https://github.com/aquasecurity/tracee/pull/2569

rafaeldtinoco avatar Jan 12 '23 22:01 rafaeldtinoco