Skip to content

Commit

Permalink
为syscall提供初步配置文件支持
Browse files Browse the repository at this point in the history
  • Loading branch information
SeeFlowerX committed Jan 23, 2024
1 parent d018719 commit 94838d0
Show file tree
Hide file tree
Showing 9 changed files with 224 additions and 24 deletions.
8 changes: 4 additions & 4 deletions cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,15 +285,15 @@ func persistentPreRunEFunc(command *cobra.Command, args []string) error {
}
}

// 2. hook syscall
mconfig.SysCallConf.Parse_SysWhitelist(gconfig)
mconfig.SysCallConf.Parse_SysBlacklist(gconfig.NoSysCall)

// 3. hook config
if len(gconfig.ConfigFiles) > 0 {
mconfig.LoadConfig(gconfig)
}

// 2. hook syscall
mconfig.SysCallConf.Parse_SysWhitelist(gconfig)
mconfig.SysCallConf.Parse_SysBlacklist(gconfig.NoSysCall)

// 4. watch breakpoint
var brk_base uint64 = 0x0
if gconfig.BrkLib != "" {
Expand Down
13 changes: 8 additions & 5 deletions tests/config_syscall_test.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
"name": "ioctl",
"params": [
{"name": "fd", "type": "int"},
{"name": "cmd", "type": "int"},
{"name": "arg", "type": "ptr", "filter": ["eq:0x801"]}
{"name": "cmd", "type": "ptr", "filter": ["eq:0xc0306201"]},
{"name": "arg", "type": "ptr"},
{"name": "ret", "type": "ptr"}
]
},
{
Expand All @@ -17,9 +18,10 @@
{"name": "sockfd", "type": "int"},
{"name": "buf", "type": "buf", "more":"enter", "size": "x2"},
{"name": "len", "type": "size_t"},
{"name": "flags", "type": "int", "format": "socket_flags"},
{"name": "flags", "type": "int", "format": "msg_flags"},
{"name": "addr", "type": "sockaddr"},
{"name": "addrlen", "type": "socklen_t"}
{"name": "addrlen", "type": "socklen_t"},
{"name": "ret", "type": "int"}
]
},
{
Expand All @@ -29,7 +31,8 @@
{"name": "sockfd", "type": "int"},
{"name": "buf", "type": "buf", "size": "x2", "more": "exit"},
{"name": "len", "type": "size_t"},
{"name": "flags", "type": "int", "format": "socket_flags"}
{"name": "flags", "type": "int", "format": "msg_flags"},
{"name": "ret", "type": "int"}
]
}
]
Expand Down
2 changes: 2 additions & 0 deletions user/argtype/argtype_base.go
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,8 @@ func init() {
Register(&ARG_STRUCT{}, "struct", TYPE_STRUCT, STRUCT, 0)
Register(&ARG_ARRAY{}, "array", TYPE_ARRAY, ARRAY, 0)

PreRegister()

RegisterAliasType(SOCKLEN_T, UINT32)
RegisterAliasType(SIZE_T, UINT64)
RegisterAliasType(SSIZE_T, INT64)
Expand Down
37 changes: 37 additions & 0 deletions user/argtype/argtype_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,30 @@ var SocketFlags []*FlagOp = []*FlagOp{
{"SOCK_NONBLOCK", int32(00004000)},
}

var MsgFlags []*FlagOp = []*FlagOp{
{"MSG_OOB", int32(1)},
{"MSG_PEEK", int32(2)},
{"MSG_DONTROUTE", int32(4)},
{"MSG_TRYHARD", int32(4)},
{"MSG_CTRUNC", int32(8)},
{"MSG_PROBE", int32(0x10)},
{"MSG_TRUNC", int32(0x20)},
{"MSG_DONTWAIT", int32(0x40)},
{"MSG_EOR", int32(0x80)},
{"MSG_WAITALL", int32(0x100)},
{"MSG_FIN", int32(0x200)},
{"MSG_SYN", int32(0x400)},
{"MSG_CONFIRM", int32(0x800)},
{"MSG_RST", int32(0x1000)},
{"MSG_ERRQUEUE", int32(0x2000)},
{"MSG_NOSIGNAL", int32(0x4000)},
{"MSG_MORE", int32(0x8000)},
{"MSG_WAITFORONE", int32(0x10000)},
{"MSG_BATCH", int32(0x40000)},
{"MSG_FASTOPEN", int32(0x20000000)},
{"MSG_CMSG_CLOEXEC", int32(0x40000000)},
}

var FcntlFlags []*FlagOp = []*FlagOp{
// {"AT_FDCWD", int32(-100)},
{"AT_SYMLINK_NOFOLLOW", int32(0x100)},
Expand Down Expand Up @@ -170,6 +194,7 @@ var FcntlFlagsConfig = &FlagsConfig{"stat", FORMAT_HEX, FcntlFlags}
var StatxFlagsConfig = &FlagsConfig{"statx", FORMAT_HEX, StatxFlags}
var UnlinkFlagsConfig = &FlagsConfig{"unlink", FORMAT_HEX, UnlinkFlags}
var MreapFlagsConfig = &FlagsConfig{"mreap", FORMAT_HEX, MreapFlags}
var MsgFlagsConfig = &FlagsConfig{"msg", FORMAT_HEX, MsgFlags}
var SocketFlagsConfig = &FlagsConfig{"socket", FORMAT_HEX, SocketFlags}
var PermissionFlagsConfig = &FlagsConfig{"permission", FORMAT_OCT, PermissionFlags}

Expand All @@ -185,6 +210,18 @@ func RegisterFlagsConfig(type_index, parent_index uint32, flags_config *FlagsCon
return new_p
}

func NewNumFlags(parent_index uint32, flags_config *FlagsConfig) IArgType {
p := GetArgType(parent_index)
new_name := fmt.Sprintf("%s_flags_%s", p.GetName(), flags_config.Name)
new_p := RegisterNew(new_name, p.GetTypeIndex())
new_i, ok := (new_p).(IArgTypeNum)
if !ok {
panic("...")
}
new_i.SetFlagsConfig(flags_config)
return new_p
}

func NewNumFormat(p IArgType, format_type uint32) IArgType {
new_name := fmt.Sprintf("%s_fmt_%d", p.GetName(), format_type)
new_p := RegisterNew(new_name, p.GetTypeIndex())
Expand Down
32 changes: 32 additions & 0 deletions user/argtype/iargtype.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,38 @@ func LazyRegister(type_index uint32) IArgType {
}
}

func PreRegister() {
// 先注册好各种内置类型
r_PRE_ARRAY(GetArgType(INT), INT_ARRAY_1, 1)
r_PRE_ARRAY(GetArgType(INT), INT_ARRAY_2, 2)
r_PRE_ARRAY(GetArgType(UINT), UINT_ARRAY_1, 1)
R_POINTER(GetArgType(INT), true)
R_POINTER(GetArgType(UINT), true)
r_STD_STRING()
r_STRING_ARRAY()
r_STACK_T()
PRE_R_STRUCT("timespec", TIMESPEC, &Arg_Timespec{})
r_SIGSET()
r_SIGINFO()
PRE_R_STRUCT("sigaction", SIGACTION, &Arg_Sigaction{})
r_EPOLLEVENT()
r_POLLFD()
r_DIRENT()
r_ITTMERSPEC()
r_RUSAGE()
r_UTSNAME()
r_TIMEVAL()
r_TIMEZONE()
r_SYSINFO()
r_STAT()
r_STATFS()
r_IOVEC()
r_IOVEC_X2()
r_MSGHDR()
r_SOCKADDR()
r_BUFFER_X2()
}

func Register(p IArgType, name string, base, index, size uint32) {
// 注册有预设的基础类型
if p == nil {
Expand Down
19 changes: 17 additions & 2 deletions user/config/config_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (this *FileConfig) GetType() string {
return this.Type
}

func (this *ParamConfig) GetPointArg(arg_index uint32) *PointArg {
func (this *ParamConfig) GetPointArg(arg_index, point_type uint32) *PointArg {
// 参数名省略时 以 a{index} 这样的形式作为名字
arg_name := fmt.Sprintf("a%d", arg_index)
if this.Name != "" {
Expand All @@ -55,7 +55,15 @@ func (this *ParamConfig) GetPointArg(arg_index uint32) *PointArg {
reg_index = GetRegIndex(this.Reg)
}
// 基础配置
point_arg := NewUprobePointArg(arg_name, POINTER, reg_index)
var point_arg *PointArg
switch point_type {
case EBPF_SYS_ENTER, EBPF_SYS_EXIT, EBPF_SYS_ALL:
point_arg = NewSyscallPointArg(arg_name, POINTER, reg_index, point_type)
case EBPF_UPROBE_ENTER:
point_arg = NewUprobePointArg(arg_name, POINTER, reg_index)
default:
panic("...")
}
// 先处理一些比较特殊的情况

to_ptr := false
Expand Down Expand Up @@ -121,6 +129,13 @@ func (this *ParamConfig) GetPointArg(arg_index uint32) *PointArg {
point_arg.SetHexFormat()
case "hexdump":
point_arg.SetHexFormat()
case "fcntl_flags", "statx_flags", "unlink_flags", "socket_flags", "perm_flags", "msg_flags":
point_arg.SetFlagsFormat(this.Format)
case "":
// 没设置就默认方式处理
break
default:
panic(fmt.Sprintf("unsupported format type:%s", this.Format))
}

// 设置过滤规则 先解析规则 然后取到规则索引
Expand Down
103 changes: 91 additions & 12 deletions user/config/config_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,27 +291,27 @@ func (this *StackUprobeConfig) GetSyscall() string {
}

func (this *StackUprobeConfig) Parse_FileConfig(config *UprobeFileConfig) (err error) {
for index, point := range config.Points {
for index, point_config := range config.Points {
hook_point := &UprobeArgs{}
hook_point.BindSyscall = false
hook_point.ExitRead = false
hook_point.Index = uint32(index)
hook_point.LibPath = this.LibPath
hook_point.RealFilePath = this.RealFilePath
hook_point.NonElfOffset = this.NonElfOffset
hook_point.Name = point.Name
if point.Signal != "" {
hook_point.KillSignal = util.ParseSignal(point.Signal)
hook_point.Name = point_config.Name
if point_config.Signal != "" {
hook_point.KillSignal = util.ParseSignal(point_config.Signal)
}

// strstr / strstr+0x4 / 0xA94E8
items := strings.Split(point.Name, "+")
items := strings.Split(point_config.Name, "+")
if len(items) == 1 {
sym_or_off := items[0]
if strings.HasPrefix(sym_or_off, "0x") {
offset, err := strconv.ParseUint(sym_or_off, 0, 64)
if err != nil {
return errors.New(fmt.Sprintf("parse for %s failed, err:%v", point.Name, err))
return errors.New(fmt.Sprintf("parse for %s failed, err:%v", point_config.Name, err))
}
hook_point.Offset = offset
hook_point.Symbol = ""
Expand All @@ -323,15 +323,15 @@ func (this *StackUprobeConfig) Parse_FileConfig(config *UprobeFileConfig) (err e
sym_or_off := items[1]
offset, err := strconv.ParseUint(sym_or_off, 0, 64)
if err != nil {
return errors.New(fmt.Sprintf("parse for %s failed, err:%v", point.Name, err))
return errors.New(fmt.Sprintf("parse for %s failed, err:%v", point_config.Name, err))
}
hook_point.Offset = offset
} else {
return errors.New(fmt.Sprintf("parse for %s failed, err:%v", point.Name, err))
return errors.New(fmt.Sprintf("parse for %s failed, err:%v", point_config.Name, err))
}

for arg_index, param := range point.Params {
point_arg := param.GetPointArg(uint32(arg_index))
for arg_index, param := range point_config.Params {
point_arg := param.GetPointArg(uint32(arg_index), EBPF_UPROBE_ENTER)
hook_point.PointArgs = append(hook_point.PointArgs, point_arg)
}
this.Points = append(this.Points, hook_point)
Expand Down Expand Up @@ -444,8 +444,59 @@ func (this *SyscallConfig) SetArgFilterRule(arg_filter *[]ArgFilter) {
this.arg_filter = arg_filter
}

func (this *SyscallConfig) GetSyscallPointByNR(nr uint32) *SyscallPoint {
// 后面加个 map 吧 总感觉这样会比较慢
for _, point_arg := range this.PointArgs {
if point_arg.Nr == nr {
return point_arg
}
}
panic(fmt.Sprintf("unknown nr:%d", nr))
}

func (this *SyscallConfig) Parse_FileConfig(config *SyscallFileConfig) (err error) {
for _, point_config := range config.Points {
var a_point_args []*PointArg
var b_point_args []*PointArg
for arg_index, param := range point_config.Params {
if param.Name == "ret" {
// 需要告知用户 syscall 中参数名 ret 仅用于返回值
point_arg := param.GetPointArg(uint32(arg_index), EBPF_SYS_EXIT)
b_point_args = append(b_point_args, point_arg)
break
}

var point_type uint32
switch param.More {
case "", "enter":
point_type = EBPF_SYS_ENTER
case "exit":
point_type = EBPF_SYS_EXIT
case "all":
point_type = EBPF_SYS_ALL
default:
panic(fmt.Sprintf("unknown point_type:%s", param.More))
}
point_arg := param.GetPointArg(uint32(arg_index), point_type)

a_p := point_arg.Clone()
a_p.SetGroupType(EBPF_SYS_ENTER)
a_point_args = append(a_point_args, a_p)

b_p := point_arg.Clone()
b_p.SetGroupType(EBPF_SYS_EXIT)
b_point_args = append(b_point_args, b_p)

}
point := &SyscallPoint{point_config.Nr, point_config.Name, a_point_args, b_point_args}
this.PointArgs = append(this.PointArgs, point)
}

return nil
}

func (this *SyscallConfig) Parse_SysWhitelist(gconfig *GlobalConfig) {
if gconfig.SysCall == "" {
if gconfig.SysCall == "" && len(gconfig.ConfigFiles) == 0 {
this.Enable = false
return
}
Expand Down Expand Up @@ -504,7 +555,9 @@ func (this *SyscallConfig) Parse_SysWhitelist(gconfig *GlobalConfig) {
case "%stat":
syscall_items = append(syscall_items, []string{"statfs", "fstatfs", "newfstatat", "fstat", "statx"}...)
default:
syscall_items = append(syscall_items, v)
if v != "" {
syscall_items = append(syscall_items, v)
}
}
}
// 去重
Expand All @@ -516,6 +569,28 @@ func (this *SyscallConfig) Parse_SysWhitelist(gconfig *GlobalConfig) {
}
}
}
if len(this.PointArgs) > 0 {
// 这个分支是配置文件走
if len(unique_items) == 0 {
// 命令行中不指定任何 syscall 那么会认为配置文件中的所有syscall都生效
// 这种是用户自定义syscall参数读取方式
for _, point_arg := range this.PointArgs {
this.SysWhitelist = append(this.SysWhitelist, point_arg.Nr)
}
} else {
// 指定了 syscall 则只从预置配置中选取存在的syscall
// 这种是使用预置配置
for _, syscall_name := range unique_items {
for _, point_arg := range this.PointArgs {
if point_arg.Name == syscall_name {
this.SysWhitelist = append(this.SysWhitelist, point_arg.Nr)
}
}
}
}
return
}

for _, v := range unique_items {
var index_items [][]uint32
syscall_name := v
Expand Down Expand Up @@ -730,6 +805,10 @@ func (this *ModuleConfig) LoadConfig(gconfig *GlobalConfig) {
if err != nil {
panic(err)
}
err = this.SysCallConf.Parse_FileConfig(config)
if err != nil {
panic(err)
}
default:
panic(fmt.Sprintf("unsupported config type %s", base_config.Type))
}
Expand Down
Loading

0 comments on commit 94838d0

Please sign in to comment.