Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37559487
en ru br
ALT Linux repos
S:20221126-alt1
5.0: 20071127-alt4
4.1: 20071127-alt0.M41.1
4.0: 20020927-alt4.2
3.0: 20020927-alt2

Group :: Networking/Other
RPM: iputils

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

Patch: iputils-s20071127-alt-droppriv.patch
Download


diff -Nur iputils~/Makefile iputils/Makefile
--- iputils~/Makefile	Thu Jan 24 20:27:37 2002
+++ iputils/Makefile	Thu Apr 11 18:08:35 2002
@@ -34,9 +34,15 @@
 all: check-kernel $(TARGETS)
 
 
+arping: arping.o fixfds.o droppriv.o
+clockdiff: clockdiff.o fixfds.o dropcap.o
+	$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lcap -o $@
 tftpd: tftpd.o tftpsubs.o
-ping: ping.o ping_common.o
-ping6: ping6.o ping_common.o
+tracepath: tracepath.o fixfds.o droppriv.o
+tracepath6: tracepath6.o fixfds.o droppriv.o
+traceroute6: traceroute6.o fixfds.o droppriv.o
+ping: ping.o ping_common.o fixfds.o droppriv.o
+ping6: ping6.o ping_common.o fixfds.o droppriv.o
 ping.o ping6.o ping_common.o: ping_common.h
 tftpd.o tftpsubs.o: tftp.h
 
--- iputils-s20071127/arping.c.orig	2007-11-27 03:57:27 +0300
+++ iputils-s20071127/arping.c	2008-09-15 13:10:07 +0400
@@ -33,6 +33,8 @@
 #include <arpa/inet.h>
 
 #include "SNAPSHOT.h"
+#include "fixfds.h"
+#include "droppriv.h"
 
 static void usage(void) __attribute__((noreturn));
 
@@ -301,16 +303,10 @@
 {
 	int socket_errno;
 	int ch;
-	uid_t uid = getuid();
 
 	s = socket(PF_PACKET, SOCK_DGRAM, 0);
 	socket_errno = errno;
 
-	if (setuid(uid)) {
-		perror("arping: setuid");
-		exit(-1);
-	}
-
 	while ((ch = getopt(argc, argv, "h?bfDUAqc:w:s:I:V")) != EOF) {
 		switch(ch) {
 		case 'b':
@@ -459,6 +455,8 @@
 		close(probe_fd);
 	};
 
+	drop_priv();
+
 	me.sll_family = AF_PACKET;
 	me.sll_ifindex = ifindex;
 	me.sll_protocol = htons(ETH_P_ARP);
--- iputils-s20071127/clockdiff.c.orig	2007-11-27 03:57:27 +0300
+++ iputils-s20071127/clockdiff.c	2008-09-15 13:15:41 +0400
@@ -20,6 +20,9 @@
 #include <arpa/inet.h>
 #include <errno.h>
 #include <linux/types.h>
+#include "fixfds.h"
+#include "dropcap.h"
+
 
 void usage(void) __attribute__((noreturn));
 
@@ -538,6 +541,8 @@
 	char hostname[MAXHOSTNAMELEN];
 	int s_errno = 0;
 
+	fix_fds();
+
 	if (argc < 2) {
 		if (setuid(getuid())) {
 			perror("clockdiff: setuid");
@@ -549,10 +554,7 @@
 	sock_raw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
 	s_errno = errno;
 
-	if (setuid(getuid())) {
-		perror("clockdiff: setuid");
-		exit(-1);
-	}
+    drop_cap();
 
 	if (argc == 3) {
 		if (strcmp(argv[1], "-o") == 0) {
diff -Nur iputils~/dropcap.c iputils/dropcap.c
--- iputils~/dropcap.c	Thu Jan  1 03:00:00 1970
+++ iputils/dropcap.c	Thu Apr 11 18:10:05 2002
@@ -0,0 +1,79 @@
+#include <stdlib.h>
+#include <error.h>
+#include <errno.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#include <linux/types.h>
+#include <sys/capability.h>
+#include <sys/prctl.h>
+
+#include "dropcap.h"
+
+extern void drop_cap (void);
+
+void
+drop_cap (void)
+{
+	const char *dir = "/var/resolv";
+	cap_t   caps;
+	uid_t uid = getuid ();
+	gid_t gid = getgid ();
+
+	if (uid && geteuid())
+		return;
+
+	if (setgroups (0, NULL) < 0)
+		error (EXIT_FAILURE, errno, "setgroups");
+
+	if (prctl (PR_SET_KEEPCAPS, 1))
+		error (EXIT_FAILURE, errno, "prctl (PR_SET_KEEPCAPS, 1) failed");
+
+	if (!uid)
+	{
+		const char *user = "iputils";
+		struct passwd *pw = getpwnam (user);
+
+		if (!pw)
+			error (EXIT_FAILURE, 0,
+			       "lookup of user \"%s\" failed", user);
+
+		gid = pw->pw_gid;
+		uid = pw->pw_uid;
+		endpwent ();
+
+		if (!uid)
+			error (EXIT_FAILURE, 0,
+			       "user \"%s\" shouldn't be root", user);
+	}
+
+	if (chroot (dir) < 0)
+		error (EXIT_FAILURE, errno, "chroot to \"%s\" failed", dir);
+
+	if (chdir ("/") < 0)
+		error (EXIT_FAILURE, errno, "chdir to \"/\" failed");
+
+	if (setgid (gid) < 0)
+		error (EXIT_FAILURE, errno, "setgid");
+
+	caps = cap_from_text ("cap_setuid,cap_net_raw=ep");
+	if (!caps)
+		error (EXIT_FAILURE, errno, "cap_from_text failed");
+
+	if (cap_set_proc (caps) < 0)
+		error (EXIT_FAILURE, errno, "cap_set_proc failed");
+
+	cap_free (caps);
+
+	if (setreuid (uid, uid) < 0)
+		error (EXIT_FAILURE, errno, "setreuid");
+
+	caps = cap_from_text ("cap_net_raw=ep");
+	if (!caps)
+		error (EXIT_FAILURE, errno, "cap_from_text failed");
+
+	if (cap_set_proc (caps) < 0)
+		error (EXIT_FAILURE, errno, "cap_set_proc failed");
+
+	cap_free (caps);
+}
diff -Nur iputils~/dropcap.h iputils/dropcap.h
--- iputils~/dropcap.h	Thu Jan  1 03:00:00 1970
+++ iputils/dropcap.h	Thu Apr 11 18:08:35 2002
@@ -0,0 +1,6 @@
+#ifndef __DROPCAP_H__
+#define __DROPCAP_H__
+
+extern void drop_cap (void);
+
+#endif /* __DROPCAP_H__ */
diff -Nur iputils~/droppriv.c iputils/droppriv.c
--- iputils~/droppriv.c	Thu Jan  1 03:00:00 1970
+++ iputils/droppriv.c	Thu Apr 11 18:08:35 2002
@@ -0,0 +1,65 @@
+#include <stdlib.h>
+#include <error.h>
+#include <errno.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include "droppriv.h"
+
+uid_t   uid = -1;
+
+void
+drop_priv (void)
+{
+	const char *dir = "/var/resolv";
+	uid = getuid ();
+
+	if (uid && geteuid())
+		return;
+
+	if (setgroups (0, NULL) < 0)
+		error (EXIT_FAILURE, errno, "setgroups");
+
+	if (uid)
+	{
+		if (chroot (dir) < 0)
+			error (EXIT_FAILURE, errno, "chroot to \"%s\" failed",
+			       dir);
+
+		if (chdir ("/") < 0)
+			error (EXIT_FAILURE, errno, "chdir to \"/\" failed");
+
+		if (setgid (getgid ()) < 0)
+			error (EXIT_FAILURE, errno, "setgid");
+
+		if (setuid (uid) < 0)
+			error (EXIT_FAILURE, errno, "setuid");
+	} else
+	{
+		const char *user = "iputils";
+		struct passwd *pw = getpwnam (user);
+
+		if (!pw)
+			error (EXIT_FAILURE, 0,
+			       "lookup of user \"%s\" failed", user);
+		endpwent ();
+
+		if (!pw->pw_uid)
+			error (EXIT_FAILURE, 0,
+			       "user \"%s\" shouldn't be root", user);
+
+		if (chroot (dir) < 0)
+			error (EXIT_FAILURE, errno, "chroot to \"%s\" failed",
+			       dir);
+
+		if (chdir ("/") < 0)
+			error (EXIT_FAILURE, errno, "chdir to \"/\" failed");
+
+		if (setgid (pw->pw_gid) < 0)
+			error (EXIT_FAILURE, errno, "setgid");
+
+		if (setuid (pw->pw_uid) < 0)
+			error (EXIT_FAILURE, errno, "setuid");
+	}
+}
diff -Nur iputils~/droppriv.h iputils/droppriv.h
--- iputils~/droppriv.h	Thu Jan  1 03:00:00 1970
+++ iputils/droppriv.h	Thu Apr 11 18:08:35 2002
@@ -0,0 +1,10 @@
+#ifndef __DROPPRIV_H__
+#define __DROPPRIV_H__
+
+#include <sys/types.h>
+
+extern void drop_priv (void);
+
+extern uid_t uid;
+
+#endif /* __DROPPRIV_H__ */
diff -Nur iputils~/fixfds.c iputils/fixfds.c
--- iputils~/fixfds.c	Thu Jan  1 03:00:00 1970
+++ iputils/fixfds.c	Thu Apr 11 18:08:35 2002
@@ -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 -Nur iputils~/fixfds.h iputils/fixfds.h
--- iputils~/fixfds.h	Thu Jan  1 03:00:00 1970
+++ iputils/fixfds.h	Thu Apr 11 18:08:35 2002
@@ -0,0 +1,6 @@
+#ifndef __FIXFDS_H__
+#define __FIXFDS_H__
+
+extern void fix_fds (void);
+
+#endif /* __FIXFDS_H__ */
--- iputils-s20071127/ping.c.orig	2008-09-15 13:16:54 +0400
+++ iputils-s20071127/ping.c	2008-09-15 13:18:50 +0400
@@ -59,6 +59,8 @@
  */
 
 #include "ping_common.h"
+#include "fixfds.h"
+#include "droppriv.h"
 
 #include <netinet/ip.h>
 #include <netinet/ip_icmp.h>
@@ -122,14 +124,12 @@
 	char *target, hnamebuf[MAXHOSTNAMELEN];
 	char rspace[3 + 4 * NROUTES + 1];	/* record route space */
 
+    fix_fds();
+
 	icmp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
 	socket_errno = errno;
 
-	uid = getuid();
-	if (setuid(uid)) {
-		perror("ping: setuid");
-		exit(-1);
-	}
+    drop_priv();
 
 	source.sin_family = AF_INET;
 
--- iputils-s20071127/ping6.c.orig	2007-11-27 03:57:27 +0300
+++ iputils-s20071127/ping6.c	2008-09-15 13:21:05 +0400
@@ -67,6 +67,8 @@
  *	This program has to run SUID to ROOT to access the ICMP socket.
  */
 #include "ping_common.h"
+#include "fixfds.h"
+#include "droppriv.h"
 
 #include <linux/filter.h>
 #include <netinet/ip6.h>
@@ -210,14 +212,12 @@
 	int err, csum_offset, sz_opt;
 	static uint32_t scope_id = 0;
 
+    fix_fds();
+
 	icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
 	socket_errno = errno;
 
-	uid = getuid();
-	if (setuid(uid)) {
-		perror("ping: setuid");
-		exit(-1);
-	}
+    drop_priv();
 
 	source.sin6_family = AF_INET6;
 	memset(&firsthop, 0, sizeof(firsthop));
diff -Nur iputils~/ping_common.c iputils/ping_common.c
--- iputils~/ping_common.c	Thu Jan 24 22:41:44 2002
+++ iputils/ping_common.c	Thu Apr 11 18:08:35 2002
@@ -1,6 +1,7 @@
 #include "ping_common.h"
 #include <ctype.h>
 #include <sched.h>
+#include "droppriv.h"
 
 int options;
 int moptions;
@@ -49,7 +50,6 @@
 int datalen = DEFDATALEN;
 
 char *hostname;
-int uid;
 int ident;			/* process id to identify our packets */
 
 static int screen_width = INT_MAX;
diff -Nur iputils~/ping_common.h iputils/ping_common.h
--- iputils~/ping_common.h	Sun Aug  5 20:38:46 2001
+++ iputils/ping_common.h	Thu Apr 11 18:08:35 2002
@@ -78,7 +78,6 @@
 
 extern int datalen;
 extern char *hostname;
-extern int uid;
 extern int ident;			/* process id to identify our packets */
 
 extern int sndbuf;
diff -Nur iputils~/tracepath.c iputils/tracepath.c
--- iputils~/tracepath.c	Thu Apr 11 15:52:55 2002
+++ iputils/tracepath.c	Thu Apr 11 18:08:35 2002
@@ -22,6 +22,8 @@
 #include <sys/time.h>
 #include <sys/uio.h>
 #include <arpa/inet.h>
+#include "fixfds.h"
+#include "droppriv.h"
 
 struct hhistory
 {
@@ -277,6 +279,9 @@
 	int ttl;
 	char *p;
 	int ch;
+
+	fix_fds();
+	drop_priv();
 
 	while ((ch = getopt(argc, argv, "nh?")) != EOF) {
 		switch(ch) {
--- iputils-s20071127/tracepath6.c.orig	2008-09-15 13:21:48 +0400
+++ iputils-s20071127/tracepath6.c	2008-09-15 13:24:42 +0400
@@ -25,6 +25,8 @@
 #include <sys/time.h>
 #include <sys/uio.h>
 #include <arpa/inet.h>
+#include "fixfds.h"
+#include "droppriv.h"
 
 #ifndef SOL_IPV6
 #define SOL_IPV6 IPPROTO_IPV6
@@ -300,6 +302,9 @@
 	int gai;
 	char pbuf[NI_MAXSERV];
 
+    fix_fds();
+    drop_priv();
+
 	while ((ch = getopt(argc, argv, "nbh?l:")) != EOF) {
 		switch(ch) {
 		case 'n':
--- iputils-s20071127/traceroute6.c.orig	2008-09-15 13:29:18 +0400
+++ iputils-s20071127/traceroute6.c	2008-09-15 13:31:25 +0400
@@ -260,6 +260,8 @@
 #include <unistd.h>
 
 #include "SNAPSHOT.h"
+#include "fixfds.h"
+#include "droppriv.h"
 
 #ifndef SOL_IPV6
 #define SOL_IPV6 IPPROTO_IPV6
@@ -337,13 +339,12 @@
 	int ch, i, on, probe, seq, tos, ttl;
 	int socket_errno;
 
+    fix_fds();
+
 	icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
 	socket_errno = errno;
 
-	if (setuid(getuid())) {
-		perror("traceroute6: setuid");
-		exit(-1);
-	}
+    drop_priv();
 
 	on = 1;
 	seq = tos = 0;
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin