Репозитории 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 |
Группа :: Система/Серверы
Пакет: 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