From 6a32252403781b303d4ebd195932ce39c5b1c08e Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 30 Jul 2019 16:03:58 +0200 Subject: Update to 5.43 --- hacks/glx/sonar-icmp.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) (limited to 'hacks/glx/sonar-icmp.c') diff --git a/hacks/glx/sonar-icmp.c b/hacks/glx/sonar-icmp.c index 862f358..961dcf5 100644 --- a/hacks/glx/sonar-icmp.c +++ b/hacks/glx/sonar-icmp.c @@ -1,4 +1,4 @@ -/* sonar, Copyright (c) 1998-2018 Jamie Zawinski and Stephen Martin +/* sonar, Copyright (c) 1998-2019 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 @@ -68,6 +68,9 @@ # ifdef HAVE_GETIFADDRS # include # endif +# ifdef HAVE_LIBCAP +# include +# endif #endif /* HAVE_ICMP || HAVE_ICMPHDR */ #if defined(HAVE_ICMP) @@ -1483,7 +1486,7 @@ parse_mode (sonar_sensor_data *ssd, char **error_ret, char **desc_ret, if (!ping_works_p) { - *error_ret = strdup ("Sonar must be setuid to ping!\n" + *error_ret = strdup ("Sonar must be setuid or libcap to ping!\n" "Running simulation instead."); return 0; } @@ -1569,6 +1572,46 @@ parse_mode (sonar_sensor_data *ssd, char **error_ret, char **desc_ret, } +static Bool +set_net_raw_capalibity(int enable_p) +{ + Bool ret_status = False; +# ifdef HAVE_LIBCAP + cap_t cap_status; + cap_value_t cap_value[] = { CAP_NET_RAW, }; + cap_flag_value_t cap_flag_value; + cap_flag_value_t new_value = enable_p ? CAP_SET : CAP_CLEAR; + + cap_status = cap_get_proc(); + do { + cap_flag_value = CAP_CLEAR; + if (cap_get_flag (cap_status, CAP_NET_RAW, CAP_EFFECTIVE, &cap_flag_value)) + break; + if (cap_flag_value == new_value) + { + ret_status = True; + break; + } + + cap_set_flag (cap_status, CAP_EFFECTIVE, 1, cap_value, new_value); + if (!cap_set_proc(cap_status)) + ret_status = True; + } while (0); + + if (cap_status) cap_free (cap_status); +# endif /* HAVE_LIBCAP */ + + return ret_status; +} + +static Bool +set_ping_capability (void) +{ + if (geteuid() == 0) return True; + return set_net_raw_capalibity (True); +} + + sonar_sensor_data * sonar_init_ping (Display *dpy, char **error_ret, char **desc_ret, const char *subnet, int timeout, @@ -1615,6 +1658,10 @@ sonar_init_ping (Display *dpy, char **error_ret, char **desc_ret, 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. */ if (global_icmpsock) { @@ -1628,7 +1675,7 @@ sonar_init_ping (Display *dpy, char **error_ret, char **desc_ret, { socket_initted_p = True; } - else if (geteuid() == 0 && + else if (set_ping_capability() && (pd->icmpsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) >= 0) { socket_initted_p = True; -- cgit v1.2.3-55-g7522