ALT Linux repositórios
Group :: Rede/Outros
RPM: iputils
Main Changelog Spec Patches Sources Download Gear Bugs e FR Repocop
Patch: iputils-20210722-alt3.patch
Download
Download
arping.c | 74 ++++-------------------
clockdiff.c | 12 ++--
doc/arping.xml | 4 +-
doc/clockdiff.xml | 4 +-
doc/meson.build | 39 +++++++++----
doc/ninfod.xml | 2 +-
doc/ping.xml | 2 +-
doc/rdisc.xml | 2 +-
doc/tracepath.xml | 8 +--
doc/traceroute6.xml | 10 ++--
fixfds.c | 27 +++++++++
fixfds.h | 6 ++
meson.build | 30 +++++-----
modcap.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++++
modcap.h | 11 ++++
ninfod/meson.build | 2 +
ninfod/ni_ifaddrs.c | 2 +-
ninfod/ninfod.c | 3 +
ping/meson.build | 2 +
ping/ping.c | 23 +++++---
ping/ping.h | 6 +-
ping/ping6_common.c | 2 +-
ping/ping_common.c | 79 ++++---------------------
tracepath.c | 11 ++++
traceroute6.c | 15 +++--
25 files changed, 341 insertions(+), 200 deletions(-)
diff --git a/arping.c b/arping.c
index 53fdbb4..d7e5555 100644
--- a/arping.c
+++ b/arping.c
@@ -31,10 +31,11 @@
#include <unistd.h>
#ifdef HAVE_LIBCAP
-# include <sys/capability.h>
-# include <sys/prctl.h>
+#include "modcap.h"
#endif
+#include "fixfds.h"
+
#include "iputils_common.h"
#ifdef DEFAULT_DEVICE
@@ -88,10 +89,6 @@ struct run_state {
unsolicited:1;
};
-#ifdef HAVE_LIBCAP
-static const cap_value_t caps[] = { CAP_NET_RAW };
-#endif
-
/*
* All includes, definitions, struct declarations, and global variables are
* above. After this comment all you can find is functions.
@@ -138,72 +135,19 @@ static void usage(void)
}
#ifdef HAVE_LIBCAP
-static void limit_capabilities(struct run_state *ctl)
+static void limit_capabilities(__attribute__((unused)) struct run_state *ctl)
{
- cap_t cap_p;
-
- cap_p = cap_get_proc();
- if (!cap_p)
- error(-1, errno, "cap_get_proc");
-
- cap_get_flag(cap_p, CAP_NET_RAW, CAP_PERMITTED, &ctl->cap_raw);
-
- if (ctl->cap_raw != CAP_CLEAR) {
- if (cap_clear(cap_p) < 0)
- error(-1, errno, "cap_clear");
-
- cap_set_flag(cap_p, CAP_PERMITTED, 1, caps, CAP_SET);
-
- if (cap_set_proc(cap_p) < 0) {
- error(0, errno, "cap_set_proc");
- if (errno != EPERM)
- exit(-1);
- }
- }
-
- if (prctl(PR_SET_KEEPCAPS, 1) < 0)
- error(-1, errno, "prctl");
-
- if (setuid(getuid()) < 0)
- error(-1, errno, "setuid");
-
- if (prctl(PR_SET_KEEPCAPS, 0) < 0)
- error(-1, errno, "prctl");
-
- cap_free(cap_p);
+ limit_capabilities_common(1, 0);
}
-static int modify_capability_raw(struct run_state *ctl, int on)
+static int modify_capability_raw(__attribute__((unused)) struct run_state *ctl, int on)
{
- cap_t cap_p;
-
- if (ctl->cap_raw != CAP_SET)
- return on ? -1 : 0;
-
- cap_p = cap_get_proc();
- if (!cap_p)
- error(-1, errno, "cap_get_proc");
-
- cap_set_flag(cap_p, CAP_EFFECTIVE, 1, caps, on ? CAP_SET : CAP_CLEAR);
-
- if (cap_set_proc(cap_p) < 0)
- error(-1, errno, "cap_set_proc");
-
- cap_free(cap_p);
- return 0;
+ return modify_capability_common(CAP_NET_RAW, on ? CAP_SET : CAP_CLEAR);
}
static void drop_capabilities(void)
{
- cap_t cap_p = cap_init();
-
- if (!cap_p)
- error(-1, errno, "cap_init");
-
- if (cap_set_proc(cap_p) < 0)
- error(-1, errno, "cap_set_proc");
-
- cap_free(cap_p);
+ drop_capabilities_common();
}
#else /* HAVE_LIBCAP */
static void limit_capabilities(struct run_state *ctl)
@@ -840,6 +784,8 @@ int main(int argc, char **argv)
};
int ch;
+ fix_fds();
+
atexit(close_stdout);
limit_capabilities(&ctl);
#if defined(USE_IDN) || defined(ENABLE_NLS)
diff --git a/clockdiff.c b/clockdiff.c
index 538bf78..1f8023f 100644
--- a/clockdiff.c
+++ b/clockdiff.c
@@ -75,8 +75,9 @@
#include <unistd.h>
#ifdef HAVE_LIBCAP
-# include <sys/capability.h>
+#include "modcap.h"
#endif
+#include "fixfds.h"
#include "iputils_common.h"
@@ -434,11 +435,8 @@ static int measure(struct run_state *ctl)
static void drop_rights(void)
{
#ifdef HAVE_LIBCAP
- cap_t caps = cap_init();
-
- if (cap_set_proc(caps))
- error(-1, errno, "cap_set_proc");
- cap_free(caps);
+ limit_capabilities_common(0, 0);
+ drop_capabilities_common();
#endif
if (setuid(getuid()))
error(-1, errno, "setuid");
@@ -523,6 +521,8 @@ int main(int argc, char **argv)
struct addrinfo *result;
int status;
+ fix_fds();
+
atexit(close_stdout);
parse_opts(&ctl, argc, argv);
diff --git a/doc/arping.xml b/doc/arping.xml
index 711718f..0a67f51 100644
--- a/doc/arping.xml
+++ b/doc/arping.xml
@@ -229,7 +229,7 @@ xml:id="man.arping">
<para>
<citerefentry>
<refentrytitle>ping</refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>clockdiff</refentrytitle>
@@ -237,7 +237,7 @@ xml:id="man.arping">
</citerefentry>,
<citerefentry>
<refentrytitle>tracepath</refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>1</manvolnum>
</citerefentry>.</para>
</refsect1>
diff --git a/doc/clockdiff.xml b/doc/clockdiff.xml
index 9643bea..609e766 100644
--- a/doc/clockdiff.xml
+++ b/doc/clockdiff.xml
@@ -165,7 +165,7 @@ xml:id="man.clockdiff">
<para>
<citerefentry>
<refentrytitle>ping</refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>arping</refentrytitle>
@@ -173,7 +173,7 @@ xml:id="man.clockdiff">
</citerefentry>,
<citerefentry>
<refentrytitle>tracepath</refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>1</manvolnum>
</citerefentry>.</para>
</refsect1>
diff --git a/doc/meson.build b/doc/meson.build
index 30aca2d..4cc0fcc 100644
--- a/doc/meson.build
+++ b/doc/meson.build
@@ -1,43 +1,47 @@
manpages = []
+manpages1 = []
+manpages8 = []
custom_man_xsl = files('custom-man.xsl')
custom_html_xsl = files('custom-html.xsl')
if build_arping == true
- manpages += ['arping']
+ manpages8 += ['arping']
endif
if build_clockdiff == true
- manpages += ['clockdiff']
+ manpages8 += ['clockdiff']
endif
if build_ping == true
- manpages += ['ping']
+ manpages1 += ['ping']
endif
if build_rarpd == true
- manpages += ['rarpd']
+ manpages8 += ['rarpd']
endif
if build_rdisc == true
- manpages += ['rdisc']
+ manpages8 += ['rdisc']
endif
if build_tftpd == true
- manpages += ['tftpd']
+ manpages8 += ['tftpd']
endif
if build_tracepath == true
- manpages += ['tracepath']
+ manpages1 += ['tracepath']
endif
if build_traceroute6 == true
- manpages += ['traceroute6']
+ manpages1 += ['traceroute6']
endif
if build_ninfod == true
- manpages += ['ninfod']
+ manpages8 += ['ninfod']
endif
+manpages = manpages1 + manpages8
+
xsltproc = find_program('xsltproc', required : build_mans or build_html_mans)
xsltproc_args = [
'--nonet',
@@ -73,7 +77,7 @@ if xsltproc_works == false
endif
if build_mans
- foreach man : manpages
+ foreach man : manpages8
custom_target(man + '.8',
output : man + '.8',
input : man + '.xml',
@@ -88,6 +92,21 @@ if build_mans
install_dir : join_paths(get_option('mandir'), 'man8'),
)
endforeach
+ foreach man : manpages1
+ custom_target(man + '.1',
+ output : man + '.1',
+ input : man + '.xml',
+ command : [
+ xsltproc,
+ '-o', '@OUTPUT@',
+ xsltproc_args,
+ custom_man_xsl,
+ '@INPUT@',
+ ],
+ install : true,
+ install_dir : join_paths(get_option('mandir'), 'man1'),
+ )
+ endforeach
endif
if build_html_mans
diff --git a/doc/ninfod.xml b/doc/ninfod.xml
index 081d470..ed88343 100644
--- a/doc/ninfod.xml
+++ b/doc/ninfod.xml
@@ -118,7 +118,7 @@ xml:id="man.ninfod">
<para>
<citerefentry>
<refentrytitle>ping</refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>1</manvolnum>
</citerefentry>.</para>
</refsection>
diff --git a/doc/ping.xml b/doc/ping.xml
index 61b8a5e..a2bd90a 100644
--- a/doc/ping.xml
+++ b/doc/ping.xml
@@ -10,7 +10,7 @@ xml:id="man.ping">
<refentrytitle>
<application>ping</application>
</refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>1</manvolnum>
<refmiscinfo class='manual'>iputils</refmiscinfo>
</refmeta>
diff --git a/doc/rdisc.xml b/doc/rdisc.xml
index 05a518c..daa339b 100644
--- a/doc/rdisc.xml
+++ b/doc/rdisc.xml
@@ -232,7 +232,7 @@ xml:id="man.rdisc">
</citerefentry>,
<citerefentry>
<refentrytitle>ping</refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>1</manvolnum>
</citerefentry>.</para>
</refsection>
diff --git a/doc/tracepath.xml b/doc/tracepath.xml
index 6dbb637..ab06cba 100644
--- a/doc/tracepath.xml
+++ b/doc/tracepath.xml
@@ -8,7 +8,7 @@ xml:id="man.tracepath">
<refmeta>
<refentrytitle><application>tracepath</application></refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>1</manvolnum>
<refmiscinfo class='manual'>iputils</refmiscinfo>
</refmeta>
@@ -192,15 +192,15 @@ root@mops:~ # tracepath -6 3ffe:2400:0:109::2
<para>
<citerefentry>
<refentrytitle>traceroute</refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>traceroute6</refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>ping</refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>1</manvolnum>
</citerefentry>.</para>
</refsect1>
diff --git a/doc/traceroute6.xml b/doc/traceroute6.xml
index 5a72784..eb1da4b 100644
--- a/doc/traceroute6.xml
+++ b/doc/traceroute6.xml
@@ -10,7 +10,7 @@ xml:id="man.traceroute6">
<refentrytitle>
<application>traceroute6</application>
</refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>1</manvolnum>
<refmiscinfo class='manual'>iputils</refmiscinfo>
</refmeta>
@@ -61,7 +61,7 @@ xml:id="man.traceroute6">
<para>Description can be found in
<citerefentry>
<refentrytitle>traceroute</refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>1</manvolnum>
</citerefentry>, all the references to IP replaced to IPv6.
It is needless to copy the description from there.</para>
</refsection>
@@ -71,15 +71,15 @@ xml:id="man.traceroute6">
<para>
<citerefentry>
<refentrytitle>traceroute</refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>tracepath</refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>ping</refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>1</manvolnum>
</citerefentry>.</para>
</refsect1>
diff --git a/fixfds.c b/fixfds.c
new file mode 100644
index 0000000..e1298a0
--- /dev/null
+++ b/fixfds.c
@@ -0,0 +1,27 @@
+#include <stdlib.h>
+#include <error.h>
+#include <errno.h>
+#include <unistd.h>
+#include <paths.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include "fixfds.h"
+
+void
+fix_fds (void)
+{
+ struct stat stb;
+
+ if ((fstat (STDIN_FILENO, &stb) < 0)
+ && (open (_PATH_DEVNULL, O_RDONLY) != STDIN_FILENO))
+ error (EXIT_FAILURE, errno, "open: %s", _PATH_DEVNULL);
+
+ if ((fstat (STDOUT_FILENO, &stb) < 0)
+ && (open (_PATH_DEVNULL, O_WRONLY) != STDOUT_FILENO))
+ error (EXIT_FAILURE, errno, "open: %s", _PATH_DEVNULL);
+
+ if ((fstat (STDERR_FILENO, &stb) < 0)
+ && (open (_PATH_DEVNULL, O_WRONLY) != STDERR_FILENO))
+ error (EXIT_FAILURE, errno, "open: %s", _PATH_DEVNULL);
+}
diff --git a/fixfds.h b/fixfds.h
new file mode 100644
index 0000000..419fe37
--- /dev/null
+++ b/fixfds.h
@@ -0,0 +1,6 @@
+#ifndef __FIXFDS_H__
+#define __FIXFDS_H__
+
+extern void fix_fds (void);
+
+#endif /* __FIXFDS_H__ */
diff --git a/meson.build b/meson.build
index cc88544..f3534d1 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
project('iputils', 'c',
default_options : [
- 'c_std=c99',
+ 'c_std=gnu99',
'warning_level=3',
'localstatedir=var',
],
@@ -77,7 +77,7 @@ if cc.compiles('''
#include <netinet/in.h>
#include <netinet/icmp6.h>
int main(void) {
- struct icmp6_nodeinfo nodeinfo;
+ struct icmp6_nodeinfo nodeinfo __attribute__((unused));
return 0;
}
''', name : 'struct icmp6_nodeinfo')
@@ -90,7 +90,7 @@ if cc.compiles('''
#include <sys/time.h>
#include <time.h>
int main(void) {
- struct tm time;
+ struct tm time __attribute__((unused));
return 0;
}
''', name : 'struct tm time;')
@@ -132,6 +132,8 @@ if gettext == true
intl_dep += cc.find_library('intl', required : false)
endif
+add_project_link_arguments('-pie', language: 'c')
+
idn = get_option('USE_IDN')
if idn == true
idn_dep = dependency('libidn2', required : false)
@@ -243,15 +245,15 @@ if build_ping == true
endif
if build_tracepath == true
- executable('tracepath', ['tracepath.c', git_version_h],
- dependencies : [idn_dep, intl_dep],
+ executable('tracepath', ['tracepath.c', 'modcap.c', 'fixfds.c', git_version_h],
+ dependencies : [cap_dep, idn_dep],
link_with : [libcommon],
install: true)
endif
if build_traceroute6 == true
- executable('traceroute6', ['traceroute6.c', git_version_h],
- dependencies : [cap_dep, intl_dep, idn_dep],
+ executable('traceroute6', ['traceroute6.c', 'modcap.c', 'fixfds.c', git_version_h],
+ dependencies : [cap_dep, idn_dep],
link_with : [libcommon],
install: true)
if (setcap_traceroute6)
@@ -265,13 +267,14 @@ if build_traceroute6 == true
endif
if build_clockdiff == true
- executable('clockdiff', ['clockdiff.c', git_version_h],
- dependencies : [cap_dep, intl_dep],
+ executable('clockdiff', ['clockdiff.c', 'modcap.c', 'fixfds.c', git_version_h],
+ dependencies : [cap_dep],
+ install_dir: 'sbin',
link_with : [libcommon],
install: true)
if (setcap_clockdiff)
meson.add_install_script('build-aux/setcap-setuid.sh',
- bindir,
+ sbindir,
'clockdiff',
perm_type,
setcap_path
@@ -305,13 +308,14 @@ if build_rdisc == true
endif
if build_arping == true
- executable('arping', ['arping.c', git_version_h],
- dependencies : [rt_dep, cap_dep, idn_dep, intl_dep],
+ executable('arping', ['arping.c', 'modcap.c', 'fixfds.c', git_version_h],
+ dependencies : [rt_dep, cap_dep, idn_dep],
+ install_dir: 'sbin',
link_with : [libcommon],
install: true)
if (setcap_arping)
meson.add_install_script('build-aux/setcap-setuid.sh',
- bindir,
+ sbindir,
'arping',
perm_type,
setcap_path
diff --git a/modcap.c b/modcap.c
new file mode 100644
index 0000000..5ba082c
--- /dev/null
+++ b/modcap.c
@@ -0,0 +1,165 @@
+#ifdef HAVE_LIBCAP
+#include <stdlib.h>
+#include <error.h>
+#include <errno.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#include <linux/types.h>
+#include <sys/prctl.h>
+
+#include "modcap.h"
+
+#define FAIL_EXIT(fstr, args...) error (EXIT_FAILURE, errno, fstr, ##args)
+
+int modify_capability_common(cap_value_t cap, cap_flag_value_t on)
+{
+ cap_t cap_p = cap_get_proc();
+ cap_flag_value_t cap_ok;
+ int rc = -1;
+
+ if (!cap_p) {
+ FAIL_EXIT("cap_get_proc");
+ }
+
+ cap_ok = CAP_CLEAR;
+ if (cap_get_flag(cap_p, cap, CAP_PERMITTED, &cap_ok) < 0) {
+ FAIL_EXIT("cap_get_flag");
+ }
+
+ if (cap_ok == CAP_CLEAR) {
+ rc = on ? -1 : 0;
+ goto out;
+ }
+
+ if (cap_set_flag(cap_p, CAP_EFFECTIVE, 1, &cap, on) < 0) {
+ FAIL_EXIT("cap_set_flag");
+ }
+
+ if (cap_set_proc(cap_p) < 0) {
+ FAIL_EXIT("cap_set_proc");
+ }
+
+ rc = 0;
+out:
+ if (cap_p)
+ cap_free(cap_p);
+ return rc;
+}
+
+void limit_capabilities_common(int perm_cap_raw, int perm_cap_admin)
+{
+ cap_t cap_cur_p;
+ cap_t cap_p;
+ cap_flag_value_t cap_ok;
+ const cap_value_t caps[] = {CAP_SETUID, CAP_SETGID};
+ const cap_value_t cap_raw = CAP_NET_RAW;
+ const cap_value_t cap_admin = CAP_NET_ADMIN;
+ uid_t uid = getuid();
+
+ cap_p = cap_init();
+ if (!cap_p) {
+ FAIL_EXIT("cap_init");
+ }
+
+ if (!uid) {
+ const char *user = "iputils";
+ const char *dir = "/var/resolv";
+ struct passwd *pw = getpwnam(user);
+ gid_t gid;
+
+ if (!pw)
+ FAIL_EXIT("lookup of user \"%s\" failed", user);
+
+ gid = pw->pw_gid;
+ uid = pw->pw_uid;
+ endpwent();
+
+ if (!uid)
+ FAIL_EXIT("user \"%s\" shouldn't be root", user);
+
+ if (initgroups(user, gid) < 0)
+ FAIL_EXIT("initgroups");
+
+ if (chroot(dir) < 0)
+ FAIL_EXIT("chroot to \"%s\" failed", dir);
+
+ if (chdir("/") < 0)
+ FAIL_EXIT("chdir to \"/\" failed");
+
+ if (cap_set_flag(cap_p, CAP_PERMITTED, 2, caps, CAP_SET) < 0 ||
+ cap_set_flag(cap_p, CAP_EFFECTIVE, 2, caps, CAP_SET) < 0) {
+ FAIL_EXIT("cap_set_flag");
+ }
+
+ if (setregid (gid, gid) < 0) {
+ FAIL_EXIT("setregid");
+ }
+ }
+
+ cap_cur_p = cap_get_proc();
+ if (!cap_cur_p) {
+ FAIL_EXIT("cap_get_proc");
+ }
+
+ if (perm_cap_admin) {
+ cap_ok = CAP_CLEAR;
+ if (cap_get_flag(cap_cur_p, CAP_NET_ADMIN, CAP_PERMITTED, &cap_ok) < 0)
+ FAIL_EXIT("cap_get_flag");
+
+ if (cap_ok != CAP_CLEAR) {
+ if (cap_set_flag(cap_p, CAP_PERMITTED, 1, &cap_admin, CAP_SET) < 0)
+ FAIL_EXIT("cap_set_flag");
+ }
+ }
+
+ if (perm_cap_raw) {
+ cap_ok = CAP_CLEAR;
+ if (cap_get_flag(cap_cur_p, CAP_NET_RAW, CAP_PERMITTED, &cap_ok) < 0)
+ FAIL_EXIT("cap_get_flag");
+
+ if (cap_ok != CAP_CLEAR) {
+ if (cap_set_flag(cap_p, CAP_PERMITTED, 1, &cap_raw, CAP_SET) < 0)
+ FAIL_EXIT("cap_set_flag");
+ }
+ }
+
+ cap_free(cap_cur_p);
+
+ if (cap_set_proc(cap_p) < 0) {
+ FAIL_EXIT("cap_set_proc");
+ }
+
+ if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
+ FAIL_EXIT("prctl(PR_SET_KEEPCAPS, 1) failed");
+ }
+
+ if (setreuid (uid, uid) < 0) {
+ FAIL_EXIT("setreuid");
+ }
+
+ if (prctl(PR_SET_KEEPCAPS, 0) < 0) {
+ FAIL_EXIT("prctl");
+ }
+
+ if (cap_set_flag(cap_p, CAP_EFFECTIVE, 2, caps, CAP_CLEAR) < 0 ||
+ cap_set_flag(cap_p, CAP_PERMITTED, 2, caps, CAP_CLEAR) < 0) {
+ FAIL_EXIT("cap_set_flag");
+ }
+
+ if (cap_set_proc(cap_p) < 0) {
+ FAIL_EXIT("cap_set_proc");
+ }
+
+ cap_free(cap_p);
+}
+
+void drop_capabilities_common(void)
+{
+ cap_t cap = cap_init();
+ if (cap_set_proc(cap) < 0) {
+ FAIL_EXIT("cap_set_proc");
+ }
+ cap_free(cap);
+}
+#endif /* HAVE_LIBCAP */
diff --git a/modcap.h b/modcap.h
new file mode 100644
index 0000000..5af31d7
--- /dev/null
+++ b/modcap.h
@@ -0,0 +1,11 @@
+#ifndef __MODCAP_H__
+#define __MODCAP_H__
+#ifdef HAVE_LIBCAP
+#include <sys/capability.h>
+
+extern int modify_capability_common(cap_value_t cap, cap_flag_value_t on);
+extern void limit_capabilities_common(int perm_cap_raw, int perm_cap_admin);
+extern void drop_capabilities_common(void);
+#endif /* HAVE_LIBCAP */
+
+#endif /* __MODCAP_H__ */
diff --git a/ninfod/meson.build b/ninfod/meson.build
index 770169a..e6ee93c 100644
--- a/ninfod/meson.build
+++ b/ninfod/meson.build
@@ -1,5 +1,7 @@
inc = include_directories('..')
ninfod_sources = files('''
+ ../fixfds.h
+ ../fixfds.c
icmp6_nodeinfo.h
ni_ifaddrs.c
ni_ifaddrs.h
diff --git a/ninfod/ni_ifaddrs.c b/ninfod/ni_ifaddrs.c
index 01ccaf5..5df0322 100644
--- a/ninfod/ni_ifaddrs.c
+++ b/ninfod/ni_ifaddrs.c
@@ -86,7 +86,7 @@ struct nlmsg_list {
struct nlmsg_list *nlm_next;
struct nlmsghdr *nlh;
int size;
- time_t seq;
+ uint32_t seq;
};
#ifndef IFA_LOCAL
diff --git a/ninfod/ninfod.c b/ninfod/ninfod.c
index aa3cd79..9aa07f6 100644
--- a/ninfod/ninfod.c
+++ b/ninfod/ninfod.c
@@ -117,6 +117,8 @@
# include <sys/capability.h>
#endif
+#include "../fixfds.h"
+
#include "iputils_common.h"
#include "iputils_ni.h"
#include "ninfod.h"
@@ -634,6 +636,7 @@ int main (int argc, char **argv)
atexit(close_stdout);
appname = argv[0];
+ fix_fds();
set_logfile();
limit_capabilities();
diff --git a/ping/meson.build b/ping/meson.build
index 1e678ec..3ee7be6 100644
--- a/ping/meson.build
+++ b/ping/meson.build
@@ -5,6 +5,8 @@ ping = executable('ping', [
'ping_common.c',
'ping6_common.c',
'node_info.c',
+ '../modcap.c',
+ '../fixfds.c',
git_version_h
],
include_directories : inc,
diff --git a/ping/ping.c b/ping/ping.c
index 6fcb44f..549c6b8 100644
--- a/ping/ping.c
+++ b/ping/ping.c
@@ -61,6 +61,8 @@
/* FIXME: global_rts will be removed in future */
struct ping_rts *global_rts;
+#include "fixfds.h"
+
#ifndef ICMP_FILTER
#define ICMP_FILTER 1
struct icmp_filter {
@@ -174,20 +176,27 @@ static double ping_strtod(const char *str, const char *err_msg)
{
double num;
char *end = NULL;
+ int strtod_errno;
if (str == NULL || *str == '\0')
goto err;
- errno = 0;
/*
* Here we always want to use locale regardless USE_IDN or ENABLE_NLS,
* because it handles decimal point of -i/-W input options.
*/
setlocale(LC_ALL, "C");
+ errno = 0;
num = strtod(str, &end);
+ strtod_errno = errno;
setlocale(LC_ALL, "");
- if (errno || str == end || (end && *end)) {
+ if (strtod_errno) {
+ errno = strtod_errno;
+ goto err;
+ }
+
+ if (str == end || (end && *end)) {
error(0, 0, _("option argument contains garbage: %s"), end);
error(0, 0, _("this will become fatal error in the future"));
}
@@ -276,10 +285,6 @@ main(int argc, char **argv)
.pipesize = -1,
.datalen = DEFDATALEN,
.screen_width = INT_MAX,
-#ifdef HAVE_LIBCAP
- .cap_raw = CAP_NET_RAW,
- .cap_admin = CAP_NET_ADMIN,
-#endif
.pmtudisc = -1,
.source.sin_family = AF_INET,
.source6.sin6_family = AF_INET6,
@@ -289,6 +294,8 @@ main(int argc, char **argv)
/* FIXME: global_rts will be removed in future */
global_rts = &rts;
+ fix_fds();
+
atexit(close_stdout);
limit_capabilities(&rts);
@@ -740,7 +747,7 @@ int ping4_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
if (!ifa->ifa_name || !ifa->ifa_addr ||
ifa->ifa_addr->sa_family != AF_INET)
continue;
- if (!strcmp(ifa->ifa_name, rts->device) &&
+ if (!strncmp(ifa->ifa_name, rts->device, IFNAMSIZ) &&
!memcmp(&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
&rts->source.sin_addr, sizeof(rts->source.sin_addr)))
break;
@@ -931,6 +938,8 @@ int ping4_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
setup(rts, sock);
+ drop_capabilities();
+
hold = main_loop(rts, &ping4_func_set, sock, packet, packlen);
free(packet);
return hold;
diff --git a/ping/ping.h b/ping/ping.h
index b81a2f1..cefaba8 100644
--- a/ping/ping.h
+++ b/ping/ping.h
@@ -35,7 +35,7 @@
#ifdef HAVE_LIBCAP
# include <sys/prctl.h>
-# include <sys/capability.h>
+#include "modcap.h"
#endif
#include "iputils_common.h"
@@ -206,10 +206,6 @@ struct ping_rts {
/* Used only in ping_common.c */
int screen_width;
-#ifdef HAVE_LIBCAP
- cap_value_t cap_raw;
- cap_value_t cap_admin;
-#endif
/* Used only in ping6_common.c */
struct sockaddr_in6 firsthop;
diff --git a/ping/ping6_common.c b/ping/ping6_common.c
index 986210b..24a4644 100644
--- a/ping/ping6_common.c
+++ b/ping/ping6_common.c
@@ -206,7 +206,7 @@ int ping6_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
if (!ifa->ifa_name || !ifa->ifa_addr ||
ifa->ifa_addr->sa_family != AF_INET6)
continue;
- if (!strcmp(ifa->ifa_name, rts->device) &&
+ if (!strncmp(ifa->ifa_name, rts->device, IFNAMSIZ) &&
IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
&rts->source6.sin6_addr))
break;
diff --git a/ping/ping_common.c b/ping/ping_common.c
index 357c39d..0147842 100644
--- a/ping/ping_common.c
+++ b/ping/ping_common.c
@@ -88,81 +88,25 @@ void usage(void)
exit(2);
}
-void limit_capabilities(struct ping_rts *rts)
-{
#ifdef HAVE_LIBCAP
- cap_t cap_cur_p;
- cap_t cap_p;
- cap_flag_value_t cap_ok;
-
- cap_cur_p = cap_get_proc();
- if (!cap_cur_p)
- error(-1, errno, "cap_get_proc");
- cap_p = cap_init();
- if (!cap_p)
- error(-1, errno, "cap_init");
- cap_ok = CAP_CLEAR;
- cap_get_flag(cap_cur_p, CAP_NET_ADMIN, CAP_PERMITTED, &cap_ok);
- if (cap_ok != CAP_CLEAR)
- cap_set_flag(cap_p, CAP_PERMITTED, 1, &rts->cap_admin, CAP_SET);
- cap_ok = CAP_CLEAR;
- cap_get_flag(cap_cur_p, CAP_NET_RAW, CAP_PERMITTED, &cap_ok);
- if (cap_ok != CAP_CLEAR)
- cap_set_flag(cap_p, CAP_PERMITTED, 1, &rts->cap_raw, CAP_SET);
- if (cap_set_proc(cap_p) < 0)
- error(-1, errno, "cap_set_proc");
- if (prctl(PR_SET_KEEPCAPS, 1) < 0)
- error(-1, errno, "prctl");
- if (setuid(getuid()) < 0)
- error(-1, errno, "setuid");
- if (prctl(PR_SET_KEEPCAPS, 0) < 0)
- error(-1, errno, "prctl");
- cap_free(cap_p);
- cap_free(cap_cur_p);
+void limit_capabilities(struct ping_rts *rts __attribute__((__unused__)))
+{
+ limit_capabilities_common(1, 1);
+}
#else
- euid = geteuid();
-#endif
+void limit_capabilities(struct ping_rts *rts)
+{
rts->uid = getuid();
-#ifndef HAVE_LIBCAP
+ euid = geteuid();
if (seteuid(rts->uid))
error(-1, errno, "setuid");
-#endif
}
+#endif
#ifdef HAVE_LIBCAP
int modify_capability(cap_value_t cap, cap_flag_value_t on)
{
- cap_t cap_p = cap_get_proc();
- cap_flag_value_t cap_ok;
- int rc = -1;
-
- if (!cap_p) {
- error(0, errno, "cap_get_proc");
- goto out;
- }
-
- cap_ok = CAP_CLEAR;
- cap_get_flag(cap_p, cap, CAP_PERMITTED, &cap_ok);
- if (cap_ok == CAP_CLEAR) {
- rc = on ? -1 : 0;
- goto out;
- }
-
- cap_set_flag(cap_p, CAP_EFFECTIVE, 1, &cap, on);
-
- if (cap_set_proc(cap_p) < 0) {
- error(0, errno, "cap_set_proc");
- goto out;
- }
-
- cap_free(cap_p);
- cap_p = NULL;
-
- rc = 0;
-out:
- if (cap_p)
- cap_free(cap_p);
- return rc;
+ return modify_capability_common(cap, on);
}
#else
int modify_capability(int on)
@@ -179,10 +123,7 @@ int modify_capability(int on)
void drop_capabilities(void)
{
#ifdef HAVE_LIBCAP
- cap_t cap = cap_init();
- if (cap_set_proc(cap) < 0)
- error(-1, errno, "cap_set_proc");
- cap_free(cap);
+ drop_capabilities_common();
#else
if (setuid(getuid()))
error(-1, errno, "setuid");
diff --git a/tracepath.c b/tracepath.c
index fb4bdca..50ec509 100644
--- a/tracepath.c
+++ b/tracepath.c
@@ -23,6 +23,10 @@
#include <sys/uio.h>
#include <time.h>
#include <unistd.h>
+#ifdef HAVE_LIBCAP
+#include "modcap.h"
+#endif
+#include "fixfds.h"
/*
* Keep linux/ includes after standard headers.
@@ -435,6 +439,13 @@ int main(int argc, char **argv)
char *p;
char pbuf[NI_MAXSERV];
+ fix_fds();
+
+#ifdef HAVE_LIBCAP
+ limit_capabilities_common(0, 0);
+ drop_capabilities_common();
+#endif
+
atexit(close_stdout);
#if defined(USE_IDN) || defined(ENABLE_NLS)
setlocale(LC_ALL, "");
diff --git a/traceroute6.c b/traceroute6.c
index c7cc242..1f85373 100644
--- a/traceroute6.c
+++ b/traceroute6.c
@@ -249,12 +249,14 @@
#endif
#ifdef HAVE_LIBCAP
-# include <sys/capability.h>
+#include "modcap.h"
#endif
#include "iputils_common.h"
#include "ipv6.h"
+#include "fixfds.h"
+
#ifdef USE_IDN
# define ADDRINFO_IDN_FLAGS AI_IDN
# define getnameinfo_flags NI_IDN
@@ -656,6 +658,8 @@ int main(int argc, char **argv)
uint32_t seq = 0;
char *resolved_hostname = NULL;
+ fix_fds();
+
atexit(close_stdout);
ctl.datalen = sizeof(struct pkt_format);
ctl.icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
@@ -665,13 +669,8 @@ int main(int argc, char **argv)
if (setuid(getuid()))
error(-1, errno, "setuid");
#ifdef HAVE_LIBCAP
- {
- cap_t caps = cap_init();
-
- if (cap_set_proc(caps))
- error(-1, errno, "cap_set_proc");
- cap_free(caps);
- }
+ limit_capabilities_common(0, 0);
+ drop_capabilities_common();
#endif
#if defined(USE_IDN) || defined(ENABLE_NLS)