]> git.gsnw.org Git - fping.git/commitdiff
fix unprivileged ping broken in v5.1 (fixes #248)
authorDavid Schweikert <david@schweikert.ch>
Sun, 13 Feb 2022 16:45:57 +0000 (17:45 +0100)
committerDavid Schweikert <david@schweikert.ch>
Sat, 5 Mar 2022 15:14:29 +0000 (16:14 +0100)
.github/workflows/test.yml
ci/test-11-nopriv-fail.pl [deleted file]
ci/test-11-unpriv.pl [new file with mode: 0755]
src/fping.c

index ec22307b9e3d2d252cac447a236abd9f86153a66..7c724ceb42266be859dfa0788425eff00c5ecf2d 100644 (file)
@@ -14,6 +14,7 @@ jobs:
         run: |
           sudo apt-get update -qq 
           sudo apt-get install libcap2-bin libtest-command-perl lcov
+          sudo sysctl net.ipv4.ping_group_range='0 2147483647'
 
       - name: Build
         run: |
diff --git a/ci/test-11-nopriv-fail.pl b/ci/test-11-nopriv-fail.pl
deleted file mode 100755 (executable)
index 243362e..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/perl -w
-
-use English;
-use Test::Command;
-use Test::More;
-
-if( $^O eq 'darwin' ) {
-    plan skip_all => 'Test irrelevant on MacOS';
-    exit 0;
-}
-
-sub get_ping_gid_range {
-       open FD, "/proc/sys/net/ipv4/ping_group_range" or return undef;
-       chomp(my $line = <FD>);
-       my @range = split(/\s+/, $line);
-       close FD;
-       return @range;
-}
-
-my @gids = split(' ', $EGID);
-my @allowed_gid_range = get_ping_gid_range();
-
-# Linux test for unprivileged ping support
-foreach(@gids) {
-       if ($_ >= $allowed_gid_range[0] && $_ <= $allowed_gid_range[1]) {
-               plan skip_all => "Userspace pings are allowed, gid $_ in range [$allowed_gid_range[0], $allowed_gid_range[1]]";
-               exit 0;
-       }
-}
-
-plan tests => 3;
-
-# run without privileges
-my $fping_bin = `which fping`; chomp $fping_bin;
-system("cp $fping_bin /tmp/fping.copy; chmod +x /tmp/fping.copy");
-
-# fping
-{
-my $cmd = Test::Command->new(cmd => "/tmp/fping.copy 127.0.0.1");
-$cmd->exit_is_num(4);
-$cmd->stdout_is_eq("");
-$cmd->stderr_like(qr{: can't create socket \(must run as root\?\)});
-}
diff --git a/ci/test-11-unpriv.pl b/ci/test-11-unpriv.pl
new file mode 100755 (executable)
index 0000000..9141c3e
--- /dev/null
@@ -0,0 +1,57 @@
+#!/usr/bin/perl -w
+
+use English;
+use Test::Command;
+use Test::More;
+
+if( $^O eq 'darwin' ) {
+    plan skip_all => 'Test irrelevant on MacOS';
+    exit 0;
+}
+
+sub get_ping_gid_range {
+    open FD, "/proc/sys/net/ipv4/ping_group_range" or return undef;
+    chomp(my $line = <FD>);
+    my @range = split(/\s+/, $line);
+    close FD;
+    return @range;
+}
+
+my @gids = split(' ', $EGID);
+my @allowed = get_ping_gid_range();
+
+# Make a copy of the binary so that we get rid of setuid bit
+my $fping_bin = `which fping`; chomp $fping_bin;
+system("cp $fping_bin /tmp/fping.copy; chmod +x /tmp/fping.copy");
+
+# Determine what test to run, based on whether unprivileged
+# pings are allowed.
+if(scalar grep { $_ >= $allowed[0] && $_ <= $allowed[1] } @gids) {
+    diag('test unprivileged mode');
+    test_unprivileged_works();
+}
+else {
+    test_privileged_fails();
+}
+
+sub test_unprivileged_works {
+    plan tests => 3;
+
+    {
+        my $cmd = Test::Command->new(cmd => "fping 127.0.0.1");
+        $cmd->exit_is_num(0);
+        $cmd->stdout_is_eq("127.0.0.1 is alive\n");
+        $cmd->stderr_is_eq("");
+    }
+}
+
+sub test_privileged_fails {
+    plan tests => 3;
+
+    {
+        my $cmd = Test::Command->new(cmd => "/tmp/fping.copy 127.0.0.1");
+        $cmd->exit_is_num(4);
+        $cmd->stdout_is_eq("");
+        $cmd->stderr_like(qr{: can't create socket \(must run as root\?\)});
+    }
+}
index e26b216c2a31cc1ee6ca64d648744ad86398733d..0bd2b70c0cfe49affdca63699f6e8c9f2afe3ac4 100644 (file)
@@ -1104,11 +1104,11 @@ int main(int argc, char** argv)
         exit(num_noaddress ? 2 : 1);
     }
 
-    if (src_addr_set && socket4 >= 0) {
+    if (socket4 >= 0 && (src_addr_set || socktype4 == SOCK_DGRAM)) {
         socket_set_src_addr_ipv4(socket4, &src_addr, (socktype4 == SOCK_DGRAM) ? &ident4 : NULL);
     }
 #ifdef IPV6
-    if (src_addr6_set && socket6 >= 0) {
+    if (socket6 >= 0 && (src_addr6_set || socktype4 == SOCK_DGRAM)) {
         socket_set_src_addr_ipv6(socket6, &src_addr6, (socktype6 == SOCK_DGRAM) ? &ident6 : NULL);
     }
 #endif