From 69f9e16e6d1d7b2d0caccbcd2fd822d7d6403b7f Mon Sep 17 00:00:00 2001 From: Jan Synacek Date: Tue, 26 Jun 2012 09:36:08 +0200 Subject: [PATCH] Ping fixes: + enable marking packets when the correct capabilities are set (#802197) --- ...defer-caps-drop-when-marking-packets.patch | 150 ++++++++++++++++++ iputils.spec | 8 +- 2 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 iputils-20101006-ping-defer-caps-drop-when-marking-packets.patch diff --git a/iputils-20101006-ping-defer-caps-drop-when-marking-packets.patch b/iputils-20101006-ping-defer-caps-drop-when-marking-packets.patch new file mode 100644 index 0000000..b0df208 --- /dev/null +++ b/iputils-20101006-ping-defer-caps-drop-when-marking-packets.patch @@ -0,0 +1,150 @@ +--- iputils-s20101006/ping.c 2012-06-25 09:53:03.779506643 +0200 ++++ iputils-s20101006-patch/ping.c 2012-06-25 10:40:17.610143823 +0200 +@@ -66,10 +66,6 @@ char copyright[] = + #include + #include + +-#ifdef HAVE_CAPABILITIES +-#include +-#endif +- + #ifndef ICMP_FILTER + #define ICMP_FILTER 1 + struct icmp_filter { +@@ -119,7 +115,6 @@ struct sockaddr_in source; + char *device; + int pmtudisc = -1; + +- + int + main(int argc, char **argv) + { +@@ -130,7 +125,8 @@ main(int argc, char **argv) + char *target, hnamebuf[MAX_HOSTNAMELEN]; + char rspace[3 + 4 * NROUTES + 1]; /* record route space */ + #ifdef HAVE_CAPABILITIES +- cap_t caps; ++ cap_t cap; ++ cap_flag_value_t net_admin_set = CAP_CLEAR; + #endif + + char *idn; +@@ -147,13 +143,21 @@ main(int argc, char **argv) + } + + #ifdef HAVE_CAPABILITIES +- /* drop all capabilities unconditionally so even root isn't special anymore */ +- caps = cap_init(); +- if (cap_set_proc(caps) < 0) { +- perror("ping: cap_set_proc"); ++ /* check for cap_net_admin because it may be needed to set packet marks */ ++ if ((cap = cap_get_proc()) == NULL) { ++ perror("ping: cap_get_proc"); + exit(-1); + } +- cap_free(caps); ++ if (cap_get_flag(cap, CAP_NET_ADMIN, CAP_EFFECTIVE, &net_admin_set) != 0) { ++ perror("ping: cap_get_flag"); ++ exit(-1); ++ } ++ cap_free(cap); ++ ++ /* if CAP_NET_ADMIN is not set, drop all capabilities now, otherwise defer ++ * dropping after the SO_MARK sock opt is set */ ++ if (net_admin_set == CAP_CLEAR) ++ drop_capabilities(); + #endif + + source.sin_family = AF_INET; +--- iputils-s20101006/ping6.c 2012-06-26 08:55:58.751744660 +0200 ++++ iputils-s20101006-patch/ping6.c 2012-06-26 08:57:38.276803832 +0200 +@@ -73,10 +73,6 @@ char copyright[] = + #include + #include + +-#ifdef HAVE_CAPABILITIES +-#include +-#endif +- + #include "ping6_niquery.h" + #include "in6_flowlabel.h" + +@@ -538,7 +534,8 @@ int main(int argc, char *argv[]) + #endif + static uint32_t scope_id = 0; + #ifdef HAVE_CAPABILITIES +- cap_t caps; ++ cap_t cap; ++ cap_flag_value_t net_admin_set = CAP_CLEAR; + #endif + + icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); +@@ -551,13 +548,21 @@ int main(int argc, char *argv[]) + } + + #ifdef HAVE_CAPABILITIES +- /* drop all capabilities unconditionally so even root isn't special anymore */ +- caps = cap_init(); +- if (cap_set_proc(caps) < 0) { +- perror("ping: cap_set_proc"); ++ /* check for cap_net_admin because it may be needed to set packet marks */ ++ if ((cap = cap_get_proc()) == NULL) { ++ perror("ping: cap_get_proc"); + exit(-1); + } +- cap_free(caps); ++ if (cap_get_flag(cap, CAP_NET_ADMIN, CAP_EFFECTIVE, &net_admin_set) != 0) { ++ perror("ping: cap_get_flag"); ++ exit(-1); ++ } ++ cap_free(cap); ++ ++ /* if CAP_NET_ADMIN is not set, drop all capabilities now, otherwise defer ++ * dropping after the SO_MARK sock opt is set */ ++ if (net_admin_set == CAP_CLEAR) ++ drop_capabilities(); + #endif + + source.sin6_family = AF_INET6; +--- iputils-s20101006/ping_common.h 2010-10-06 13:59:20.000000000 +0200 ++++ iputils-s20101006-patch/ping_common.h 2012-06-25 10:43:21.676189489 +0200 +@@ -17,6 +17,10 @@ + #include + #include + ++#ifdef HAVE_CAPABILITIES ++#include ++#endif ++ + #include + #include + #include +@@ -188,6 +192,15 @@ static inline void advance_ntransmitted( + acked = (__u16)ntransmitted + 1; + } + ++static inline void drop_capabilities(void) ++{ ++ cap_t cap = cap_init(); ++ if (cap_set_proc(cap) < 0) { ++ perror("ping: cap_set_proc"); ++ exit(-1); ++ } ++ cap_free(cap); ++} + + extern int send_probe(void); + extern int receive_error_msg(void); +--- iputils-s20101006/ping_common.c 2012-06-25 09:53:03.705506619 +0200 ++++ iputils-s20101006-patch/ping_common.c 2012-06-25 10:40:40.220150202 +0200 +@@ -486,6 +486,10 @@ void setup(int icmp_sock) + * dont support mark .. + */ + fprintf(stderr, "Warning: Failed to set mark %d\n", mark); ++#ifdef HAVE_CAPABILITIES ++ /* in case we deferred dropping capabilities because of SO_MARK */ ++ drop_capabilities(); ++#endif + } + } + diff --git a/iputils.spec b/iputils.spec index b38af2c..a14b3a0 100644 --- a/iputils.spec +++ b/iputils.spec @@ -1,7 +1,7 @@ Summary: Network monitoring tools including ping Name: iputils Version: 20101006 -Release: 14%{?dist} +Release: 15%{?dist} License: BSD URL: http://www.skbuff.net/iputils Group: System Environment/Daemons @@ -31,6 +31,7 @@ Patch15: iputils-20101006-unused.patch Patch16: iputils-20101006-man.patch Patch17: iputils-20101006-eth.patch Patch18: iputils-20101006-rr.patch +Patch20: iputils-20101006-ping-defer-caps-drop-when-marking-packets.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: docbook-utils perl-SGMLSpm @@ -88,6 +89,7 @@ The iputils-sysvinit contains SysV initscritps support. %patch16 -p1 -b .man %patch17 -p1 -b .eth %patch18 -p1 -b .rr +%patch20 -p1 %build %ifarch s390 s390x @@ -191,6 +193,10 @@ rm -rf ${RPM_BUILD_ROOT} %{_sysconfdir}/rc.d/init.d/rdisc %changelog +* Mon Jun 25 2012 Jan Synáček 20101006-15 +- Ping fixes: + + enable marking packets when the correct capabilities are set (#802197) + * Wed Jan 25 2012 Harald Hoyer 20101006-14 - install everything in /usr https://fedoraproject.org/wiki/Features/UsrMove