-
Notifications
You must be signed in to change notification settings - Fork 53
keylog module causes deadlock when trying dynamically load c-shared poseidon on older glibc #62
Description
Hi.
I faced an issue when tried to load poseidon as c-shared library in an obsolete evnironment and it resulted in a deadlock. After the debugging session it's turned out that the issue is because of keylog module, and particularly in user.Curent() of os/user . The issue is most likely because the call is triggered from the library contrustror, which loads keylog module which creates an NewKeyLog instance in the init stage:
poseidon/Payload_Type/poseidon/poseidon/agent_code/keylog/keystate/keystate.go
Lines 13 to 16 in 8f6c1e7
| var ( | |
| curTask *structs.Task | |
| // Struct to monitor keystrokes. | |
| ksmonitor, _ = NewKeyLog() |
poseidon/Payload_Type/poseidon/poseidon/agent_code/keylog/keystate/keystate.go
Lines 108 to 109 in 8f6c1e7
| func NewKeyLog() (KeyLogWithMutex, error) { | |
| curUser, err := user.Current() |
As far as I understand the problem is related to a multithreaded loading of the dynamic library (
user.Current loads libc to execute getpwuid_r) while another thread holds the dlopen lock for loading poseidon library. It also seems that problem is fixed/mitigated somehow in the libc 2.35. The problem also doesnt appear when loading poseidon using LD_PRELOAD.
Steps to reproduce:
- Compile poseidon as c-shared library
- Try to load it with libc <= 2.34 (any ubuntu before 22.04 release)
$ docker run -ti -v $(pwd):/app python:2 python2 -c '__import__("ctypes").CDLL("/app/poseidon.so")'
debug string: true
- You've got a deadlock
Possible solution
Probably moving the call of NewKeyLog from init/constructor stage to a direct call from outside should fix the issue