oping: Disable the “-f” option when real and effective user IDs don't match.
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Tue, 29 Sep 2009 15:44:05 +0000 (17:44 +0200)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Tue, 29 Sep 2009 15:44:05 +0000 (17:44 +0200)
Thanks to Steve Kemp who reported this issue as Debian bug #548684.
<http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=548684>

src/mans/oping.pod
src/oping.c

index 8a3cb58..fc8911d 100644 (file)
@@ -58,6 +58,10 @@ Set the outgoing network device to use.
 Instead of specifying hostnames on the command line, read them from
 I<filename>. If I<filename> is B<->, read from C<STDIN>.
 
+This option is only available if the real user ID (as returned by L<getuid(2)>)
+and the effective user ID (as returned by L<geteuid(2)>) match. This is meant
+to avoid security issues when I<oping> is installed with the SUID-bit.
+
 =back
 
 =head1 SEE ALSO
index fc4cb5f..8419710 100644 (file)
@@ -27,6 +27,7 @@
 # include <string.h>
 # include <errno.h>
 # include <assert.h>
+# include <unistd.h>
 #else
 # error "You don't have the standard C99 header files installed"
 #endif /* STDC_HEADERS */
@@ -133,6 +134,11 @@ static void usage_exit (const char *name, int status)
        exit (status);
 }
 
+static _Bool is_setuid (void)
+{
+       return (getuid () != geteuid ());
+}
+
 static int read_options (int argc, char **argv)
 {
        int optchar;
@@ -164,6 +170,13 @@ static int read_options (int argc, char **argv)
                                break;
 
                        case 'f':
+                               if (is_setuid ())
+                               {
+                                       fprintf (stderr, "For security reasons the `-f' option "
+                                                       "is disabled if real and effective "
+                                                       "user IDs don't match. Sorry.\n");
+                               }
+                               else
                                {
                                        if (opt_filename != NULL)
                                                free (opt_filename);