From ec260a31927ef77295eaa07ba370b58b416f47f5 Mon Sep 17 00:00:00 2001 From: We-unite <3205135446@qq.com> Date: Fri, 26 Jul 2024 17:23:53 +0800 Subject: Fix execve before fork & Fix regex to match "exit" There's 2 bugs from ancestor commits: - In the 'things_left' tag commit(the grandpa of this commit), we add a function that allows execve comes before fork, but when it happens, I forget to insert the basic info (pid, ppid, etc.), as a result of which it doesn't work in the designed way. Now it is well, insert execve with pid and ppid, so that the fork event can find it and finish other info. However, we shouldn't make start_stamp in this case, so that it's also a flag. I've not removed the unused execve info, waiting for the future. - In the parent commit, the syscallRegex is changed, because when we add more syscalls to be watched, we need more info about their params but not only the first one. Instead of keeping using single a0 to get the first param, i use argsRegex for all the params. But this change causes mismatch of syscallRegex. Now it's fixed. --- src/deal.go | 226 ++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 122 insertions(+), 104 deletions(-) (limited to 'src/deal.go') diff --git a/src/deal.go b/src/deal.go index db6fc26..a9861a5 100644 --- a/src/deal.go +++ b/src/deal.go @@ -16,32 +16,18 @@ const ( var mongoMutex sync.Mutex var pidCol mongoClient +var docRes []bson.M +var err error + func deal() { defer wg.Done() var cooked Event var ok bool - var err error - var res []bson.M - - if err = pidCol.Connect(dbName, pidColName); err != nil { - fmt.Printf("Error connecting the mongodb: %v\n", err) - } - if err = pidCol.Drop(); err != nil { - fmt.Printf("Error drop the mongodb: %v\n", err) - } - - err = pidCol.InsertOne(bson.M{ - "ppid": 1, - "pid": containerdPid, - "cwd": "/", - "children": bson.M{}, - }) - if err != nil { - fmt.Printf("Err containerd: %v", err) + if err = initMongo(); err != nil { + fmt.Printf("Error while initing the mongodb: %v\n", err) return } - fmt.Printf("Containerd: %d\n", containerdPid) defer pidCol.Disconnect() for { @@ -50,91 +36,12 @@ func deal() { break } - switch syscallTable[cooked.syscall] { - case "clone": - // 有无父进程在观察中 - res, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid}) - if err != nil || len(res) != 1 { - break - } - - // 自身是否已经记录 - res, err = pidCol.Finddoc(bson.M{"pid": cooked.pid}) - if err != nil { - fmt.Printf("Err finding: %v\n", err) - break - } - mongoMutex.Lock() - if len(res) != 0 { - // 进程原本就存在,换言之别的消息先到了 - // 所有先行抵达的消息必须保留execve/children字段 - // 此处不再更新 - // 以防把原有信息更没了 - pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ - "start_timestamp": cooked.timestamp, - "ppid": cooked.ppid, - "pid": cooked.pid, - "cwd": cooked.cwd, - // "execve": []bson.M{}, - "args": cooked.argv, - // "children": []bson.M{}, - }) - } else { - // 这进程本是新修的 - pidCol.InsertOne(bson.M{ - "start_timestamp": cooked.timestamp, - "ppid": cooked.ppid, - "pid": cooked.pid, - "cwd": cooked.cwd, - "execve": []bson.M{}, - "args": cooked.argv, - "children": []bson.M{}, - }) - } - - pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{ - "$push": bson.M{ - "children": cooked.pid, - }, - }) - mongoMutex.Unlock() - case "execve": - // 父进程在不在?不在扔 - res, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid}) - if err != nil || len(res) != 1 { - break - } - - // 首先检查进程是否存在,如不存在则为之创建 - res, err = pidCol.Finddoc(bson.M{"pid": cooked.pid}) - if err != nil { - break - } - mongoMutex.Lock() - if len(res) == 1 { - // 自身已在,直接记录 - pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ - "$push": bson.M{ - "execve": bson.M{ - "timestamp": cooked.timestamp, - "args": cooked.argv, - }, - }, - }) - } else { - // 先fork抵达,插入 - pidCol.InsertOne(bson.M{ - "children": []bson.M{}, - "exe_args": []bson.M{ - { - "timestamp": cooked.timestamp, - "execve": cooked.argv, - }, - }, - }) - } - mongoMutex.Unlock() - case "exit", "exit_group": + switch cooked.tag { + case NEWPID: + dealNewPid(cooked) + case EXECVE: + dealExecve(cooked) + case PIDEXIT: go deletePid(cooked) } } @@ -163,3 +70,114 @@ func deletePid(cooked Event) { }) mongoMutex.Unlock() } + +func initMongo() error { + var err error + if err = pidCol.Connect(dbName, pidColName); err != nil { + return err + } + if err = pidCol.Drop(); err != nil { + return err + } + + err = pidCol.InsertOne(bson.M{ + "ppid": 1, + "pid": containerdPid, + "cwd": "/", + "children": bson.M{}, + }) + if err != nil { + return err + } + fmt.Printf("Containerd: %d\n", containerdPid) + return nil +} + +func dealNewPid(cooked Event) { + // 有无父进程在观察中 + docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid}) + if err != nil || len(docRes) != 1 { + return + } + + // 自身是否已经记录 + docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.pid}) + if err != nil { + fmt.Printf("Err finding: %v\n", err) + return + } + mongoMutex.Lock() + if len(docRes) != 0 { + // 进程原本就存在,换言之别的消息先到了 + // 所有先行抵达的消息必须保留execve/children字段 + // 此处不再更新 + // 以防把原有信息更没了 + pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ + "start_timestamp": cooked.timestamp, + "ppid": cooked.ppid, + "pid": cooked.pid, + "cwd": cooked.cwd, + // "execve": []bson.M{}, + "args": cooked.argv, + // "children": []bson.M{}, + }) + } else { + // 这进程本是新修的 + pidCol.InsertOne(bson.M{ + "start_timestamp": cooked.timestamp, + "ppid": cooked.ppid, + "pid": cooked.pid, + "cwd": cooked.cwd, + "execve": []bson.M{}, + "args": cooked.argv, + "children": []bson.M{}, + }) + } + + pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{ + "$push": bson.M{ + "children": cooked.pid, + }, + }) + mongoMutex.Unlock() +} + +func dealExecve(cooked Event) { + // 父进程在不在?不在扔 + docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid}) + if err != nil || len(docRes) != 1 { + return + } + + // 首先检查进程是否存在,如不存在则为之创建 + docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.pid}) + if err != nil { + return + } + mongoMutex.Lock() + if len(docRes) == 1 { + // 自身已在,直接记录 + pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ + "$push": bson.M{ + "execve": bson.M{ + "timestamp": cooked.timestamp, + "execArgs": cooked.argv, + }, + }, + }) + } else { + // 先fork抵达,插入 + pidCol.InsertOne(bson.M{ + "ppid": cooked.ppid, + "pid": cooked.pid, + "children": []bson.M{}, + "execve": []bson.M{ + { + "timestamp": cooked.timestamp, + "execArgs": cooked.argv, + }, + }, + }) + } + mongoMutex.Unlock() +} -- cgit v1.2.3-70-g09d2