ABY icon indicating copy to clipboard operation
ABY copied to clipboard

Heap overflow in get_clear_value()

Open lenerd opened this issue 6 years ago • 3 comments

With help of ASan found a buffer overflow occurring when arithmetic sharing is used (see below). I used test case no. 12 "ioarith". For the type sizes I assume a Linux AMD64 platform.

Let's look at ArithSharing<T>::InstantiateGate:

template<typename T>
void ArithSharing<T>::InstantiateGate(GATE* gate) {
	gate->instantiated = true;
	gate->gs.aval = (UGATE_T*) calloc(sizeof(T), gate->nvals);
}

If ArithSharing<T> is instantiated with an unsigned int (usually 32 bit on AMD64), 4 bytes are allocated. However, UGATE_T is defined as a 64 bit integer and needs 8 bytes.

I think sizeof(UGATE_T) should be used here. ASan is satisfied with that solution, but I might have missed something here.


ENCRYPTO_utils/typedefs.h
49:typedef unsigned long long UINT64_T;
53:typedef UINT64_T UGATE_T;
==2903==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200003a410 at pc 0x5555557c2f4b bp 0x7fffffffd580 sp 0x7fffffffd570
READ of size 8 at 0x60200003a410 thread T0
    #0 0x5555557c2f4a in unsigned int share::get_clear_value<unsigned int>() common/../../../abycore/circuit/share.h:96
    #1 0x5555557ba291 in test_standard_ops(aby_ops_t*, ABYParty*, unsigned int, unsigned int, unsigned int, e_role, bool) /home/lennart/git/ABY/src/test/abytest.cpp:254
    #2 0x5555557b8713 in run_tests(e_role, char*, unsigned short, SECURITYLEVELS, unsigned int, unsigned int, unsigned int, e_mt_gen_alg, int, unsigned int, bool, bool) /home/lennart/git/ABY/src/test/abytest.cpp:124
    #3 0x5555557b7251 in main /home/lennart/git/ABY/src/test/abytest.cpp:45
    #4 0x7ffff51f5f49 in __libc_start_main (/usr/lib/libc.so.6+0x20f49)
    #5 0x5555555d7d19 in _start (/home/lennart/git/ABY/bin/test-aby.exe+0x83d19)

0x60200003a414 is located 0 bytes to the right of 4-byte region [0x60200003a410,0x60200003a414)
allocated by thread T0 here:
    #0 0x7ffff6efdce1 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:70
    #1 0x55555562a124 in ArithSharing<unsigned int>::InstantiateGate(GATE*) (/home/lennart/git/ABY/bin/test-aby.exe+0xd6124)
    #2 0x55555562ebd5 in ArithSharing<unsigned int>::AssignOutputShares() (/home/lennart/git/ABY/bin/test-aby.exe+0xdabd5)
    #3 0x555555629cbe in ArithSharing<unsigned int>::FinishCircuitLayer(unsigned int) (/home/lennart/git/ABY/bin/test-aby.exe+0xd5cbe)
    #4 0x55555576a1d3 in ABYParty::EvaluateCircuit() ../../abycore/aby/abyparty.cpp:386
    #5 0x5555557683be in ABYParty::ExecCircuit() ../../abycore/aby/abyparty.cpp:248
    #6 0x5555557ba256 in test_standard_ops(aby_ops_t*, ABYParty*, unsigned int, unsigned int, unsigned int, e_role, bool) /home/lennart/git/ABY/src/test/abytest.cpp:252
    #7 0x5555557b8713 in run_tests(e_role, char*, unsigned short, SECURITYLEVELS, unsigned int, unsigned int, unsigned int, e_mt_gen_alg, int, unsigned int, bool, bool) /home/lennart/git/ABY/src/test/abytest.cpp:124
    #8 0x5555557b7251 in main /home/lennart/git/ABY/src/test/abytest.cpp:45
    #9 0x7ffff51f5f49 in __libc_start_main (/usr/lib/libc.so.6+0x20f49)

SUMMARY: AddressSanitizer: heap-buffer-overflow common/../../../abycore/circuit/share.h:96 in unsigned int share::get_clear_value<unsigned int>()

lenerd avatar Mar 22 '18 15:03 lenerd

Thanks for reporting this.

I think the intuition of using template T in this case was, that there are 8, 16, 32, and 64-bit elements in arithmetic sharing and in the smaller 3 cases you don't want to allocate 64 bit for every element.

~~So I guess, what it should look like is similar to BoolSharing::InstantiateGate(GATE* gate) i.e., we ceil-divide nvals by sizeof(T). We have to verify and test this though.~~

dd23 avatar Mar 22 '18 16:03 dd23

I have pushed f59161cf8c164d818284db6cabacddb711db6dfc that should fix this. Previously the amount of data read from the gate was indeed too large in some cases (always UGATE_T, which is 64 bit). Now the amount of data that is read matches the type you pass to get_clear_value() as template.

This is still not the end of the whole story, as sometimes other tests do fail for various reasons, but it should fix this particular problem.

dd23 avatar Mar 22 '18 19:03 dd23

It breaks during a2y operations (test cases 24 and 25) in yaoserversharing.cpp:275 and yaoclientsharing.cpp:427 (see below).

The ArithSharing<T>::InstantiateGate method should be modified anyway since the UGATE_T* points to a buffer too small for a UGATE_T.


ASan output of the server side:

$ ./test-aby.exe -r 0 -t 24
Running test no. 0 on operation a2y                       
=================================================================
==11796==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000043850 at pc 0x55d2529a03d3 bp 0x7ffd75304ef0 sp 0x7ffd75304ee0
READ of size 8 at 0x602000043850 thread T0
    #0 0x55d2529a03d2 in YaoServerSharing::SendConversionValues(unsigned int) ../../abycore/sharing/yaoserversharing.cpp:275
    #1 0x55d25299fc46 in YaoServerSharing::EvaluateInteractiveOperations(unsigned int) ../../abycore/sharing/yaoserversharing.cpp:241
    #2 0x55d252a60ea2 in ABYParty::EvaluateCircuit() ../../abycore/aby/abyparty.cpp:361
    #3 0x55d252a5f13a in ABYParty::ExecCircuit() ../../abycore/aby/abyparty.cpp:248
    #4 0x55d252ab1458 in test_standard_ops(aby_ops_t*, ABYParty*, unsigned int, unsigned int, unsigned int, e_role, bool) /home/lennart/git/ABY/src/test/abytest.cpp:256
    #5 0x55d252aaf8e4 in run_tests(e_role, char*, unsigned short, SECURITYLEVELS, unsigned int, unsigned int, unsigned int, e_mt_gen_alg, int, unsigned int, bool, bool) /home/lennart/git/ABY/src/test/abytest.cpp:126
    #6 0x55d252aaf2b5 in main /home/lennart/git/ABY/src/test/abytest.cpp:45
    #7 0x7fe4b8c4bf49 in __libc_start_main (/usr/lib/libc.so.6+0x20f49)
    #8 0x55d2528964d9 in _start (/home/lennart/git/ABY/bin/test-aby.exe+0x824d9)

0x602000043854 is located 0 bytes to the right of 4-byte region [0x602000043850,0x602000043854)
allocated by thread T0 here:
    #0 0x7fe4ba953ce1 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:70
    #1 0x55d2528fc032 in ArithSharing<unsigned int>::InstantiateGate(GATE*) src/abycore/sharing/arithsharing.cpp:866
    #2 0x55d2528fa98b in ArithSharing<unsigned int>::EvaluateMULGate() src/abycore/sharing/arithsharing.cpp:560
    #3 0x55d2528fa374 in ArithSharing<unsigned int>::FinishCircuitLayer(unsigned int) src/abycore/sharing/arithsharing.cpp:513
    #4 0x55d252a60f8b in ABYParty::EvaluateCircuit() ../../abycore/aby/abyparty.cpp:386
    #5 0x55d252a5f13a in ABYParty::ExecCircuit() ../../abycore/aby/abyparty.cpp:248
    #6 0x55d252ab1458 in test_standard_ops(aby_ops_t*, ABYParty*, unsigned int, unsigned int, unsigned int, e_role, bool) /home/lennart/git/ABY/src/test/abytest.cpp:256
    #7 0x55d252aaf8e4 in run_tests(e_role, char*, unsigned short, SECURITYLEVELS, unsigned int, unsigned int, unsigned int, e_mt_gen_alg, int, unsigned int, bool, bool) /home/lennart/git/ABY/src/test/abytest.cpp:126
    #8 0x55d252aaf2b5 in main /home/lennart/git/ABY/src/test/abytest.cpp:45
    #9 0x7fe4b8c4bf49 in __libc_start_main (/usr/lib/libc.so.6+0x20f49)

SUMMARY: AddressSanitizer: heap-buffer-overflow ../../abycore/sharing/yaoserversharing.cpp:275 in YaoServerSharing::SendConversionValues(unsigned int)

ASan output of the client side:

$ ./test-aby.exe -r 1 -t 24                          [0:17:15]
Running test no. 0 on operation a2y
=================================================================
==11801==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200003b530 at pc 0x560e461e2c17 bp 0x7ffce99adec0 sp 0x7ffce99adeb0
READ of size 8 at 0x60200003b530 thread T0
    #0 0x560e461e2c16 in YaoClientSharing::EvaluateConversionGate(unsigned int) ../../abycore/sharing/yaoclientsharing.cpp:427
    #1 0x560e461e0ef6 in YaoClientSharing::EvaluateInteractiveOperations(unsigned int) ../../abycore/sharing/yaoclientsharing.cpp:234
    #2 0x560e462b2ea2 in ABYParty::EvaluateCircuit() ../../abycore/aby/abyparty.cpp:361
    #3 0x560e462b113a in ABYParty::ExecCircuit() ../../abycore/aby/abyparty.cpp:248
    #4 0x560e46303458 in test_standard_ops(aby_ops_t*, ABYParty*, unsigned int, unsigned int, unsigned int, e_role, bool) /home/lennart/git/ABY/src/test/abytest.cpp:256
    #5 0x560e463018e4 in run_tests(e_role, char*, unsigned short, SECURITYLEVELS, unsigned int, unsigned int, unsigned int, e_mt_gen_alg, int, unsigned int, bool, bool) /home/lennart/git/ABY/src/test/abytest.cpp:126
    #6 0x560e463012b5 in main /home/lennart/git/ABY/src/test/abytest.cpp:45
    #7 0x7f58003b8f49 in __libc_start_main (/usr/lib/libc.so.6+0x20f49)
    #8 0x560e460e84d9 in _start (/home/lennart/git/ABY/bin/test-aby.exe+0x824d9)

0x60200003b534 is located 0 bytes to the right of 4-byte region [0x60200003b530,0x60200003b534)
allocated by thread T0 here:
    #0 0x7f58020c0ce1 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:70
    #1 0x560e4614e032 in ArithSharing<unsigned int>::InstantiateGate(GATE*) src/abycore/sharing/arithsharing.cpp:866
    #2 0x560e4614c98b in ArithSharing<unsigned int>::EvaluateMULGate() src/abycore/sharing/arithsharing.cpp:560
    #3 0x560e4614c374 in ArithSharing<unsigned int>::FinishCircuitLayer(unsigned int) src/abycore/sharing/arithsharing.cpp:513
    #4 0x560e462b2f8b in ABYParty::EvaluateCircuit() ../../abycore/aby/abyparty.cpp:386
    #5 0x560e462b113a in ABYParty::ExecCircuit() ../../abycore/aby/abyparty.cpp:248
    #6 0x560e46303458 in test_standard_ops(aby_ops_t*, ABYParty*, unsigned int, unsigned int, unsigned int, e_role, bool) /home/lennart/git/ABY/src/test/abytest.cpp:256
    #7 0x560e463018e4 in run_tests(e_role, char*, unsigned short, SECURITYLEVELS, unsigned int, unsigned int, unsigned int, e_mt_gen_alg, int, unsigned int, bool, bool) /home/lennart/git/ABY/src/test/abytest.cpp:126
    #8 0x560e463012b5 in main /home/lennart/git/ABY/src/test/abytest.cpp:45
    #9 0x7f58003b8f49 in __libc_start_main (/usr/lib/libc.so.6+0x20f49)

SUMMARY: AddressSanitizer: heap-buffer-overflow ../../abycore/sharing/yaoclientsharing.cpp:427 in YaoClientSharing::EvaluateConversionGate(unsigned int)

lenerd avatar Mar 25 '18 22:03 lenerd