Skip to content

Commit

Permalink
More SIGINT fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
david-dick committed Jan 20, 2025
1 parent 70df95b commit 5dbac1d
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 52 deletions.
103 changes: 57 additions & 46 deletions lib/Crypt/URandom.pm
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ use constant GETRANDOM_AVAILABLE => do {
};
$result;
};
use constant SYSTEM_CALL_FAILED => -1;

## use critic

Expand Down Expand Up @@ -166,61 +167,71 @@ sub _urandom {
if ( !GETRANDOM_AVAILABLE() ) {
_init();
}
my $original_length = $length;
my $urandom;
BUFFER_FILLED: {
if ( OS_WIN32() ) {
$urandom = chr(0) x $length;
if ($_cryptgenrandom) {
if ( OS_WIN32() ) {
my $urandom = chr(0) x $length;
if ($_cryptgenrandom) {

my $result =
$_cryptgenrandom->Call( $_context, $length, $urandom );
if ( !$result ) {
Carp::croak("CryptGenRandom failed: $EXTENDED_OS_ERROR");
}
my $result = $_cryptgenrandom->Call( $_context, $length, $urandom );
if ( !$result ) {
Carp::croak("CryptGenRandom failed: $EXTENDED_OS_ERROR");
}
elsif ($_rtlgenrand) {
}
elsif ($_rtlgenrand) {

my $result = $_rtlgenrand->Call( $urandom, $length );
if ( !$result ) {
Carp::croak("RtlGenRand failed: $EXTENDED_OS_ERROR");
}
my $result = $_rtlgenrand->Call( $urandom, $length );
if ( !$result ) {
Carp::croak("RtlGenRand failed: $EXTENDED_OS_ERROR");
}
}
elsif ( GETRANDOM_AVAILABLE() ) {
return getrandom($length);
return $urandom;
}
elsif ( GETRANDOM_AVAILABLE() ) {
return getrandom($length);
}
else {
return _read_urandom_fs( $type, $length );
}
return;
}

sub _read_urandom_fs {
my ( $type, $length ) = @_;
my $original_length = $length;
my $urandom;
BUFFER_FILLED: {
my $result;
if ( defined $urandom ) {
$length = $original_length - ( length $urandom );
$result = $_urandom_handle->$type( my $buffer, $length );
if ( defined $buffer ) {
$urandom .= $buffer;
}
}
else {
my $result;
if ( defined $urandom ) {
$length = $original_length - ( length $urandom );
$result .= $_urandom_handle->$type( my $buffer, $length );
if ( defined $result ) {
$urandom .= $buffer;
}
}
else {
$result = $_urandom_handle->$type( my $buffer, $length );
if ( defined $result ) {
$urandom .= $buffer;
}
}
if ( ( defined $urandom )
&& ( length $urandom == $original_length ) )
{
return $urandom;
}
elsif ( $OS_ERROR == POSIX::EINTR() ) {
redo BUFFER_FILLED;
}
else {
my $returned_bytes = length $urandom;
my $error = $EXTENDED_OS_ERROR;
$_urandom_handle = undef;
$_initialised = undef;
Carp::croak( q[Failed to read from ] . PATH() . qq[:$error] );
$result = $_urandom_handle->$type( my $buffer, $length );
if ( defined $buffer ) {
$urandom .= $buffer;
}
}
if ( ( defined $urandom )
&& ( length $urandom == $original_length ) )
{
}
elsif (( $result == SYSTEM_CALL_FAILED() )
&& ( $OS_ERROR == POSIX::EINTR() ) )
{
redo BUFFER_FILLED;
}
elsif ( $result != SYSTEM_CALL_FAILED() ) {
redo BUFFER_FILLED;
}
else {
my $returned_bytes = length $urandom;
my $error = $EXTENDED_OS_ERROR;
$_urandom_handle = undef;
$_initialised = undef;
Carp::croak( q[Failed to read from ] . PATH() . qq[:$error] );
}
}
return $urandom;
}
Expand Down
13 changes: 9 additions & 4 deletions t/core_partial_read.t
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ SKIP: {
skip("No functions to override in Win32", 1);
} else {
no warnings;
*CORE::GLOBAL::read = sub { $_[1] = q[]; $! = POSIX::EAGAIN(); return 0 };
*CORE::GLOBAL::sysread = sub { $_[1] = q[]; $! = POSIX::EAGAIN(); return 0 };
*CORE::GLOBAL::read = sub { $_[1] = undef; $! = POSIX::EAGAIN(); return -1 };
*CORE::GLOBAL::sysread = sub { $_[1] = undef; $! = POSIX::EAGAIN(); return -1 };
use warnings;
my $required_error_message = quotemeta "Failed to read from";
require FileHandle;
Expand All @@ -41,18 +41,23 @@ SKIP: {
my @sample_random_data = ('a', 'bc');
no warnings;
*CORE::GLOBAL::read = sub { $_[1] = shift @sample_random_data; $! = POSIX::EINTR(); return length $_[1] };
*CORE::GLOBAL::sysread = sub { $_[1] = shift @sample_random_data; $! = POSIX::EINTR(); return length $_[1] };
use warnings;
my $expected_result = join q[], @sample_random_data;
my $actual_result = Crypt::URandom::urandom(3);
ok($actual_result eq $expected_result, "Correctly survived an EINTR in urandom:$actual_result vs $expected_result");
@sample_random_data = ('a', 'bc');
no warnings;
*CORE::GLOBAL::read = sub { $_[1] = shift @sample_random_data; $! = POSIX::EINTR(); return length $_[1] };
*CORE::GLOBAL::sysread = sub { $_[1] = shift @sample_random_data; $! = POSIX::EINTR(); return length $_[1] };
use warnings;
$actual_result = Crypt::URandom::urandom_ub(3);
ok($actual_result eq $expected_result, "Correctly survived an EINTR in urandom_nb:$actual_result vs $expected_result");
@sample_random_data = ('a', 'bc');
my $count = 0;
no warnings;
*CORE::GLOBAL::sysread = sub { $count += 1; if ($count == 1 || $count == 3) { $_[1] = undef; $! == POSIX::EINTR(); return -1 } else { $_[1] = shift @sample_random_data; ($count == 2 ? $! =0 : $! = POSIX::EINTR()); return length $_[1] } };
use warnings;
$actual_result = Crypt::URandom::urandom_ub(3);
ok($actual_result eq $expected_result, "Correctly survived an EINTR in urandom_nb:$actual_result vs $expected_result");
}
}
done_testing();
4 changes: 2 additions & 2 deletions t/core_read.t
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ SKIP: {
ok(!$generated && $@ =~ /$required_error_message/smx, "Correct exception thrown when Win32::API->new() is overridden:$@");
} else {
no warnings;
*CORE::GLOBAL::read = sub { $! = POSIX::EACCES(); return };
*CORE::GLOBAL::sysread = sub { $! = POSIX::EACCES(); return };
*CORE::GLOBAL::read = sub { $! = POSIX::EACCES(); return -1 };
*CORE::GLOBAL::sysread = sub { $! = POSIX::EACCES(); return -1 };
use warnings;
my $required_error_message = q[(?:] . (quotemeta POSIX::strerror(POSIX::EACCES())) . q[|Permission[ ]denied)];
require FileHandle;
Expand Down

0 comments on commit 5dbac1d

Please sign in to comment.