diff options
author | We-unite <3205135446@qq.com> | 2024-08-05 16:59:51 +0800 |
---|---|---|
committer | We-unite <3205135446@qq.com> | 2024-08-05 16:59:51 +0800 |
commit | 78de56b9f2d862bbdac8a02a72dd95500b7ef83e (patch) | |
tree | f0d6ba73fed9d41464e6feea42baac95b87a73c3 | |
parent | 2c2975d032b1c26fd0094c8d3aa568251b5c9c6a (diff) | |
download | godo-starvation.tar.gz godo-starvation.zip |
Try t use coroutine, but starvationstarvation
-rw-r--r-- | src/deal.go | 48 | ||||
-rw-r--r-- | src/global.go | 59 | ||||
-rw-r--r-- | src/godo.go | 21 | ||||
-rw-r--r-- | src/mongo.go | 13 | ||||
-rw-r--r-- | src/organize.go | 1 |
5 files changed, 57 insertions, 85 deletions
diff --git a/src/deal.go b/src/deal.go index 871b7ff..483d4d2 100644 --- a/src/deal.go +++ b/src/deal.go | |||
@@ -2,20 +2,20 @@ package main | |||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | "sync" | ||
6 | "syscall" | 5 | "syscall" |
7 | 6 | ||
8 | "go.mongodb.org/mongo-driver/bson" | 7 | "go.mongodb.org/mongo-driver/bson" |
9 | ) | 8 | ) |
10 | 9 | ||
11 | const ( | 10 | const ( |
12 | dbName string = "test" | 11 | dbName string = "test" |
13 | pidColName string = "pids" | 12 | pidColName string = "pids" |
14 | fdColName string = "fds" | 13 | fdColName string = "fds" |
14 | fileColName string = "files" | ||
15 | ) | 15 | ) |
16 | 16 | ||
17 | var mongoMutex sync.Mutex | 17 | // var mongoMutex sync.Mutex |
18 | var pidCol, fdCol mongoClient | 18 | var pidCol, fdCol, fileCol mongoClient |
19 | 19 | ||
20 | var docRes []bson.M | 20 | var docRes []bson.M |
21 | var err error | 21 | var err error |
@@ -44,10 +44,14 @@ func deal() { | |||
44 | fmt.Printf("Error while initing the mongodb: %v\n", err) | 44 | fmt.Printf("Error while initing the mongodb: %v\n", err) |
45 | return | 45 | return |
46 | } | 46 | } |
47 | if err = fileCol.init(dbName, fileColName); err != nil { | ||
48 | fmt.Printf("Error while initing the mongodb: %v\n", err) | ||
49 | } | ||
47 | 50 | ||
48 | fmt.Printf("Containerd: %d\n", containerdPid) | 51 | fmt.Printf("Containerd: %d\n", containerdPid) |
49 | defer pidCol.Disconnect() | 52 | defer pidCol.Disconnect() |
50 | defer fdCol.Disconnect() | 53 | defer fdCol.Disconnect() |
54 | defer fileCol.Disconnect() | ||
51 | 55 | ||
52 | for { | 56 | for { |
53 | cooked, ok = <-cookedChan | 57 | cooked, ok = <-cookedChan |
@@ -57,11 +61,11 @@ func deal() { | |||
57 | 61 | ||
58 | switch cooked.tag { | 62 | switch cooked.tag { |
59 | case NEWPID: | 63 | case NEWPID: |
60 | dealNewPid(cooked) | 64 | go dealNewPid(cooked) |
61 | case EXECVE: | 65 | case EXECVE: |
62 | dealExecve(cooked) | 66 | go dealExecve(cooked) |
63 | case PIDEXIT: | 67 | case PIDEXIT: |
64 | deletePid(cooked) | 68 | go deletePid(cooked) |
65 | case FILEOPEN: | 69 | case FILEOPEN: |
66 | fileOpen(cooked) | 70 | fileOpen(cooked) |
67 | case FILEWRITE: | 71 | case FILEWRITE: |
@@ -73,9 +77,7 @@ func deal() { | |||
73 | } | 77 | } |
74 | 78 | ||
75 | func deletePid(cooked Event) { | 79 | func deletePid(cooked Event) { |
76 | // TODO: 是否还需要延时? | 80 | pidCol.GetLock() |
77 | // time.Sleep(1 * time.Second) | ||
78 | mongoMutex.Lock() | ||
79 | // 先从老爹那里销户 | 81 | // 先从老爹那里销户 |
80 | pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{ | 82 | pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{ |
81 | "$pull": bson.M{ | 83 | "$pull": bson.M{ |
@@ -85,7 +87,8 @@ func deletePid(cooked Event) { | |||
85 | 87 | ||
86 | // 孩子们需要收容 | 88 | // 孩子们需要收容 |
87 | // 不必到children里一个个找,直接看ppid即可 | 89 | // 不必到children里一个个找,直接看ppid即可 |
88 | pidCol.UpdateMany(bson.M{"ppid": cooked.pid}, bson.M{"ppid": 1}) | 90 | // pidCol.UpdateMany(bson.M{"ppid": cooked.pid}, bson.M{"ppid": 1}) |
91 | // 在这套逻辑里,孩子是不需要收容的,因为我们根本就不看ppid来工作 | ||
89 | 92 | ||
90 | // 可以去死了 | 93 | // 可以去死了 |
91 | pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ | 94 | pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ |
@@ -95,8 +98,7 @@ func deletePid(cooked Event) { | |||
95 | "exit_signal": cooked.exit_signal, | 98 | "exit_signal": cooked.exit_signal, |
96 | }, | 99 | }, |
97 | }) | 100 | }) |
98 | mongoMutex.Unlock() | 101 | pidCol.Mutex.Unlock() |
99 | fmt.Printf("Exit: %v\t%6d\t%6d\n", cooked.timestamp, cooked.pid, cooked.exit_code) | ||
100 | } | 102 | } |
101 | 103 | ||
102 | func dealNewPid(cooked Event) { | 104 | func dealNewPid(cooked Event) { |
@@ -113,7 +115,8 @@ func dealNewPid(cooked Event) { | |||
113 | fmt.Printf("Err finding: %v\n", err) | 115 | fmt.Printf("Err finding: %v\n", err) |
114 | return | 116 | return |
115 | } | 117 | } |
116 | mongoMutex.Lock() | 118 | |
119 | pidCol.GetLock() | ||
117 | if len(docRes) != 0 { | 120 | if len(docRes) != 0 { |
118 | // 进程原本就存在,换言之别的消息先到了 | 121 | // 进程原本就存在,换言之别的消息先到了 |
119 | // 所有先行抵达的消息必须保留execve/children字段 | 122 | // 所有先行抵达的消息必须保留execve/children字段 |
@@ -146,7 +149,7 @@ func dealNewPid(cooked Event) { | |||
146 | "children": cooked.pid, | 149 | "children": cooked.pid, |
147 | }, | 150 | }, |
148 | }) | 151 | }) |
149 | mongoMutex.Unlock() | 152 | pidCol.Mutex.Unlock() |
150 | } | 153 | } |
151 | 154 | ||
152 | func dealExecve(cooked Event) { | 155 | func dealExecve(cooked Event) { |
@@ -162,7 +165,8 @@ func dealExecve(cooked Event) { | |||
162 | if err != nil { | 165 | if err != nil { |
163 | return | 166 | return |
164 | } | 167 | } |
165 | mongoMutex.Lock() | 168 | |
169 | pidCol.GetLock() | ||
166 | if len(docRes) == 1 { | 170 | if len(docRes) == 1 { |
167 | // 自身已在,直接记录 | 171 | // 自身已在,直接记录 |
168 | pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ | 172 | pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ |
@@ -187,12 +191,10 @@ func dealExecve(cooked Event) { | |||
187 | }, | 191 | }, |
188 | }) | 192 | }) |
189 | } | 193 | } |
190 | mongoMutex.Unlock() | 194 | pidCol.Mutex.Unlock() |
191 | } | 195 | } |
192 | 196 | ||
193 | func fileOpen(cooked Event) { | 197 | func fileOpen(cooked Event) { |
194 | // fmt.Printf("Open: %6d\t%6d\t%s\n", cooked.ppid, cooked.pid, cooked.pathName) | ||
195 | |||
196 | // 权限检查过了,不必再查 | 198 | // 权限检查过了,不必再查 |
197 | fdCol.InsertOne(bson.M{ | 199 | fdCol.InsertOne(bson.M{ |
198 | "timestamp": cooked.timestamp, | 200 | "timestamp": cooked.timestamp, |
@@ -213,8 +215,6 @@ func fileOpen(cooked Event) { | |||
213 | } | 215 | } |
214 | 216 | ||
215 | func fileClose(cooked Event) { | 217 | func fileClose(cooked Event) { |
216 | // fmt.Printf("Close: %6d\t%6d\t%s\n", cooked.ppid, cooked.pid, cooked.pathName) | ||
217 | // 直接看文件表有无记录 | ||
218 | res, err := fdCol.Finddoc(bson.M{ | 218 | res, err := fdCol.Finddoc(bson.M{ |
219 | "pid": cooked.pid, | 219 | "pid": cooked.pid, |
220 | "fd": cooked.syscallParam[0], | 220 | "fd": cooked.syscallParam[0], |
@@ -234,8 +234,6 @@ func fileClose(cooked Event) { | |||
234 | } | 234 | } |
235 | 235 | ||
236 | func fileWrite(cooked Event) { | 236 | func fileWrite(cooked Event) { |
237 | // fmt.Printf("Write: %6d\t%6d\t%s\n", cooked.ppid, cooked.pid, cooked.pathName) | ||
238 | // 直接看文件表有无记录 | ||
239 | res, err := fdCol.Finddoc(bson.M{ | 237 | res, err := fdCol.Finddoc(bson.M{ |
240 | "pid": cooked.pid, | 238 | "pid": cooked.pid, |
241 | "fd": cooked.syscallParam[0], | 239 | "fd": cooked.syscallParam[0], |
diff --git a/src/global.go b/src/global.go index a266b1b..b6635c9 100644 --- a/src/global.go +++ b/src/global.go | |||
@@ -1,11 +1,8 @@ | |||
1 | package main | 1 | package main |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | ||
5 | "sync" | 4 | "sync" |
6 | "time" | 5 | "time" |
7 | |||
8 | "go.mongodb.org/mongo-driver/bson/primitive" | ||
9 | ) | 6 | ) |
10 | 7 | ||
11 | type eventType int | 8 | type eventType int |
@@ -29,50 +26,18 @@ func (et eventType) String() string { | |||
29 | } | 26 | } |
30 | 27 | ||
31 | type Event struct { | 28 | type Event struct { |
32 | tag eventType | 29 | tag eventType |
33 | timestamp time.Time | 30 | timestamp time.Time |
34 | pid, ppid int | 31 | pid, tgid int |
35 | syscall int | 32 | ppid, parentTgid int |
36 | syscallParam [4]uint64 | 33 | syscall int |
37 | pathName string | 34 | syscallParam [4]uint64 |
38 | argc int | 35 | pathName string |
39 | argv []string | 36 | argc int |
40 | cwd string | 37 | argv []string |
41 | exit_code uint64 | 38 | cwd string |
42 | exit_signal int | 39 | exit_code uint64 |
43 | } | 40 | exit_signal int |
44 | |||
45 | func (event Event) String() string { | ||
46 | var res string | ||
47 | res = fmt.Sprintf("tag: %v\ntimestamp: %v\nppid: %d\npid: %d\n", event.tag, event.timestamp.Local(), event.ppid, event.pid) | ||
48 | res += fmt.Sprintf("syscall: %s\nexit_code: %d\nargs: \n", syscallTable[event.syscall], event.exit_code) | ||
49 | for i := 0; i < len(event.argv); i++ { | ||
50 | res += fmt.Sprintf("\t\"%s\"\n", event.argv[i]) | ||
51 | } | ||
52 | res += "syscallParam: " | ||
53 | for i := 0; i < len(event.syscallParam); i++ { | ||
54 | res += fmt.Sprintf("\t\"%d\"\n", event.syscallParam[i]) | ||
55 | } | ||
56 | res += "pathName: \"" + event.pathName + "\"\n------\n" | ||
57 | return res | ||
58 | } | ||
59 | |||
60 | type pidExec struct { | ||
61 | timestamp time.Time `bson:"timestamp"` | ||
62 | execArgs []string `bson:"execArgs"` | ||
63 | } | ||
64 | |||
65 | type pid struct { | ||
66 | ID primitive.ObjectID `bson:"_id,ometempty"` | ||
67 | start_timestamp time.Time `bson:"start_timestamp"` | ||
68 | ppid int `bson:"ppid"` | ||
69 | pid int `bson:"pid"` | ||
70 | cwd string `bson:"cwd"` | ||
71 | args []string `bson:"args"` | ||
72 | execve []pidExec `bson:"execve"` | ||
73 | children []int `bson:"children"` | ||
74 | exit_timestamp time.Time `bson:"exit_timestamp"` | ||
75 | exit_code uint64 `bson:"exit_code"` | ||
76 | } | 41 | } |
77 | 42 | ||
78 | var wg sync.WaitGroup // 掌管协程 | 43 | var wg sync.WaitGroup // 掌管协程 |
diff --git a/src/godo.go b/src/godo.go index 2ba32d6..77e677c 100644 --- a/src/godo.go +++ b/src/godo.go | |||
@@ -44,7 +44,6 @@ func main() { | |||
44 | var auditCmd *exec.Cmd | 44 | var auditCmd *exec.Cmd |
45 | 45 | ||
46 | pidSyscall := []string{"execve"} | 46 | pidSyscall := []string{"execve"} |
47 | // pidSyscall := []string{"fork", "vfork", "clone", "execve", "exit", "exit_group"} | ||
48 | // 设置监听规则 | 47 | // 设置监听规则 |
49 | for i := 0; i < len(pidSyscall); i++ { | 48 | for i := 0; i < len(pidSyscall); i++ { |
50 | auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", pidSyscall[i]) | 49 | auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", pidSyscall[i]) |
@@ -52,7 +51,7 @@ func main() { | |||
52 | } | 51 | } |
53 | 52 | ||
54 | // 监听文件的消息 | 53 | // 监听文件的消息 |
55 | fileSyscall := []string{"open"} | 54 | fileSyscall := []string{"open", "write", "close"} |
56 | // fileSyscall := []string{"open", "write", "creat", "unlink", "opendir", "mkdir", "rmdir", "chmod", "fchmod", "chown", "fchown", "lchown", "flock"} | 55 | // fileSyscall := []string{"open", "write", "creat", "unlink", "opendir", "mkdir", "rmdir", "chmod", "fchmod", "chown", "fchown", "lchown", "flock"} |
57 | for i := 0; i < len(fileSyscall); i++ { | 56 | for i := 0; i < len(fileSyscall); i++ { |
58 | auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", fileSyscall[i]) | 57 | auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", fileSyscall[i]) |
@@ -118,16 +117,14 @@ func procWatch() error { | |||
118 | case netlink.PROC_EVENT_FORK: | 117 | case netlink.PROC_EVENT_FORK: |
119 | data := procEvent.Data.(netlink.ProcEventFork) | 118 | data := procEvent.Data.(netlink.ProcEventFork) |
120 | cooked := Event{ | 119 | cooked := Event{ |
121 | tag: NEWPID, | 120 | tag: NEWPID, |
122 | ppid: int(data.ParentTgid), | 121 | timestamp: time.Now(), |
123 | pid: int(data.ChildPid), | 122 | pid: int(data.ChildPid), |
124 | timestamp: time.Now(), | 123 | tgid: int(data.ChildTgid), |
124 | ppid: int(data.ParentPid), | ||
125 | parentTgid: int(data.ParentTgid), | ||
125 | } | 126 | } |
126 | checkProc(&cooked) | 127 | checkProc(&cooked) |
127 | if data.ChildPid != data.ChildTgid { | ||
128 | cooked.ppid = int(data.ChildTgid) | ||
129 | cooked.pid = int(data.ChildPid) | ||
130 | } | ||
131 | cookedChan <- cooked | 128 | cookedChan <- cooked |
132 | case netlink.PROC_EVENT_EXIT: | 129 | case netlink.PROC_EVENT_EXIT: |
133 | data := procEvent.Data.(netlink.ProcEventExit) | 130 | data := procEvent.Data.(netlink.ProcEventExit) |
@@ -146,7 +143,7 @@ func procWatch() error { | |||
146 | } | 143 | } |
147 | 144 | ||
148 | func checkProc(pCooked *Event) { | 145 | func checkProc(pCooked *Event) { |
149 | fileName := fmt.Sprintf("/proc/%d/cmdline", pCooked.pid) | 146 | fileName := fmt.Sprintf("/proc/%d/task/%d/cmdline", pCooked.tgid, pCooked.pid) |
150 | fd, err := os.Open(fileName) | 147 | fd, err := os.Open(fileName) |
151 | if err != nil { | 148 | if err != nil { |
152 | fmt.Printf("Err: %v\n", err) | 149 | fmt.Printf("Err: %v\n", err) |
@@ -162,7 +159,7 @@ func checkProc(pCooked *Event) { | |||
162 | pCooked.argc = len(pCooked.argv) | 159 | pCooked.argc = len(pCooked.argv) |
163 | fd.Close() | 160 | fd.Close() |
164 | 161 | ||
165 | fileName = fmt.Sprintf("/proc/%d/cwd", pCooked.pid) | 162 | fileName = fmt.Sprintf("/proc/%d/task/%d/cwd", pCooked.tgid, pCooked.pid) |
166 | pCooked.cwd, err = os.Readlink(fileName) | 163 | pCooked.cwd, err = os.Readlink(fileName) |
167 | if err != nil { | 164 | if err != nil { |
168 | fmt.Printf("Err readlink %s: %v\n", fileName, err) | 165 | fmt.Printf("Err readlink %s: %v\n", fileName, err) |
diff --git a/src/mongo.go b/src/mongo.go index 54f9533..3a23131 100644 --- a/src/mongo.go +++ b/src/mongo.go | |||
@@ -2,6 +2,8 @@ package main | |||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "context" | 4 | "context" |
5 | "fmt" | ||
6 | "sync" | ||
5 | "time" | 7 | "time" |
6 | 8 | ||
7 | "go.mongodb.org/mongo-driver/bson" | 9 | "go.mongodb.org/mongo-driver/bson" |
@@ -13,6 +15,8 @@ type mongoClient struct { | |||
13 | dbName, colName string | 15 | dbName, colName string |
14 | client *mongo.Client | 16 | client *mongo.Client |
15 | col *mongo.Collection | 17 | col *mongo.Collection |
18 | Mutex sync.Mutex | ||
19 | // Attention: 这把锁是否有必要? | ||
16 | } | 20 | } |
17 | 21 | ||
18 | func (mc *mongoClient) init(dbName, colName string) error { | 22 | func (mc *mongoClient) init(dbName, colName string) error { |
@@ -89,3 +93,12 @@ func (mc *mongoClient) Disconnect() error { | |||
89 | mc.colName = "" | 93 | mc.colName = "" |
90 | return nil | 94 | return nil |
91 | } | 95 | } |
96 | |||
97 | func (mc *mongoClient) GetLock() { | ||
98 | for i := 0; i < 20000; { | ||
99 | if !mc.Mutex.TryLock() { | ||
100 | i++ | ||
101 | } | ||
102 | } | ||
103 | fmt.Printf("Die...\n") | ||
104 | } | ||
diff --git a/src/organize.go b/src/organize.go index 8deba53..238509f 100644 --- a/src/organize.go +++ b/src/organize.go | |||
@@ -47,7 +47,6 @@ func orgnaze() { | |||
47 | break | 47 | break |
48 | } | 48 | } |
49 | rawEvent = raw.(libaudit.RawAuditMessage) | 49 | rawEvent = raw.(libaudit.RawAuditMessage) |
50 | // fmt.Printf("type=%v msg=%s\n", rawEvent.Type, rawEvent.Data) | ||
51 | 50 | ||
52 | switch rawEvent.Type { | 51 | switch rawEvent.Type { |
53 | case auparse.AUDIT_SYSCALL: | 52 | case auparse.AUDIT_SYSCALL: |