mirror of
https://github.com/kubeshark/kubeshark.git
synced 2025-08-05 10:41:36 +00:00
* Determine the Go ABI and get `goid` offset from DWARF
* Add `ABI` enum and morph the function according to the detected ABI
* Pass `goid` offset to an eBPF map to retrieve it in eBPF context
* Add `vmlinux.h` and implement `get_goid_from_thread_local_storage`
* Fix BPF verifier errors
* Update the comments
* Add `go_abi_0.h` and implement `ABI0` specific reads for `arm64`
* Upgrade `github.com/cilium/ebpf` to `v0.9.0`
* Add a comment
* Add macros for x86 specific parts
* Update `x86.o`
* Fix the map key type
* Add `user_pt_regs`
* Update arm64 object file
* Fix the version detection logic
* Add `getGStructOffset` method
* Define `goid_offsets`, `goid_offsets_map` structs and pass the offsets correctly
* Fix the `net.TCPConn` and buffer addresses for `ABI0`
* Remove comment
* Fix the issues for arm64 build
* Update x86.o
* Revert "Fix the issues for arm64 build"
This reverts commit 48b041b1b6
.
* Revert `user_pt_regs`
* Add `vmlinux` directory
* Fix the `build.sh` and `Dockerfile`
* Add vmlinux_arm64.h
* Disable `get_goid_from_thread_local_storage` on ARM64 with a macro
* Update x86.o
* Update arm64.o
* x86
* arm64
* Fix the cross-compilation issue from x86 to arm64
* Fix the same thing for x86
* Use `BPF_CORE_READ` macro instead of `bpf_ringbuf_reserve` to support kernel versions older than 5.8
Also;
Add legacy version of thread_struct: thread_struct___v46
Build an additional object file for the kernel versions older than or equal to 4.6 and load them accordingly.
Add github.com/moby/moby
* Make #define directives more definitive
* Select the x86 and arm64 versions of `vmlinux.h` using macros
* Put `goid` offsets into the map before installing `uprobe`(s)
* arm64
* #run_acceptance_tests
* Remove a forgotten `fmt.Printf`
* Log the detected Linux kernel version
129 lines
3.1 KiB
Go
129 lines
3.1 KiB
Go
package tlstapper
|
|
|
|
import (
|
|
"github.com/cilium/ebpf/link"
|
|
"github.com/go-errors/errors"
|
|
)
|
|
|
|
type goHooks struct {
|
|
goWriteProbe link.Link
|
|
goWriteExProbes []link.Link
|
|
goReadProbe link.Link
|
|
goReadExProbes []link.Link
|
|
}
|
|
|
|
func (s *goHooks) installUprobes(bpfObjects *tlsTapperObjects, filePath string) error {
|
|
ex, err := link.OpenExecutable(filePath)
|
|
|
|
if err != nil {
|
|
return errors.Wrap(err, 0)
|
|
}
|
|
|
|
offsets, err := findGoOffsets(filePath)
|
|
|
|
if err != nil {
|
|
return errors.Wrap(err, 0)
|
|
}
|
|
|
|
return s.installHooks(bpfObjects, ex, offsets)
|
|
}
|
|
|
|
func (s *goHooks) installHooks(bpfObjects *tlsTapperObjects, ex *link.Executable, offsets goOffsets) error {
|
|
var err error
|
|
|
|
goCryptoTlsWrite := bpfObjects.GoCryptoTlsAbiInternalWrite
|
|
goCryptoTlsWriteEx := bpfObjects.GoCryptoTlsAbiInternalWriteEx
|
|
goCryptoTlsRead := bpfObjects.GoCryptoTlsAbiInternalRead
|
|
goCryptoTlsReadEx := bpfObjects.GoCryptoTlsAbiInternalReadEx
|
|
|
|
if offsets.Abi == ABI0 {
|
|
goCryptoTlsWrite = bpfObjects.GoCryptoTlsAbi0Write
|
|
goCryptoTlsWriteEx = bpfObjects.GoCryptoTlsAbi0WriteEx
|
|
goCryptoTlsRead = bpfObjects.GoCryptoTlsAbi0Read
|
|
goCryptoTlsReadEx = bpfObjects.GoCryptoTlsAbi0ReadEx
|
|
|
|
// Pass goid and g struct offsets to an eBPF map to retrieve it in eBPF context
|
|
if err := bpfObjects.tlsTapperMaps.GoidOffsetsMap.Put(
|
|
uint32(0),
|
|
tlsTapperGoidOffsets{
|
|
G_addrOffset: offsets.GStructOffset,
|
|
GoidOffset: offsets.GoidOffset,
|
|
},
|
|
); err != nil {
|
|
return errors.Wrap(err, 0)
|
|
}
|
|
}
|
|
|
|
// Symbol points to
|
|
// [`crypto/tls.(*Conn).Write`](https://github.com/golang/go/blob/go1.17.6/src/crypto/tls/conn.go#L1099)
|
|
s.goWriteProbe, err = ex.Uprobe(goWriteSymbol, goCryptoTlsWrite, &link.UprobeOptions{
|
|
Offset: offsets.GoWriteOffset.enter,
|
|
})
|
|
|
|
if err != nil {
|
|
return errors.Wrap(err, 0)
|
|
}
|
|
|
|
for _, offset := range offsets.GoWriteOffset.exits {
|
|
probe, err := ex.Uprobe(goWriteSymbol, goCryptoTlsWriteEx, &link.UprobeOptions{
|
|
Offset: offset,
|
|
})
|
|
|
|
if err != nil {
|
|
return errors.Wrap(err, 0)
|
|
}
|
|
|
|
s.goWriteExProbes = append(s.goWriteExProbes, probe)
|
|
}
|
|
|
|
// Symbol points to
|
|
// [`crypto/tls.(*Conn).Read`](https://github.com/golang/go/blob/go1.17.6/src/crypto/tls/conn.go#L1263)
|
|
s.goReadProbe, err = ex.Uprobe(goReadSymbol, goCryptoTlsRead, &link.UprobeOptions{
|
|
Offset: offsets.GoReadOffset.enter,
|
|
})
|
|
|
|
if err != nil {
|
|
return errors.Wrap(err, 0)
|
|
}
|
|
|
|
for _, offset := range offsets.GoReadOffset.exits {
|
|
probe, err := ex.Uprobe(goReadSymbol, goCryptoTlsReadEx, &link.UprobeOptions{
|
|
Offset: offset,
|
|
})
|
|
|
|
if err != nil {
|
|
return errors.Wrap(err, 0)
|
|
}
|
|
|
|
s.goReadExProbes = append(s.goReadExProbes, probe)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *goHooks) close() []error {
|
|
errors := make([]error, 0)
|
|
|
|
if err := s.goWriteProbe.Close(); err != nil {
|
|
errors = append(errors, err)
|
|
}
|
|
|
|
for _, probe := range s.goWriteExProbes {
|
|
if err := probe.Close(); err != nil {
|
|
errors = append(errors, err)
|
|
}
|
|
}
|
|
|
|
if err := s.goReadProbe.Close(); err != nil {
|
|
errors = append(errors, err)
|
|
}
|
|
|
|
for _, probe := range s.goReadExProbes {
|
|
if err := probe.Close(); err != nil {
|
|
errors = append(errors, err)
|
|
}
|
|
}
|
|
|
|
return errors
|
|
}
|