Skip to content

Commit

Permalink
Make default pid to be -1 and remove unsafe code
Browse files Browse the repository at this point in the history
  • Loading branch information
vlabo committed Jun 23, 2023
1 parent daeafa4 commit 74b4ce0
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 20 deletions.
27 changes: 18 additions & 9 deletions firewall/interception/ebpf/bandwidth/interface.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package ebpf

import (
"encoding/binary"
"fmt"
"net"
"path/filepath"
"syscall"
"time"
"unsafe"

"github.com/cilium/ebpf"
"github.com/cilium/ebpf/link"
"github.com/cilium/ebpf/rlimit"
"github.com/safing/portbase/log"
"github.com/safing/portmaster/network/packet"
"golang.org/x/sys/unix"
)

Expand All @@ -28,6 +28,7 @@ var ebpfInterface = struct {
objs: bpfObjects{},
}

// SetupBandwidthInterface initializes the ebpf interface and starts gattering bandwidth information for all connections.
func SetupBandwidthInterface() error {

// Allow the current process to lock memory for eBPF resources.
Expand Down Expand Up @@ -141,6 +142,7 @@ func ShutdownBandwithInterface() {
ebpfInterface.objs.Close()
}

// findCgroupPath returns the default unified path of the cgroup
func findCgroupPath() (string, error) {
cgroupPath := "/sys/fs/cgroup"

Expand All @@ -156,24 +158,31 @@ func findCgroupPath() (string, error) {
return cgroupPath, nil
}

// printBandwidthData prints the contencs of the shared map in the ebpf program.
func printBandwidthData() {
iter := ebpfInterface.objs.bpfMaps.PmBandwidthMap.Iterate()
var skKey bpfSkKey
var skInfo bpfSkInfo
for iter.Next(&skKey, &skInfo) {
log.Debugf("Connection: %d %s:%d %s:%d %d %d", skKey.Protocol,
arrayToIP(skKey.SrcIp, skKey.Ipv6).String(), skKey.SrcPort,
arrayToIP(skKey.DstIp, skKey.Ipv6).String(), skKey.DstPort,
convertArrayToIPv4(skKey.SrcIp, packet.IPVersion(skKey.Ipv6)).String(), skKey.SrcPort,
convertArrayToIPv4(skKey.DstIp, packet.IPVersion(skKey.Ipv6)).String(), skKey.DstPort,
skInfo.Rx, skInfo.Tx,
)
}
}

// arrayToIP converts IP number array to net.IP
func arrayToIP(ipNum [4]uint32, ipv6 uint8) net.IP {
if ipv6 == 0 {
return unsafe.Slice((*byte)(unsafe.Pointer(&ipNum)), 4)
// convertArrayToIPv4 converts an array of uint32 values to an IPv4 net.IP address.
func convertArrayToIPv4(input [4]uint32, ipVersion packet.IPVersion) net.IP {
if ipVersion == packet.IPv4 {
addressBuf := make([]byte, 4)
binary.LittleEndian.PutUint32(addressBuf, input[0])
return net.IP(addressBuf)
} else {
return unsafe.Slice((*byte)(unsafe.Pointer(&ipNum)), 16)
addressBuf := make([]byte, 16)
for i := 0; i < 4; i++ {
binary.LittleEndian.PutUint32(addressBuf[i*4:i*4+4], input[i])
}
return net.IP(addressBuf)
}
}
40 changes: 29 additions & 11 deletions firewall/interception/ebpf/connection_listener/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"encoding/binary"
"errors"
"net"
"unsafe"

"github.com/cilium/ebpf/link"
"github.com/cilium/ebpf/ringbuf"
Expand All @@ -15,8 +14,10 @@ import (
)

//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang -cflags "-O2 -g -Wall -Werror" -type Event bpf ../programs/monitor.c

var stopper chan struct{}

// StartEBPFWorker starts the ebpf worker.
func StartEBPFWorker(ch chan packet.Packet) {
stopper = make(chan struct{})
go func() {
Expand All @@ -32,7 +33,7 @@ func StartEBPFWorker(ch chan packet.Packet) {
log.Errorf("ebpf: failed to load ebpf object: %s", err)
return
}
defer objs.Close()
defer objs.Close() //nolint:errcheck

// Create a link to the tcp_connect program.
linkTCPConnect, err := link.AttachTracing(link.TracingOptions{
Expand All @@ -42,7 +43,7 @@ func StartEBPFWorker(ch chan packet.Packet) {
log.Errorf("ebpf: failed to attach to tcp_v4_connect: %s ", err)
return
}
defer linkTCPConnect.Close()
defer linkTCPConnect.Close() //nolint:errcheck

// Create a link to the udp_v4_connect program.
linkUDPV4, err := link.AttachTracing(link.TracingOptions{
Expand All @@ -52,7 +53,7 @@ func StartEBPFWorker(ch chan packet.Packet) {
log.Errorf("ebpf: failed to attach to udp_v4_connect: %s ", err)
return
}
defer linkUDPV4.Close()
defer linkUDPV4.Close() //nolint:errcheck

// Create a link to the udp_v6_connect program.
linkUDPV6, err := link.AttachTracing(link.TracingOptions{
Expand All @@ -62,7 +63,7 @@ func StartEBPFWorker(ch chan packet.Packet) {
log.Errorf("ebpf: failed to attach to udp_v6_connect: %s ", err)
return
}
defer linkUDPV6.Close()
defer linkUDPV6.Close() //nolint:errcheck

rd, err := ringbuf.NewReader(objs.bpfMaps.PmConnectionEvents)
if err != nil {
Expand Down Expand Up @@ -105,8 +106,8 @@ func StartEBPFWorker(ch chan packet.Packet) {
Protocol: packet.IPProtocol(event.Protocol),
SrcPort: event.Sport,
DstPort: event.Dport,
Src: arrayToIP(event.Saddr, packet.IPVersion(event.IpVersion)),
Dst: arrayToIP(event.Daddr, packet.IPVersion(event.IpVersion)),
Src: convertArrayToIPv4(event.Saddr, packet.IPVersion(event.IpVersion)),
Dst: convertArrayToIPv4(event.Daddr, packet.IPVersion(event.IpVersion)),
PID: int(event.Pid),
}
if isEventValid(event) {
Expand All @@ -123,19 +124,30 @@ func StartEBPFWorker(ch chan packet.Packet) {
}()
}

// StopEBPFWorker stops the ebpf worker.
func StopEBPFWorker() {
close(stopper)
}

// isEventValid checks whether the given bpfEvent is valid or not.
// It returns true if the event is valid, otherwise false.
func isEventValid(event bpfEvent) bool {
// Check if the destination port is 0
if event.Dport == 0 {
return false
}

// Check if the source port is 0
if event.Sport == 0 {
return false
}

// Check if the process ID is 0
if event.Pid == 0 {
return false
}

// If the IP version is IPv4
if event.IpVersion == 4 {
if event.Saddr[0] == 0 {
return false
Expand All @@ -148,11 +160,17 @@ func isEventValid(event bpfEvent) bool {
return true
}

// arrayToIP converts IP number array to net.IP
func arrayToIP(ipNum [4]uint32, ipVersion packet.IPVersion) net.IP {
// convertArrayToIPv4 converts an array of uint32 values to an IPv4 net.IP address.
func convertArrayToIPv4(input [4]uint32, ipVersion packet.IPVersion) net.IP {
if ipVersion == packet.IPv4 {
return unsafe.Slice((*byte)(unsafe.Pointer(&ipNum)), 4)
addressBuf := make([]byte, 4)
binary.LittleEndian.PutUint32(addressBuf, input[0])
return net.IP(addressBuf)
} else {
return unsafe.Slice((*byte)(unsafe.Pointer(&ipNum)), 16)
addressBuf := make([]byte, 16)
for i := 0; i < 4; i++ {
binary.LittleEndian.PutUint32(addressBuf[i*4:i*4+4], input[i])
}
return net.IP(addressBuf)
}
}
1 change: 1 addition & 0 deletions process/find.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ func GetProcessByRequestOrigin(ar *api.Request) (*Process, error) {
Protocol: packet.TCP,
Src: remoteIP, // source as in the process we are looking for
SrcPort: remotePort, // source as in the process we are looking for
PID: -1,
}

pid, _, err := GetPidOfConnection(ar.Context(), pkt)
Expand Down

0 comments on commit 74b4ce0

Please sign in to comment.