ALT Linux repositórios
Group :: Rede/Outros
RPM: iputils
Main Changelog Spec Patches Sources Download Gear Bugs e FR Repocop
Patch: iputils-s20101006-alt-droppriv.patch
Download
Download
diff -urN iputils-s20101006.orig/arping.c iputils-s20101006/arping.c
--- iputils-s20101006.orig/arping.c 2011-01-23 01:40:55.000000000 +0200
+++ iputils-s20101006/arping.c 2011-05-03 20:21:19.000000000 +0300
@@ -35,6 +35,8 @@
#include <sysfs/libsysfs.h>
#include "SNAPSHOT.h"
+#include "fixfds.h"
+#include "droppriv.h"
static void usage(void) __attribute__((noreturn));
@@ -346,16 +348,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':
@@ -504,6 +500,10 @@
close(probe_fd);
};
+#if 0
+ drop_priv();
+#endif
+
((struct sockaddr_ll *)&me)->sll_family = AF_PACKET;
((struct sockaddr_ll *)&me)->sll_ifindex = ifindex;
((struct sockaddr_ll *)&me)->sll_protocol = htons(ETH_P_ARP);
@@ -530,6 +530,7 @@
#if 1
set_device_broadcast(device, ((struct sockaddr_ll *)&he)->sll_addr,
((struct sockaddr_ll *)&he)->sll_halen);
+ drop_priv();
#else
memset(((struct sockaddr_ll *)&he)->sll_addr, -1, ((struct sockaddr_ll *)&he)->sll_halen);
#endif
diff -urN iputils-s20101006.orig/clockdiff.c iputils-s20101006/clockdiff.c
--- iputils-s20101006.orig/clockdiff.c 2011-01-23 01:40:55.000000000 +0200
+++ iputils-s20101006/clockdiff.c 2011-05-03 20:20:16.000000000 +0300
@@ -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));
@@ -539,6 +542,8 @@
char hostname[MAX_HOSTNAMELEN];
int s_errno = 0;
+ fix_fds();
+
if (argc < 2) {
if (setuid(getuid())) {
perror("clockdiff: setuid");
@@ -550,10 +555,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 -urN iputils-s20101006.orig/dropcap.c iputils-s20101006/dropcap.c
--- iputils-s20101006.orig/dropcap.c 1970-01-01 03:00:00.000000000 +0300
+++ iputils-s20101006/dropcap.c 2011-05-03 20:20:16.000000000 +0300
@@ -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 -urN iputils-s20101006.orig/dropcap.h iputils-s20101006/dropcap.h
--- iputils-s20101006.orig/dropcap.h 1970-01-01 03:00:00.000000000 +0300
+++ iputils-s20101006/dropcap.h 2011-05-03 20:20:16.000000000 +0300
@@ -0,0 +1,6 @@
+#ifndef __DROPCAP_H__
+#define __DROPCAP_H__
+
+extern void drop_cap (void);
+
+#endif /* __DROPCAP_H__ */
diff -urN iputils-s20101006.orig/droppriv.c iputils-s20101006/droppriv.c
--- iputils-s20101006.orig/droppriv.c 1970-01-01 03:00:00.000000000 +0300
+++ iputils-s20101006/droppriv.c 2011-05-03 20:20:16.000000000 +0300
@@ -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 -urN iputils-s20101006.orig/droppriv.h iputils-s20101006/droppriv.h
--- iputils-s20101006.orig/droppriv.h 1970-01-01 03:00:00.000000000 +0300
+++ iputils-s20101006/droppriv.h 2011-05-03 20:20:16.000000000 +0300
@@ -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 -urN iputils-s20101006.orig/fixfds.c iputils-s20101006/fixfds.c
--- iputils-s20101006.orig/fixfds.c 1970-01-01 03:00:00.000000000 +0300
+++ iputils-s20101006/fixfds.c 2011-05-03 20:20:16.000000000 +0300
@@ -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 -urN iputils-s20101006.orig/fixfds.h iputils-s20101006/fixfds.h
--- iputils-s20101006.orig/fixfds.h 1970-01-01 03:00:00.000000000 +0300
+++ iputils-s20101006/fixfds.h 2011-05-03 20:20:16.000000000 +0300
@@ -0,0 +1,6 @@
+#ifndef __FIXFDS_H__
+#define __FIXFDS_H__
+
+extern void fix_fds (void);
+
+#endif /* __FIXFDS_H__ */
diff -urN iputils-s20101006.orig/Makefile iputils-s20101006/Makefile
--- iputils-s20101006.orig/Makefile 2011-01-23 01:40:55.000000000 +0200
+++ iputils-s20101006/Makefile 2011-05-03 20:20:16.000000000 +0300
@@ -26,10 +26,15 @@
all: $(TARGETS)
+arping: arping.o -lsysfs fixfds.o droppriv.o
+clockdiff: clockdiff.o fixfds.o dropcap.o
+ $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lcap -o $@
tftpd: tftpd.o tftpsubs.o
-arping: arping.o -lsysfs
-ping: ping.o ping_common.o
-ping6: ping6.o ping_common.o -lresolv -lcrypto
+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 -lresolv -lcrypto
ping.o ping6.o ping_common.o: ping_common.h
tftpd.o tftpsubs.o: tftp.h
diff -urN iputils-s20101006.orig/ping6.c iputils-s20101006/ping6.c
--- iputils-s20101006.orig/ping6.c 2011-01-23 01:40:55.000000000 +0200
+++ iputils-s20101006/ping6.c 2011-05-03 20:20:16.000000000 +0300
@@ -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>
@@ -529,14 +531,12 @@
#endif
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 -urN iputils-s20101006.orig/ping.c iputils-s20101006/ping.c
--- iputils-s20101006.orig/ping.c 2011-01-23 01:40:55.000000000 +0200
+++ iputils-s20101006/ping.c 2011-05-03 20:20:16.000000000 +0300
@@ -59,6 +59,8 @@
*/
#include "ping_common.h"
+#include "fixfds.h"
+#include "droppriv.h"
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
@@ -123,14 +125,12 @@
char *target, hnamebuf[MAX_HOSTNAMELEN];
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;
diff -urN iputils-s20101006.orig/ping_common.c iputils-s20101006/ping_common.c
--- iputils-s20101006.orig/ping_common.c 2011-01-23 01:40:55.000000000 +0200
+++ iputils-s20101006/ping_common.c 2011-05-03 20:20:16.000000000 +0300
@@ -1,6 +1,7 @@
#include "ping_common.h"
#include <ctype.h>
#include <sched.h>
+#include "droppriv.h"
int options;
@@ -55,7 +56,6 @@
int datalen = DEFDATALEN;
char *hostname;
-int uid;
int ident; /* process id to identify our packets */
static int screen_width = INT_MAX;
diff -urN iputils-s20101006.orig/ping_common.h iputils-s20101006/ping_common.h
--- iputils-s20101006.orig/ping_common.h 2011-01-23 01:40:55.000000000 +0200
+++ iputils-s20101006/ping_common.h 2011-05-03 20:20:16.000000000 +0300
@@ -77,7 +77,6 @@
extern int datalen;
extern char *hostname;
-extern int uid;
extern int ident; /* process id to identify our packets */
extern int sndbuf;
diff -urN iputils-s20101006.orig/tracepath6.c iputils-s20101006/tracepath6.c
--- iputils-s20101006.orig/tracepath6.c 2011-01-23 01:40:55.000000000 +0200
+++ iputils-s20101006/tracepath6.c 2011-05-03 20:20:16.000000000 +0300
@@ -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
@@ -375,6 +377,9 @@
int gai;
char pbuf[NI_MAXSERV];
+ fix_fds();
+ drop_priv();
+
while ((ch = getopt(argc, argv, "nbh?l:")) != EOF) {
switch(ch) {
case 'n':
diff -urN iputils-s20101006.orig/tracepath.c iputils-s20101006/tracepath.c
--- iputils-s20101006.orig/tracepath.c 2011-01-23 01:40:55.000000000 +0200
+++ iputils-s20101006/tracepath.c 2011-05-03 20:20:16.000000000 +0300
@@ -23,6 +23,8 @@
#include <sys/time.h>
#include <sys/uio.h>
#include <arpa/inet.h>
+#include "fixfds.h"
+#include "droppriv.h"
#ifndef IP_PMTUDISC_PROBE
#define IP_PMTUDISC_PROBE 3
@@ -299,6 +301,9 @@
char *p;
int ch;
+ fix_fds();
+ drop_priv();
+
while ((ch = getopt(argc, argv, "nbh?l:")) != EOF) {
switch(ch) {
case 'n':
diff -urN iputils-s20101006.orig/traceroute6.c iputils-s20101006/traceroute6.c
--- iputils-s20101006.orig/traceroute6.c 2011-01-23 01:40:55.000000000 +0200
+++ iputils-s20101006/traceroute6.c 2011-05-03 20:20:16.000000000 +0300
@@ -260,6 +260,8 @@
#include <unistd.h>
#include "SNAPSHOT.h"
+#include "fixfds.h"
+#include "droppriv.h"
#ifndef SOL_IPV6
#define SOL_IPV6 IPPROTO_IPV6
@@ -335,13 +337,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;