ABY
ABY copied to clipboard
Missing cleanup of threads
While testing my circuits I saw that with each invocation of ABY a few more threads were added to the process.
I traced the creation and joining of threads in the sha1 example:
- 10 threads created
- 6 thread joined
Here are the full call stacks:
./bin/sha1.exe -r 0
======================
calling pthread_create (1)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(ABYSetup::Init() 0x111)[0x4f83a1]
./bin/sha1.exe(ABYSetup::ABYSetup(crypto*, unsigned int, e_role, e_mt_gen_alg) 0xdc)[0x4f81cc]
./bin/sha1.exe(ABYParty::Init() 0x74)[0x4e97d4]
./bin/sha1.exe(ABYParty::ABYParty(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, unsigned int, unsigned short) 0x1f7)[0x4e9017]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xc2)[0x471732]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_create (2)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(ABYSetup::Init() 0x111)[0x4f83a1]
./bin/sha1.exe(ABYSetup::ABYSetup(crypto*, unsigned int, e_role, e_mt_gen_alg) 0xdc)[0x4f81cc]
./bin/sha1.exe(ABYParty::Init() 0x74)[0x4e97d4]
./bin/sha1.exe(ABYParty::ABYParty(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, unsigned int, unsigned short) 0x1f7)[0x4e9017]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xc2)[0x471732]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_create (3)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(ABYParty::Init() 0x11f)[0x4e987f]
./bin/sha1.exe(ABYParty::ABYParty(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, unsigned int, unsigned short) 0x1f7)[0x4e9017]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xc2)[0x471732]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_create (4)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(ABYParty::Init() 0x11f)[0x4e987f]
./bin/sha1.exe(ABYParty::ABYParty(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, unsigned int, unsigned short) 0x1f7)[0x4e9017]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xc2)[0x471732]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_create (5)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(ABYParty::EstablishConnection() 0x1a9)[0x4ea319]
./bin/sha1.exe(ABYParty::ABYParty(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, unsigned int, unsigned short) 0x4fc)[0x4e931c]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xc2)[0x471732]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_create (6)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(ABYParty::EstablishConnection() 0x1c6)[0x4ea336]
./bin/sha1.exe(ABYParty::ABYParty(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, unsigned int, unsigned short) 0x4fc)[0x4e931c]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xc2)[0x471732]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_create (7)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(ABYParty::EstablishConnection() 0x1e3)[0x4ea353]
./bin/sha1.exe(ABYParty::ABYParty(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, unsigned int, unsigned short) 0x4fc)[0x4e931c]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xc2)[0x471732]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_create (8)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(ABYParty::EstablishConnection() 0x200)[0x4ea370]
./bin/sha1.exe(ABYParty::ABYParty(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, unsigned int, unsigned short) 0x4fc)[0x4e931c]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xc2)[0x471732]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_create (9)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(OTExtSnd::start_send(unsigned int) 0x276)[0x483ce6]
./bin/sha1.exe(OTExtSnd::send(unsigned long, unsigned long, unsigned long, CBitVector**, snd_ot_flavor, rec_ot_flavor, unsigned int, MaskingFunction*) 0xee)[0x4839de]
./bin/sha1.exe(ABYSetup::ThreadRunIKNPSnd(unsigned int) 0x10d)[0x4f8e0d]
./bin/sha1.exe(ABYSetup::CWorkerThread::ThreadMain() 0x81)[0x4f9d21]
./bin/sha1.exe(CThread::ThreadMainHandler(void*) 0x1e)[0x481f9e]
/usr/lib/libpthread.so.0( 0x7454)[0x7fdff0732454]
/usr/lib/libc.so.6(clone 0x5f)[0x7fdfef2e07df]
======================
======================
calling pthread_create (10)
----------------------
./bin/sha1.exe(CThread::Start() 0xfd)[0x4818dd]
./bin/sha1.exe(OTExtRec::start_receive(unsigned int) 0x270)[0x47f6b0]
./bin/sha1.exe(OTExtRec::receive(unsigned long, unsigned long, unsigned long, CBitVector*, CBitVector*, snd_ot_flavor, rec_ot_flavor, unsigned int, MaskingFunction*) 0x100)[0x47f3b0]
./bin/sha1.exe(ABYSetup::ThreadRunIKNPRcv(unsigned int) 0x106)[0x4f8f76]
./bin/sha1.exe(ABYSetup::CWorkerThread::ThreadMain() 0x99)[0x4f9d39]
./bin/sha1.exe(CThread::ThreadMainHandler(void*) 0x1e)[0x481f9e]
/usr/lib/libpthread.so.0( 0x7454)[0x7fdff0732454]
/usr/lib/libc.so.6(clone 0x5f)[0x7fdfef2e07df]
======================
======================
calling pthread_join (9)
----------------------
./bin/sha1.exe(CThread::Wait() 0xec)[0x481a8c]
./bin/sha1.exe(OTExtSnd::start_send(unsigned int) 0x2fc)[0x483d6c]
./bin/sha1.exe(OTExtSnd::send(unsigned long, unsigned long, unsigned long, CBitVector**, snd_ot_flavor, rec_ot_flavor, unsigned int, MaskingFunction*) 0xee)[0x4839de]
./bin/sha1.exe(ABYSetup::ThreadRunIKNPSnd(unsigned int) 0x10d)[0x4f8e0d]
./bin/sha1.exe(ABYSetup::CWorkerThread::ThreadMain() 0x81)[0x4f9d21]
./bin/sha1.exe(CThread::ThreadMainHandler(void*) 0x1e)[0x481f9e]
/usr/lib/libpthread.so.0( 0x7454)[0x7fdff0732454]
/usr/lib/libc.so.6(clone 0x5f)[0x7fdfef2e07df]
======================
======================
calling pthread_join (10)
----------------------
./bin/sha1.exe(CThread::Wait() 0xec)[0x481a8c]
./bin/sha1.exe(OTExtRec::start_receive(unsigned int) 0x2f6)[0x47f736]
./bin/sha1.exe(OTExtRec::receive(unsigned long, unsigned long, unsigned long, CBitVector*, CBitVector*, snd_ot_flavor, rec_ot_flavor, unsigned int, MaskingFunction*) 0x100)[0x47f3b0]
./bin/sha1.exe(ABYSetup::ThreadRunIKNPRcv(unsigned int) 0x106)[0x4f8f76]
./bin/sha1.exe(ABYSetup::CWorkerThread::ThreadMain() 0x99)[0x4f9d39]
./bin/sha1.exe(CThread::ThreadMainHandler(void*) 0x1e)[0x481f9e]
/usr/lib/libpthread.so.0( 0x7454)[0x7fdff0732454]
/usr/lib/libc.so.6(clone 0x5f)[0x7fdfef2e07df]
======================
Plaintext output:
dc2172e79fae05b55178d431cd03262b0b45270
Testing SHA1 hash in Bool sharing:
(0) Server Input: fde4fbae4a09e020eff722969f83832b141cb2193eab67101d177fa95249c8ca
(0) Client Input: de63b7f21d2a67d8b91953b9ea3bc26e78c5ccba10c7bff05dbee6ce8ccff78c
(0) Circ: dc2172e709fae05b55178d431cd03262b0b45270
(0) Verify: dc2172e709fae05b55178d431cd03262b0b45270
======================
calling pthread_join (3)
----------------------
./bin/sha1.exe(CThread::Wait() 0xec)[0x481a8c]
./bin/sha1.exe(ABYParty::Cleanup() 0x275)[0x4eaa15]
./bin/sha1.exe(ABYParty::~ABYParty() 0x39)[0x4ea6a9]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xa88)[0x4720f8]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_join (4)
----------------------
./bin/sha1.exe(CThread::Wait() 0xec)[0x481a8c]
./bin/sha1.exe(ABYParty::Cleanup() 0x275)[0x4eaa15]
./bin/sha1.exe(ABYParty::~ABYParty() 0x39)[0x4ea6a9]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xa88)[0x4720f8]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_join (5)
----------------------
./bin/sha1.exe(CThread::Wait() 0xec)[0x481a8c]
./bin/sha1.exe(SndThread::~SndThread() 0x2d)[0x4f16bd]
./bin/sha1.exe(SndThread::~SndThread() 0x19)[0x4f1739]
./bin/sha1.exe(ABYParty::Cleanup() 0x320)[0x4eaac0]
./bin/sha1.exe(ABYParty::~ABYParty() 0x39)[0x4ea6a9]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xa88)[0x4720f8]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
======================
calling pthread_join (6)
----------------------
./bin/sha1.exe(CThread::Wait() 0xec)[0x481a8c]
./bin/sha1.exe(SndThread::~SndThread() 0x2d)[0x4f16bd]
./bin/sha1.exe(SndThread::~SndThread() 0x19)[0x4f1739]
./bin/sha1.exe(ABYParty::Cleanup() 0x34a)[0x4eaaea]
./bin/sha1.exe(ABYParty::~ABYParty() 0x39)[0x4ea6a9]
./bin/sha1.exe(test_sha1_circuit(e_role, char*, SECURITYLEVELS, unsigned int, unsigned int, e_mt_gen_alg, e_sharing) 0xa88)[0x4720f8]
./bin/sha1.exe(main 0x129)[0x476329]
/usr/lib/libc.so.6(__libc_start_main 0xf1)[0x7fdfef218291]
./bin/sha1.exe(_start 0x2a)[0x47159a]
======================
One problem: While SndThread joins the underlying thread on destruction, RcvThread does not do so.
Destructor of SndThread
~SndThread() {
kill_task();
this->Wait();
}
;
Destructor of RcvThread
~RcvThread() {
//this->Kill();
delete rcvlock;
free(listeners);
}
;
The missing Kill() in RcvThread has been uncommented in 9b4fc258cee5293b9be4f7f09cd1168724563cc3, but this probably needs more careful investigation.
I'm not sure, this does, what is intended.
I am assuming, the RcvThread objects were created by some kind of control thread. When these objects are destructed, CTread::Kill() is called, which in turn calls pthread_exit(NULL);
The pthread_exit() function terminates the calling thread and returns a value via retval that (if the thread is joinable) is available to another thread in the same process that calls pthread_join(3).
If I understand it correctly, the control thread is terminated, when it tries to destroy a RcvThread object.
The TerminateThread() in the Windows implementation of CThread::Kill() however does terminate a different thread.
My guess is, that in ~RcvThread() the method this->Wait() should be called instead. This does a pthread_join() and waits until the ThreadMain() method exits, which happens after receiving the kill message generated by the sender's kill_task().