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
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