summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doio.c6
-rw-r--r--ext/Test-Harness/t/sample-tests/taint2
-rw-r--r--ext/Test-Harness/t/sample-tests/taint_warn2
-rw-r--r--pod/perl5110delta.pod7
-rw-r--r--pod/perldiag.pod6
-rw-r--r--pod/perlfunc.pod12
-rw-r--r--t/op/kill0.t16
7 files changed, 43 insertions, 8 deletions
diff --git a/doio.c b/doio.c
index 7be7af1142..1e9d7d9347 100644
--- a/doio.c
+++ b/doio.c
@@ -1726,6 +1726,8 @@ nothing in the core.
* CRTL's emulation of Unix-style signals and kill()
*/
while (++mark <= sp) {
+ if (!(SvIOK(*mark) || SvNOK(*mark) || looks_like_number(*mark)))
+ Perl_croak(aTHX_ "Can't kill a non-numeric process ID");
I32 proc = SvIV(*mark);
register unsigned long int __vmssts;
APPLY_TAINT_PROPER();
@@ -1750,6 +1752,8 @@ nothing in the core.
if (val < 0) {
val = -val;
while (++mark <= sp) {
+ if (!(SvIOK(*mark) || SvNOK(*mark) || looks_like_number(*mark)))
+ Perl_croak(aTHX_ "Can't kill a non-numeric process ID");
const I32 proc = SvIV(*mark);
APPLY_TAINT_PROPER();
#ifdef HAS_KILLPG
@@ -1762,6 +1766,8 @@ nothing in the core.
}
else {
while (++mark <= sp) {
+ if (!(SvIOK(*mark) || SvNOK(*mark) || looks_like_number(*mark)))
+ Perl_croak(aTHX_ "Can't kill a non-numeric process ID");
const I32 proc = SvIV(*mark);
APPLY_TAINT_PROPER();
if (PerlProc_kill(proc, val))
diff --git a/ext/Test-Harness/t/sample-tests/taint b/ext/Test-Harness/t/sample-tests/taint
index b67d719fc7..c36698e042 100644
--- a/ext/Test-Harness/t/sample-tests/taint
+++ b/ext/Test-Harness/t/sample-tests/taint
@@ -3,5 +3,5 @@
use lib qw(t/lib);
use Test::More tests => 1;
-eval { kill 0, $^X };
+eval { `$^X -e1` };
like( $@, '/^Insecure dependency/', '-T honored' );
diff --git a/ext/Test-Harness/t/sample-tests/taint_warn b/ext/Test-Harness/t/sample-tests/taint_warn
index 768f527326..398d6181ee 100644
--- a/ext/Test-Harness/t/sample-tests/taint_warn
+++ b/ext/Test-Harness/t/sample-tests/taint_warn
@@ -6,6 +6,6 @@ use Test::More tests => 1;
my $warnings = '';
{
local $SIG{__WARN__} = sub { $warnings .= join '', @_ };
- kill 0, $^X;
+ `$^X -e1`;
}
like( $warnings, '/^Insecure dependency/', '-t honored' );
diff --git a/pod/perl5110delta.pod b/pod/perl5110delta.pod
index e9e9efa160..c49c0e7b4c 100644
--- a/pod/perl5110delta.pod
+++ b/pod/perl5110delta.pod
@@ -185,6 +185,13 @@ See L</"The C<overloading> pragma"> above.
as documented, and as does C<-I> when specified on the command-line.
(Renée Bäcker)
+=item C<kill> is now fatal when called on non-numeric process identifiers
+
+Previously, an 'undef' process identifier would be interpreted as a request to
+kill process "0", which would terminate the current process group on POSIX
+systems. Since process identifiers are always integers, killing a non-numeric
+process is now fatal.
+
=back
=head1 New or Changed Diagnostics
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index dc0c5ea3ee..9d58104ab8 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -830,6 +830,12 @@ processes, Perl has reset the signal to its default value. This
situation typically indicates that the parent program under which Perl
may be running (e.g. cron) is being very careless.
+=item Can't kill a non-numeric process ID
+
+(F) Process identifiers must be (signed) integers. It is a fatal error to
+attempt to kill() an undefined, empty-string or otherwise non-numeric
+process identifier.
+
=item Can't "last" outside a loop block
(F) A "last" statement was executed to break out of the current block,
diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod
index 2035795bb6..23e5535e4f 100644
--- a/pod/perlfunc.pod
+++ b/pod/perlfunc.pod
@@ -2631,11 +2631,13 @@ the super-user). This is a useful way to check that a child process is
alive (even if only as a zombie) and hasn't changed its UID. See
L<perlport> for notes on the portability of this construct.
-Unlike in the shell, if SIGNAL is negative, it kills
-process groups instead of processes. (On System V, a negative I<PROCESS>
-number will also kill process groups, but that's not portable.) That
-means you usually want to use positive not negative signals. You may also
-use a signal name in quotes.
+Unlike in the shell, if SIGNAL is negative, it kills process groups instead
+of processes. That means you usually want to use positive not negative signals.
+You may also use a signal name in quotes.
+
+The behavior of kill when a I<PROCESS> number is zero or negative depends on
+the operating system. For example, on POSIX-conforming systems, zero will
+signal the current process group and -1 will signal all processes.
See L<perlipc/"Signals"> for more details.
diff --git a/t/op/kill0.t b/t/op/kill0.t
index 063c38897b..eadf15dc36 100644
--- a/t/op/kill0.t
+++ b/t/op/kill0.t
@@ -14,7 +14,7 @@ BEGIN {
use strict;
-plan tests => 2;
+plan tests => 5;
ok( kill(0, $$), 'kill(0, $pid) returns true if $pid exists' );
@@ -29,3 +29,17 @@ for my $pid (1 .. $total) {
# It is highly unlikely that all of the above PIDs are genuinely in use,
# so $count should be less than $total.
ok( $count < $total, 'kill(0, $pid) returns false if $pid does not exist' );
+
+# Verify that trying to kill a non-numeric PID is fatal
+my @bad_pids = (
+ [ undef , 'undef' ],
+ [ '' , 'empty string' ],
+ [ 'abcd', 'alphabetic' ],
+);
+
+for my $case ( @bad_pids ) {
+ my ($pid, $name) = @$case;
+ eval { kill 0, $pid };
+ like( $@, qr/^Can't kill a non-numeric process ID/, "dies killing $name pid");
+}
+