Sisyphus repositório
Última atualização: 1 outubro 2023 | SRPMs: 18631 | Visitas: 37533059
en ru br
ALT Linux repositórios
S:9.16.44-alt1
5.0: 9.3.6-alt5
4.1: 9.3.6-alt4.M41.2
+updates:9.3.6-alt4.M41.1
4.0: 9.3.6-alt4.M41.1
+updates:9.3.6-alt4.M41.1
3.0: 9.2.4.rel-alt2

Group :: Sistema/Servidores
RPM: bind

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs e FR  Repocop 

Patch: 0002-ALT-Minimize-linux-capabilities.patch
Download


From 8ac58a757c98ef604b174efd0deab859b93a1bf7 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Wed, 11 Jan 2017 15:27:28 +0000
Subject: [PATCH] ALT: Minimize linux capabilities
When PR_SET_KEEPCAPS is enables before the user change,
disable it back after the change.
If HAVE_LINUX_CAPABILITY_H is enabled, minimize linux capabilities early
like in HAVE_LINUXTHREADS mode: lower capabilities to
CAP_SYS_RESOURCE|CAP_NET_BIND_SERVICE at the end of the first user
change in ns_os_changeuser, and clear remaining capabilities later when
ns_os_dropprivs is called right after the second ns_os_changeuser call
in load_configuration.
If HAVE_LINUXTHREADS is enabled, keep the saved set-user-ID during the
first user change in ns_os_changeuser, and finalize the switch later
when ns_os_dropprivs is called right after the second ns_os_changeuser
call in load_configuration.  This trick activates NPTL feature
of forcing process credential changes over all threads.
---
 bind/bin/named/server.c                |  1 +
 bind/bin/named/unix/include/named/os.h |  3 ++
 bind/bin/named/unix/os.c               | 59 +++++++++++++++++++++++---
 3 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/bind/bin/named/server.c b/bind/bin/named/server.c
index dcd4f0e696d..0c0fdc409bd 100644
--- a/bind/bin/named/server.c
+++ b/bind/bin/named/server.c
@@ -9194,6 +9194,7 @@ load_configuration(const char *filename, named_server_t *server,
 	 */
 	if (first_time) {
 		named_os_changeuser();
+		named_os_dropprivs();
 	}
 
 	/*
diff --git a/bind/bin/named/unix/include/named/os.h b/bind/bin/named/unix/include/named/os.h
index 7f167b1c2d1..ea17fecd086 100644
--- a/bind/bin/named/unix/include/named/os.h
+++ b/bind/bin/named/unix/include/named/os.h
@@ -54,6 +54,9 @@ named_os_minprivs(void);
 FILE *
 named_os_openfile(const char *filename, mode_t mode, bool switch_user);
 
+void
+named_os_dropprivs(void);
+
 void
 named_os_writepidfile(const char *filename, bool first_time);
 
diff --git a/bind/bin/named/unix/os.c b/bind/bin/named/unix/os.c
index 1ab428baee3..44faacde85e 100644
--- a/bind/bin/named/unix/os.c
+++ b/bind/bin/named/unix/os.c
@@ -41,7 +41,9 @@
 #include <isc/result.h>
 #include <isc/strerr.h>
 #include <isc/string.h>
+#ifndef WANT_SETPERMS
 #include <isc/util.h>
+#endif /* WANT_SETPERMS */
 
 #include <named/globals.h>
 #include <named/main.h>
@@ -75,7 +77,7 @@ static void
 linux_setcaps(cap_t caps) {
 	char strbuf[ISC_STRERRORSIZE];
 
-	if ((getuid() != 0 && !non_root_caps) || non_root) {
+	if ((caps && getuid() != 0 && !non_root_caps) || non_root) {
 		return;
 	}
 	if (cap_set_proc(caps) < 0) {
@@ -249,6 +251,16 @@ linux_keepcaps(void) {
 	}
 }
 
+static void
+linux_losecaps(void) {
+	if (prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) < 0 && errno != EINVAL) {
+		char strbuf[ISC_STRERRORSIZE];
+		strerror_r(errno, strbuf, sizeof(strbuf));
+		named_main_earlyfatal("prctl(PR_SET_KEEPCAPS, 0) failed: %s",
+				   strbuf);
+	}
+}
+
 #endif /* HAVE_SYS_CAPABILITY_H */
 
 static void
@@ -455,7 +467,7 @@ named_os_changeuser(void) {
 		named_main_earlyfatal("setgid(): %s", strbuf);
 	}
 
-	if (setuid(runas_pw->pw_uid) < 0) {
+	if (setresuid(runas_pw->pw_uid, runas_pw->pw_uid, -1) < 0) {
 		strerror_r(errno, strbuf, sizeof(strbuf));
 		named_main_earlyfatal("setuid(): %s", strbuf);
 	}
@@ -475,6 +487,31 @@ named_os_changeuser(void) {
 #endif /* if defined(HAVE_SYS_CAPABILITY_H) */
 }
 
+void
+named_os_dropprivs(void) {
+	char strbuf[ISC_STRERRORSIZE];
+	if (runas_pw == NULL) {
+		return;
+	}
+	if (setresuid(runas_pw->pw_uid, runas_pw->pw_uid, runas_pw->pw_uid) < 0) {
+		strerror_r(errno, strbuf, sizeof(strbuf));
+		named_main_earlyfatal("setresuid(): %s", strbuf);
+	}
+
+#if defined(HAVE_SYS_CAPABILITY_H)
+	/*
+	 * Restore the ability of named to drop core after the setuid()
+	 * call has disabled it.
+	 */
+	if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
+		strerror_r(errno, strbuf, sizeof(strbuf));
+		named_main_earlywarning("prctl(PR_SET_DUMPABLE) failed: %s",
+					strbuf);
+	}
+
+#endif /* if defined(HAVE_SYS_CAPABILITY_H) */
+}
+
 uid_t
 ns_os_uid(void) {
 	if (runas_pw == NULL) {
@@ -507,7 +544,7 @@ named_os_minprivs(void) {
 #if defined(HAVE_SYS_CAPABILITY_H)
 	linux_keepcaps();
 	named_os_changeuser();
-	linux_minprivs();
+	linux_losecaps();
 #endif /* if defined(HAVE_SYS_CAPABILITY_H) */
 }
 
@@ -576,18 +613,21 @@ static int
 mkdirpath(char *filename, void (*report)(const char *, ...)) {
 	char *slash = strrchr(filename, '/');
 	char strbuf[ISC_STRERRORSIZE];
-	unsigned int mode;
 
 	if (slash != NULL && slash != filename) {
 		struct stat sb;
 		*slash = '\0';
 
 		if (stat(filename, &sb) == -1) {
+#ifdef WANT_SETPERMS
+			unsigned int mode;
 			if (errno != ENOENT) {
+#endif /* WANT_SETPERMS */
 				strerror_r(errno, strbuf, sizeof(strbuf));
 				(*report)("couldn't stat '%s': %s", filename,
 					  strbuf);
 				goto error;
+#ifdef WANT_SETPERMS
 			}
 			if (mkdirpath(filename, report) == -1) {
 				goto error;
@@ -618,6 +658,7 @@ mkdirpath(char *filename, void (*report)(const char *, ...)) {
 				(*report)("couldn't chown '%s': %s", filename,
 					  strbuf);
 			}
+#endif /* WANT_SETPERMS */
 		}
 		*slash = '/';
 	}
@@ -628,6 +669,7 @@ error:
 	return (-1);
 }
 
+#ifdef WANT_SETPERMS
 #if !HAVE_SYS_CAPABILITY_H
 static void
 setperms(uid_t uid, gid_t gid) {
@@ -677,6 +719,7 @@ setperms(uid_t uid, gid_t gid) {
 #endif /* if defined(HAVE_SETEUID) */
 }
 #endif /* HAVE_SYS_CAPABILITY_H */
+#endif /* WANT_SETPERMS */
 
 FILE *
 named_os_openfile(const char *filename, mode_t mode, bool switch_user) {
@@ -684,6 +727,9 @@ named_os_openfile(const char *filename, mode_t mode, bool switch_user) {
 	FILE *fp;
 	int fd;
 
+#ifndef WANT_SETPERMS
+	UNUSED(switch_user);
+#endif /* WANT_SETPERMS */
 	/*
 	 * Make the containing directory if it doesn't exist.
 	 */
@@ -700,6 +746,7 @@ named_os_openfile(const char *filename, mode_t mode, bool switch_user) {
 	}
 	free(f);
 
+#ifdef WANT_SETPERMS
 	if (switch_user && runas_pw != NULL) {
 		uid_t olduid = getuid();
 		gid_t oldgid = getgid();
@@ -733,7 +780,9 @@ named_os_openfile(const char *filename, mode_t mode, bool switch_user) {
 						"directory permissions "
 						"or reconfigure the filename.");
 		}
-	} else {
+	} else
+#endif /* WANT_SETPERMS */
+	{
 		fd = safe_open(filename, mode, false);
 	}
 
-- 
2.33.4
 
projeto & código: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
mantenedor atual: Michael Shigorin
mantenedor da tradução: Fernando Martini aka fmartini © 2009