Skip to content

Commit

Permalink
system/socket: Add ip_local_out alternative (elastic#22787)
Browse files Browse the repository at this point in the history
This commit adds a new function alternative, `__ip_local_out` for selecting
a proper ip_local_out function, and fixes `guess_ip_local_out` logic in
order to account for this new function.

The new order of precedence is:
- ip_local_out_sk (kernels before 3.16)
- __ip_local_out (for kernels where ip_local_out calls are inlined)
- ip_local_out (all others).

Relates elastic#18755
  • Loading branch information
adriansr authored Dec 2, 2020
1 parent e58fe59 commit b627fb7
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 7 deletions.
21 changes: 15 additions & 6 deletions x-pack/auditbeat/module/system/socket/guess/iplocalout.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,22 @@ import (
"github.com/elastic/beats/v7/x-pack/auditbeat/tracing"
)

// Guess how to get a struct sock* from an ip_local_out() call.
// Guess how to get a struct sock* and an sk_buff* from an ip_local_out() call.
// This function has three forms depending on kernel version:
// - ip_local_out(struct sk_buff *skb) // 2.x//<3.13
// - ip_local_out_sk(struct sock *sk, struct sk_buff *skb) // 3.13..4.3
// - ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb) // 4.4+
//
// what it does is set a probe on tcp_sendmsg (guaranteed to have a *sock)
// and in ip_local_out, which will be called by tcp_sendmsg.
// To make things more complicated, in some 5.x+ kernels, ip_local_out is never
// triggered although it exists, but __ip_local_out always works, so
// this guess expects the template variable IP_LOCAL_OUT to be set to the
// first of these functions that is available for tracing:
// [ "ip_local_out_sk", "__ip_local_out", "ip_local_out" ]
//
// ----
//
// What it guess does is set a probe on tcp_sendmsg (guaranteed to have a *sock)
// and in .IP_LOCAL_OUT, which will be called by tcp_sendmsg.
// It dumps the first param (which can be a struct net* or a struct sk_buff)
// and gets the second param. Either the second param is the sock, or is it
// found at some point in the dumped first param.
Expand Down Expand Up @@ -98,8 +106,8 @@ func (g *guessIPLocalOut) Probes() ([]helper.ProbeDef, error) {
Probe: tracing.Probe{
Name: "ip_local_out_sock_guess",
Address: "{{.IP_LOCAL_OUT}}",
Fetchargs: "arg={{if eq .IP_LOCAL_OUT \"ip_local_out\"}}{{.P2}}{{else}}{{.P1}}{{end}} dump=" +
helper.MakeMemoryDump("{{if eq .IP_LOCAL_OUT \"ip_local_out\"}}{{.P1}}{{else}}{{.P2}}{{end}}", 0, skbuffDumpSize),
Fetchargs: "arg={{if ne .IP_LOCAL_OUT \"ip_local_out_sk\"}}{{.P2}}{{else}}{{.P1}}{{end}} dump=" +
helper.MakeMemoryDump("{{if ne .IP_LOCAL_OUT \"ip_local_out_sk\"}}{{.P1}}{{else}}{{.P2}}{{end}}", 0, skbuffDumpSize),
},
Decoder: helper.NewStructDecoder(func() interface{} { return new(skbuffSockGuess) }),
},
Expand Down Expand Up @@ -149,7 +157,8 @@ func (g *guessIPLocalOut) Extract(ev interface{}) (common.MapStr, bool) {
// No tcp_sendmsg received?
return nil, false
}
isIpLocalOut := g.ctx.Vars["IP_LOCAL_OUT"] == "ip_local_out"
// Special handling for ip_local_out_sk
isIpLocalOut := g.ctx.Vars["IP_LOCAL_OUT"] != "ip_local_out_sk"
if v.Arg == g.sock {
if isIpLocalOut {
return common.MapStr{
Expand Down
2 changes: 1 addition & 1 deletion x-pack/auditbeat/module/system/socket/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var baseTemplateVars = common.MapStr{
// These functions names vary between kernel versions. The first available one
// will be selected during setup.
var functionAlternatives = map[string][]string{
"IP_LOCAL_OUT": {"ip_local_out", "ip_local_out_sk"},
"IP_LOCAL_OUT": {"ip_local_out_sk", "__ip_local_out", "ip_local_out"},
"RECV_UDP_DATAGRAM": {"__skb_recv_udp", "__skb_recv_datagram", "skb_recv_datagram"},
"SYS_EXECVE": syscallAlternatives("execve"),
"SYS_GETTIMEOFDAY": syscallAlternatives("gettimeofday"),
Expand Down

0 comments on commit b627fb7

Please sign in to comment.