From 38886de0c3e9ea5729ef23e4c653fa2822f52e8f Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 6 Apr 2021 14:43:39 +0200 Subject: xscreensaver 6.00 --- hacks/glx/sonar-icmp.c | 61 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 19 deletions(-) (limited to 'hacks/glx/sonar-icmp.c') diff --git a/hacks/glx/sonar-icmp.c b/hacks/glx/sonar-icmp.c index 658074b..b23b6bf 100644 --- a/hacks/glx/sonar-icmp.c +++ b/hacks/glx/sonar-icmp.c @@ -1,4 +1,4 @@ -/* sonar, Copyright (c) 1998-2020 Jamie Zawinski and Stephen Martin +/* sonar, Copyright © 1998-2021 Jamie Zawinski and Stephen Martin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -18,11 +18,15 @@ #undef usleep /* conflicts with unistd.h on OSX */ -#ifdef USE_IPHONE +#ifdef HAVE_IPHONE /* Note: to get this to compile for iPhone, you need to fix Xcode! The icmp headers exist for the simulator build environment, but not for the real-device build environment. This appears to - just be an Apple bug, not intentional. + just be an Apple bug, not intentional. But it has existed for + many years. + + The "ICMP Sanity Check" build phase in the Xcode project checks + this and tells you what to do. xc=/Applications/Xcode.app/Contents for path in /Developer/Platforms/iPhone*?/Developer/SDKs/?* \ @@ -452,12 +456,13 @@ read_hosts_file (sonar_sensor_data *ssd, const char *filename) fp = fopen(filename, "r"); if (!fp) { - char buf2[1024]; - sprintf(buf2, "%s: %s", progname, filename); #ifdef HAVE_JWXYZ if (pd->debug_p) /* on OSX don't syslog this */ #endif - perror (buf2); + { + char *str_error = strerror(errno); + fprintf(stderr, "%s: %s: %s", progname, filename, str_error); + } return 0; } @@ -1248,7 +1253,7 @@ get_ping (sonar_sensor_data *ssd) if (strlen(s) > 28) { s2 = s + strlen(s) - 28; - strncpy (s2, "...", 3); + memcpy (s2, "...", 3); } fprintf (stdout, "%3d bytes from %28s: icmp_seq=%-4d time=%s\n", @@ -1494,8 +1499,13 @@ parse_mode (sonar_sensor_data *ssd, char **error_ret, char **desc_ret, if (!ping_works_p) { +# ifdef HAVE_LIBCAP *error_ret = strdup ("Sonar must be setuid or libcap to ping!\n" "Running simulation instead."); +# else + *error_ret = strdup ("Sonar must be setuid to ping!\n" + "Running simulation instead."); +# endif return 0; } @@ -1656,20 +1666,33 @@ sonar_init_ping (Display *dpy, char **error_ret, char **desc_ret, /* Create the ICMP socket. Do this before dropping privs. - Raw sockets can only be opened by root (or setuid root), so we - only try to do this when the effective uid is 0. + Raw sockets can only be opened by root (or setuid root), so we only try + to do this when the effective uid is 0. + + We used to just always try, and notice the failure. But apparently that + causes "SELinux" to log spurious warnings when running with the "strict" + policy. So to avoid that, we just don't try unless we know it will work. + + On MacOS X, we can avoid the whole problem by using a non-privileged + datagram instead of a raw socket. + + On recent Linux systems (2012-ish?) we can avoid setuid by instead using + cap_set_flag(... CAP_NET_RAW). To make that call the executable needs to + have "sudo setcap cap_net_raw=p sonar" done to it first. - We used to just always try, and notice the failure. But apparently - that causes "SELinux" to log spurious warnings when running with the - "strict" policy. So to avoid that, we just don't try unless we - know it will work. + Except, it turns out that $MESA_LOADER_DRIVER_OVERRIDE would then let you + run arbitrary other programs with access to raw sockets. It's possible + that un-setting $MESA_LOADER_DRIVER_OVERRIDE early in main() would prevent + this, but Mesa uses a ton of environment variables, and who knows what + other crap is lurking in there. So that's just great. - On MacOS X, we can avoid the whole problem by using a - non-privileged datagram instead of a raw socket. + Ironically, being setuid root is *more* secure, as Mesa happens to contain + code that says, "Hey, maybe I shouldn't link in arbitrary other .so files + when I'm root". - On recent Linux systems (2012-ish?) we can avoid setuid by instead - using cap_set_flag(... CAP_NET_RAW). To make that call the executable - needs to have "sudo setcap cap_net_raw=p sonar" done to it first. + This trick does not work with $LD_PRELOAD because the kernel checks auxv + for AT_SECURE and won't run $LD_PRELOAD if setcap is in use, whereas Mesa + only checks geteuid. */ if (global_icmpsock) { @@ -1735,7 +1758,7 @@ sonar_init_ping (Display *dpy, char **error_ret, char **desc_ret, if (! *error_ret) *error_ret = strdup ("No hosts to ping!\n" "Simulating instead."); - if (pd) ping_free_data (ssd, pd); + ping_free_data (ssd, pd); if (ssd) free (ssd); return 0; } -- cgit v1.2.3-55-g7522