Describe the bug
MaliciousShamirMC::reconstruct performs an out-of-bounds heap read (and silently skips share
consistency verification) whenever the number of parties exceeds 2t+1 — e.g.
malicious-shamir-party.x -N 7 -T 2 — and the program executes a private output
(reveal_to). The reconstruction table is sized for 2t+2 entries, but the private-output
path passes all n received shares, and the verification loop indexes the table up to n.
The bug is present in v0.4.3 and is still present in current master
(Protocols/MaliciousShamirMC.hpp, reconstructions.resize(2 * threshold + 2) vs. the loop
for (size_t j = threshold + 2; j <= shares.size(); j++)).
To Reproduce
- Any
malicious-shamir-party.x run with n > 2t+1 (allowed by ShamirOptions::set_threshold,
which only rejects 2 * threshold >= nparties)
- Any program using
sint.reveal_to(player) (private output)
The regular public-opening path is not affected because finalize_raw resizes shares to
2t+1 first; the bug is specific to private output, which passes the full n-element vector
(MaliciousShamirPO allocates shares(P.num_players())).
a = sint(42)
x = a.reveal_to(0)
print_ln("done")
Compile and run 7 parties with threshold 2:
./compile.py poc_privout
for i in 0 1 2 3 4 5 6; do
./malicious-shamir-party.x -u -N 7 -T 2 -pn 21000 -h 127.0.0.1 $i poc_privout &
sleep 2
done
wait
-u is only used to skip certificate setup; the bug is in the share-verification logic and
is independent of channel encryption.
Expected behavior
Successfully executed
Error message
Observed behavior (ASan report)
==1661==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xffff80c06320
READ of size 8 at 0xffff80c06320 thread T10
#0 std::vector<gfp_<0, 2>>::operator[](unsigned long) stl_vector.h:1046
#1 MaliciousShamirMC<MaliciousShamirShare<gfp_<0, 2>>>::reconstruct(
std::vector<gfp_<0, 2>> const&) Protocols/MaliciousShamirMC.hpp:57
#2 SpecificPrivateOutput<...>::finalize(int) Processor/SpecificPrivateOutput.h:58
#3 SubProcessor<...>::private_output(...) Processor/Processor.hpp:1048
#4 Instruction::execute<...> Processor/Instruction.hpp:1147
...
0xffff80c06320 is located 0 bytes to the right of 144-byte region
MP-SPDZ version
v0.4.3 and master
Describe the bug
MaliciousShamirMC::reconstructperforms an out-of-bounds heap read (and silently skips shareconsistency verification) whenever the number of parties exceeds
2t+1— e.g.malicious-shamir-party.x -N 7 -T 2— and the program executes a private output(
reveal_to). The reconstruction table is sized for2t+2entries, but the private-outputpath passes all
nreceived shares, and the verification loop indexes the table up ton.The bug is present in v0.4.3 and is still present in current
master(
Protocols/MaliciousShamirMC.hpp,reconstructions.resize(2 * threshold + 2)vs. the loopfor (size_t j = threshold + 2; j <= shares.size(); j++)).To Reproduce
malicious-shamir-party.xrun withn > 2t+1(allowed byShamirOptions::set_threshold,which only rejects
2 * threshold >= nparties)sint.reveal_to(player)(private output)The regular public-opening path is not affected because
finalize_rawresizessharesto2t+1first; the bug is specific to private output, which passes the fulln-element vector(
MaliciousShamirPOallocatesshares(P.num_players())).Compile and run 7 parties with threshold 2:
-uis only used to skip certificate setup; the bug is in the share-verification logic andis independent of channel encryption.
Expected behavior
Successfully executed
Error message
Observed behavior (ASan report)
MP-SPDZ version
v0.4.3 and master