Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37767982
en ru br
Репозитории ALT
S:9.16.44-alt1
5.1: 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
www.altlinux.org/Changes

Группа :: Система/Серверы
Пакет: bind

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: 0003-ALT-Make-it-possible-to-retain-Linux-capabilities-of.patch
Скачать


From 748e21b42e4ca8276e085e447e8dbe43352908bb Mon Sep 17 00:00:00 2001
From: Stanislav Levin <slev@altlinux.org>
Date: Fri, 29 May 2020 15:31:08 +0300
Subject: [PATCH] ALT: Make it possible to retain Linux capabilities of named
Current behaviour of named is differ from upstream
version. This leads to the failures under the certain
conditions. One of the incompatibilities is the
different employment of Linux capabilities(7).
This is how the process of caps setup/dropping looks for now:
___________________________________________________
conditions:
HAVE_LINUX_CAPABILITY_H && HAVE_LIBCAP && HAVE_LINUXTHREADS
caps initial set: CAP_NET_BIND_SERVICE
                  CAP_SYS_CHROOT
                  CAP_SETUID
                  CAP_SETGID
                  CAP_DAC_READ_SEARCH
                  CAP_SYS_RESOURCE
                  CAP_CHOWN
caps working set: CAP_NET_BIND_SERVICE
                  CAP_SYS_RESOURCE
___________________________________________________
upstream version:
ns_os_init:
    linux_initialprivs : apply caps initial set
ns_os_minprivs :
    linux_keepcaps : keep caps after setuid
    ns_os_changeuser : setgid; setuid;
    linux_minprivs : apply caps working set
___________________________________________________
ALT specific:
ns_os_init:
    linux_initialprivs : apply caps initial set
ns_os_minprivs :
    linux_keepcaps : keep caps after setuid
    ns_os_changeuser : setgid; setresuid (named, named, -1)
        linux_minprivs : apply caps working set
    linux_losecaps : don't keep caps after setuid
=> configuration was loaded, threads run
ns_os_dropprivs : setresuid all uids to non-zero
                  (also clears all caps for all threads)
___________________________________________________
Simply put, we drop all the capabilities, while upstream retains
CAP_NET_BIND_SERVICE and CAP_SYS_RESOURCE.
Proposal is the implementation of another mode of operation on capabilities:
ns_os_init
    linux_cap_drop_bounding_set : clear cap bounding set
    linux_initialprivs : sets initial caps
ns_os_minprivs :
    linux_keepcaps : keep caps after setuid
    ns_os_changeuser : setgid; setuid
        linux_minprivs : apply caps working set
    linux_losecaps : don't keep caps after setuid
In this mode named retains CAP_NET_BIND_SERVICE and CAP_SYS_RESOURCE,
but drops caps bounding set as well as SECBIT_KEEP_CAPS.
Fixes: https://bugzilla.altlinux.org/show_bug.cgi?id=33300
---
 bind/bin/named/include/named/globals.h |  1 +
 bind/bin/named/include/named/main.h    |  2 +-
 bind/bin/named/main.c                  |  5 +++-
 bind/bin/named/server.c                |  4 ++-
 bind/bin/named/unix/os.c               | 36 +++++++++++++++++++++++---
 5 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/bind/bin/named/include/named/globals.h b/bind/bin/named/include/named/globals.h
index 82b632ef043..4436ef8eb61 100644
--- a/bind/bin/named/include/named/globals.h
+++ b/bind/bin/named/include/named/globals.h
@@ -111,6 +111,7 @@ EXTERN isc_resourcevalue_t named_g_initopenfiles INIT(0);
 /*
  * Misc.
  */
+EXTERN bool named_g_retain_caps     INIT(false);
 EXTERN bool named_g_coreok	     INIT(true);
 EXTERN const char *named_g_chrootdir INIT(NULL);
 EXTERN bool named_g_foreground	     INIT(false);
diff --git a/bind/bin/named/include/named/main.h b/bind/bin/named/include/named/main.h
index ee790b96ca3..ee4a451b3dd 100644
--- a/bind/bin/named/include/named/main.h
+++ b/bind/bin/named/include/named/main.h
@@ -23,7 +23,7 @@
 /*
  * Commandline arguments for named; also referenced in win32/ntservice.c
  */
-#define NAMED_MAIN_ARGS "46A:c:Cd:D:E:fFgL:M:m:n:N:p:sS:t:T:U:u:vVx:X:"
+#define NAMED_MAIN_ARGS "46A:c:Cd:D:E:fFgL:M:m:n:N:p:rsS:t:T:U:u:vVx:X:"
 
 ISC_PLATFORM_NORETURN_PRE void
 named_main_earlyfatal(const char *format, ...)
diff --git a/bind/bin/named/main.c b/bind/bin/named/main.c
index 97cd36f6925..25c3313fc35 100644
--- a/bind/bin/named/main.c
+++ b/bind/bin/named/main.c
@@ -345,7 +345,7 @@ usage(void) {
 	fprintf(stderr, "usage: named [-4|-6] [-c conffile] [-d debuglevel] "
 			"[-D comment] [-E engine]\n"
 			"             [-f|-g] [-L logfile] [-n number_of_cpus] "
-			"[-p port] [-s]\n"
+			"[-p port] [-r] [-s]\n"
 			"             [-S sockets] [-t chrootdir] [-u "
 			"username] [-U listeners]\n"
 			"             [-X lockfile] [-m "
@@ -954,6 +954,9 @@ parse_command_line(int argc, char *argv[]) {
 			}
 			named_g_port = port;
 			break;
+		case 'r':
+			named_g_retain_caps = true;
+			break;
 		case 's':
 			/* XXXRTH temporary syntax */
 			want_stats = true;
diff --git a/bind/bin/named/server.c b/bind/bin/named/server.c
index 0c0fdc409bd..3a5e2e15cd7 100644
--- a/bind/bin/named/server.c
+++ b/bind/bin/named/server.c
@@ -9194,7 +9194,9 @@ load_configuration(const char *filename, named_server_t *server,
 	 */
 	if (first_time) {
 		named_os_changeuser();
-		named_os_dropprivs();
+		if (!named_g_retain_caps) {
+			named_os_dropprivs();
+		}
 	}
 
 	/*
diff --git a/bind/bin/named/unix/os.c b/bind/bin/named/unix/os.c
index 44faacde85e..090b1654fd3 100644
--- a/bind/bin/named/unix/os.c
+++ b/bind/bin/named/unix/os.c
@@ -197,6 +197,28 @@ linux_initialprivs(void) {
 	FREE_CAP;
 }
 
+static void
+linux_cap_drop_bounding_set(void) {
+	/*
+	 * actually, cap_drop_bound (PR_CAPBSET_DROP) requires CAP_SETPCAP
+	 * capability, but to simplify the logic drop bounding set only
+	 * for root assuming that a regular user is not granted with caps.
+	*/
+	if (getuid() != 0) {
+		return;
+	}
+	cap_value_t capval = 0;
+	char strbuf[ISC_STRERRORSIZE];
+	while (CAP_IS_SUPPORTED(capval)) {
+		if (cap_drop_bound(capval) != 0) {
+			strerror_r(errno, strbuf, sizeof(strbuf));
+			named_main_earlyfatal("cap_drop_bound failed: %s",
+					      strbuf);
+		}
+		capval++;
+	}
+}
+
 static void
 linux_minprivs(void) {
 	cap_t caps;
@@ -278,6 +300,7 @@ void
 named_os_init(const char *progname) {
 	setup_syslog(progname);
 #ifdef HAVE_SYS_CAPABILITY_H
+	linux_cap_drop_bounding_set();
 	linux_initialprivs();
 #endif /* ifdef HAVE_SYS_CAPABILITY_H */
 #ifdef SIGXFSZ
@@ -467,9 +490,16 @@ named_os_changeuser(void) {
 		named_main_earlyfatal("setgid(): %s", strbuf);
 	}
 
-	if (setresuid(runas_pw->pw_uid, runas_pw->pw_uid, -1) < 0) {
-		strerror_r(errno, strbuf, sizeof(strbuf));
-		named_main_earlyfatal("setuid(): %s", strbuf);
+	if (!named_g_retain_caps) {
+		if (setresuid(runas_pw->pw_uid, runas_pw->pw_uid, -1) < 0) {
+			strerror_r(errno, strbuf, sizeof(strbuf));
+			named_main_earlyfatal("setresuid(): %s", strbuf);
+		}
+	} else {
+		if (setuid(runas_pw->pw_uid) < 0) {
+			strerror_r(errno, strbuf, sizeof(strbuf));
+			named_main_earlyfatal("setuid(): %s", strbuf);
+		}
 	}
 
 #if defined(HAVE_SYS_CAPABILITY_H)
-- 
2.33.4
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin