Subject: | Crash when trying to decrypt an empty string |
If I try to round trip '' through crypto_secretbox/crypto_secretbox_open I get a segfault - Signal SEGV.
Looking at the code it appears that Perl_newSVpv assumes that if you pass it 0 for a length, it assumes you didn't know the length and it tries to use strlen to calculate it, leading to strlen segfaulting as you aren't providing a null terminated string.
I have attached a quick patch to fix that and a test to check the issue is fixed.
Subject: | empty-string-segfault.patch |
diff -Naur Crypt-Sodium-0.08/Sodium.xs /home/colin/.cpanm/work/1480069977.15466/Crypt-Sodium-0.08/Sodium.xs
--- Crypt-Sodium-0.08/Sodium.xs 2015-10-18 06:34:28.000000000 +0100
+++ /home/colin/.cpanm/work/1480069977.15466/Crypt-Sodium-0.08/Sodium.xs 2016-11-25 10:55:24.232418482 +0000
@@ -308,7 +308,13 @@
(unsigned long long) clen, (const unsigned char*)n, (const unsigned char*)sk);
if (status == 0) {
- RETVAL = newSVpv( m, clen - crypto_secretbox_MACBYTES );
+ // newSVpv assumes 0 in length mean 'don't know, figure it out by
+ // calling strlen, so we need to fudge it.
+ if (clen - crypto_secretbox_MACBYTES == 0) {
+ RETVAL = newSVpv( "", 0 );
+ } else {
+ RETVAL = newSVpv( m, clen - crypto_secretbox_MACBYTES );
+ }
} else {
RETVAL = &PL_sv_undef;
}
diff -Naur Crypt-Sodium-0.08/t/Crypt-Sodium.t /home/colin/.cpanm/work/1480069977.15466/Crypt-Sodium-0.08/t/Crypt-Sodium.t
--- Crypt-Sodium-0.08/t/Crypt-Sodium.t 2015-10-18 06:24:22.000000000 +0100
+++ /home/colin/.cpanm/work/1480069977.15466/Crypt-Sodium-0.08/t/Crypt-Sodium.t 2016-11-25 10:57:44.596842752 +0000
@@ -28,6 +28,9 @@
$enciphered = crypto_secretbox($message, $n, $k);
is(crypto_secretbox_open($enciphered, $n, $k), $message, "Testing roundtrip of crypto_secretbox");
+my $empty = crypto_secretbox('', $n, $k);
+is(crypto_secretbox_open($empty, $n, $k), '', "Testing we can encrypt/decrypt empty string");
+
# public key crypto
my ($pk1, $sk1) = box_keypair();
my ($pk2, $sk2) = box_keypair();