[openssh-commits] [openssh] branch master updated: Don't link sshd against libselinux
git+noreply at mindrot.org
git+noreply at mindrot.org
Tue Sep 15 17:23:59 AEST 2026
This is an automated email from the git hooks/post-receive script.
djm pushed a commit to branch master
in repository openssh.
The following commit(s) were added to refs/heads/master by this push:
new d91663336 Don't link sshd against libselinux
d91663336 is described below
commit d9166333616f4575749e64873796ad6a96f01c93
Author: Colin Watson <cjwatson at debian.org>
AuthorDate: Tue Sep 1 01:14:44 2026 +0100
Don't link sshd against libselinux
When configured with --with-selinux, the main sshd binary only appears
to need symbols from libselinux because functions that it needs are in
the same translation units as functions that use libselinux, meaning
that `ld --as-needed` doesn't realize that it can drop those functions
and the resulting DT_NEEDED tag.
This should have the effect of dropping libselinux and libpcre2-8 from
sshd's linkage in the configuration used by several common Linux
distributions, including Debian.
---
openbsd-compat/Makefile.in | 1 +
.../{port-linux.c => port-linux-selinux.c} | 183 +-----------------
openbsd-compat/port-linux.c | 211 +--------------------
3 files changed, 6 insertions(+), 389 deletions(-)
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in
index 53c87db6d..643aefed6 100644
--- a/openbsd-compat/Makefile.in
+++ b/openbsd-compat/Makefile.in
@@ -99,6 +99,7 @@ COMPAT= bsd-asprintf.o \
PORTS= port-aix.o \
port-irix.o \
port-linux.o \
+ port-linux-selinux.o \
port-prngd.o \
port-solaris.o \
port-net.o \
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux-selinux.c
similarity index 58%
copy from openbsd-compat/port-linux.c
copy to openbsd-compat/port-linux-selinux.c
index c1d54f38d..e36e2ec94 100644
--- a/openbsd-compat/port-linux.c
+++ b/openbsd-compat/port-linux-selinux.c
@@ -16,31 +16,27 @@
*/
/*
- * Linux-specific portability code - just SELinux support at present
+ * Linux-specific portability code: SELinux support
*/
#include "includes.h"
-#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) || \
- defined(SYSTEMD_NOTIFY)
+#ifdef WITH_SELINUX
+
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
-#include <inttypes.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
-#include <time.h>
-#include <unistd.h>
#include "log.h"
#include "xmalloc.h"
#include "port-linux.h"
#include "misc.h"
-#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#include <selinux/label.h>
#include <selinux/get_context_list.h>
@@ -245,176 +241,3 @@ ssh_selinux_setfscreatecon(const char *path)
}
#endif /* WITH_SELINUX */
-
-#ifdef LINUX_OOM_ADJUST
-/*
- * The magic "don't kill me" values, old and new, as documented in eg:
- * http://lxr.linux.no/#linux+v2.6.32/Documentation/filesystems/proc.txt
- * http://lxr.linux.no/#linux+v2.6.36/Documentation/filesystems/proc.txt
- */
-
-static int oom_adj_save = INT_MIN;
-static char *oom_adj_path = NULL;
-struct {
- char *path;
- int value;
-} oom_adjust[] = {
- {"/proc/self/oom_score_adj", -1000}, /* kernels >= 2.6.36 */
- {"/proc/self/oom_adj", -17}, /* kernels <= 2.6.35 */
- {NULL, 0},
-};
-
-/*
- * Tell the kernel's out-of-memory killer to avoid sshd.
- * Returns the previous oom_adj value or zero.
- */
-void
-oom_adjust_setup(void)
-{
- int i, value;
- FILE *fp;
-
- debug3("%s", __func__);
- for (i = 0; oom_adjust[i].path != NULL; i++) {
- oom_adj_path = oom_adjust[i].path;
- value = oom_adjust[i].value;
- if ((fp = fopen(oom_adj_path, "r+")) != NULL) {
- if (fscanf(fp, "%d", &oom_adj_save) != 1)
- verbose("error reading %s: %s", oom_adj_path,
- strerror(errno));
- else {
- rewind(fp);
- if (fprintf(fp, "%d\n", value) <= 0)
- verbose("error writing %s: %s",
- oom_adj_path, strerror(errno));
- else
- debug("Set %s from %d to %d",
- oom_adj_path, oom_adj_save, value);
- }
- fclose(fp);
- return;
- }
- }
- oom_adj_path = NULL;
-}
-
-/* Restore the saved OOM adjustment */
-void
-oom_adjust_restore(void)
-{
- FILE *fp;
-
- debug3("%s", __func__);
- if (oom_adj_save == INT_MIN || oom_adj_path == NULL ||
- (fp = fopen(oom_adj_path, "w")) == NULL)
- return;
-
- if (fprintf(fp, "%d\n", oom_adj_save) <= 0)
- verbose("error writing %s: %s", oom_adj_path, strerror(errno));
- else
- debug("Set %s to %d", oom_adj_path, oom_adj_save);
-
- fclose(fp);
- return;
-}
-#endif /* LINUX_OOM_ADJUST */
-
-#ifdef LINUX_MEMLOCK_ONFAULT
-#include <sys/mman.h>
-
-void
-memlock_onfault_setup(void)
-{
- if (mlockall(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT) < 0)
- verbose("unable to lock memory: %s", strerror(errno));
- else
- debug("memory locked");
-}
-#endif /* LINUX_MEMLOCK_ONFAULT */
-
-#ifdef SYSTEMD_NOTIFY
-
-static void ssh_systemd_notify(const char *, ...)
- __attribute__((__format__ (printf, 1, 2))) __attribute__((__nonnull__ (1)));
-
-static void
-ssh_systemd_notify(const char *fmt, ...)
-{
- char *s = NULL;
- const char *path;
- struct stat sb;
- struct sockaddr_un addr;
- int fd = -1;
- va_list ap;
-
- if ((path = getenv("NOTIFY_SOCKET")) == NULL || strlen(path) == 0)
- return;
-
- va_start(ap, fmt);
- xvasprintf(&s, fmt, ap);
- va_end(ap);
-
- /* Only AF_UNIX is supported, with path or abstract sockets */
- if (path[0] != '/' && path[0] != '@') {
- error_f("socket \"%s\" is not compatible with AF_UNIX", path);
- goto out;
- }
-
- if (path[0] == '/' && stat(path, &sb) != 0) {
- error_f("socket \"%s\" stat: %s", path, strerror(errno));
- goto out;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- if (strlcpy(addr.sun_path, path,
- sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) {
- error_f("socket path \"%s\" too long", path);
- goto out;
- }
- /* Support for abstract socket */
- if (addr.sun_path[0] == '@')
- addr.sun_path[0] = 0;
- if ((fd = socket(PF_UNIX, SOCK_DGRAM, 0)) == -1) {
- error_f("socket \"%s\": %s", path, strerror(errno));
- goto out;
- }
- if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
- error_f("socket \"%s\" connect: %s", path, strerror(errno));
- goto out;
- }
- if (write(fd, s, strlen(s)) != (ssize_t)strlen(s)) {
- error_f("socket \"%s\" write: %s", path, strerror(errno));
- goto out;
- }
- debug_f("socket \"%s\" notified %s", path, s);
- out:
- if (fd != -1)
- close(fd);
- free(s);
-}
-
-void
-ssh_systemd_notify_ready(void)
-{
- ssh_systemd_notify("READY=1");
-}
-
-void
-ssh_systemd_notify_reload(void)
-{
- struct timespec now;
-
- monotime_ts(&now);
- if (now.tv_sec < 0 || now.tv_nsec < 0) {
- error_f("monotime returned negative value");
- ssh_systemd_notify("RELOADING=1");
- } else {
- ssh_systemd_notify("RELOADING=1\nMONOTONIC_USEC=%llu",
- ((uint64_t)now.tv_sec * 1000000ULL) +
- ((uint64_t)now.tv_nsec / 1000ULL));
- }
-}
-#endif /* SYSTEMD_NOTIFY */
-
-#endif /* WITH_SELINUX || LINUX_OOM_ADJUST || SYSTEMD_NOTIFY */
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
index c1d54f38d..f47201143 100644
--- a/openbsd-compat/port-linux.c
+++ b/openbsd-compat/port-linux.c
@@ -16,13 +16,12 @@
*/
/*
- * Linux-specific portability code - just SELinux support at present
+ * Linux-specific portability code
*/
#include "includes.h"
-#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) || \
- defined(SYSTEMD_NOTIFY)
+#if defined(LINUX_OOM_ADJUST) || defined(SYSTEMD_NOTIFY)
#include <sys/socket.h>
#include <sys/un.h>
@@ -40,212 +39,6 @@
#include "port-linux.h"
#include "misc.h"
-#ifdef WITH_SELINUX
-#include <selinux/selinux.h>
-#include <selinux/label.h>
-#include <selinux/get_context_list.h>
-
-#ifndef SSH_SELINUX_UNCONFINED_TYPE
-# define SSH_SELINUX_UNCONFINED_TYPE ":unconfined_t:"
-#endif
-
-/* Wrapper around is_selinux_enabled() to log its return value once only */
-int
-ssh_selinux_enabled(void)
-{
- static int enabled = -1;
-
- if (enabled == -1) {
- enabled = (is_selinux_enabled() == 1);
- debug("SELinux support %s", enabled ? "enabled" : "disabled");
- }
-
- return (enabled);
-}
-
-/* Return the default security context for the given username */
-static char *
-ssh_selinux_getctxbyname(char *pwname)
-{
- char *sc = NULL, *sename = NULL, *lvl = NULL;
- int r;
-
-#ifdef HAVE_GETSEUSERBYNAME
- if (getseuserbyname(pwname, &sename, &lvl) != 0)
- return NULL;
-#else
- sename = pwname;
- lvl = NULL;
-#endif
-
-#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
- r = get_default_context_with_level(sename, lvl, NULL, &sc);
-#else
- r = get_default_context(sename, NULL, &sc);
-#endif
-
- if (r != 0) {
- switch (security_getenforce()) {
- case -1:
- fatal("%s: ssh_selinux_getctxbyname: "
- "security_getenforce() failed", __func__);
- case 0:
- error("%s: Failed to get default SELinux security "
- "context for %s", __func__, pwname);
- sc = NULL;
- break;
- default:
- fatal("%s: Failed to get default SELinux security "
- "context for %s (in enforcing mode)",
- __func__, pwname);
- }
- }
-
-#ifdef HAVE_GETSEUSERBYNAME
- free(sename);
- free(lvl);
-#endif
-
- return sc;
-}
-
-/* Set the execution context to the default for the specified user */
-void
-ssh_selinux_setup_exec_context(char *pwname)
-{
- char *user_ctx = NULL;
-
- if (!ssh_selinux_enabled())
- return;
-
- debug3("%s: setting execution context", __func__);
-
- user_ctx = ssh_selinux_getctxbyname(pwname);
- if (setexeccon(user_ctx) != 0) {
- switch (security_getenforce()) {
- case -1:
- fatal("%s: security_getenforce() failed", __func__);
- case 0:
- error("%s: Failed to set SELinux execution "
- "context for %s", __func__, pwname);
- break;
- default:
- fatal("%s: Failed to set SELinux execution context "
- "for %s (in enforcing mode)", __func__, pwname);
- }
- }
- if (user_ctx != NULL)
- freecon(user_ctx);
-
- debug3("%s: done", __func__);
-}
-
-/* Set the TTY context for the specified user */
-void
-ssh_selinux_setup_pty(char *pwname, const char *tty)
-{
- char *new_tty_ctx = NULL, *user_ctx = NULL, *old_tty_ctx = NULL;
- security_class_t chrclass;
-
- if (!ssh_selinux_enabled())
- return;
-
- debug3("%s: setting TTY context on %s", __func__, tty);
-
- user_ctx = ssh_selinux_getctxbyname(pwname);
-
- /* XXX: should these calls fatal() upon failure in enforcing mode? */
-
- if (getfilecon(tty, &old_tty_ctx) == -1) {
- error("%s: getfilecon: %s", __func__, strerror(errno));
- goto out;
- }
- if ((chrclass = string_to_security_class("chr_file")) == 0) {
- error("%s: couldn't get security class for chr_file", __func__);
- goto out;
- }
- if (security_compute_relabel(user_ctx, old_tty_ctx,
- chrclass, &new_tty_ctx) != 0) {
- error("%s: security_compute_relabel: %s",
- __func__, strerror(errno));
- goto out;
- }
-
- if (setfilecon(tty, new_tty_ctx) != 0)
- error("%s: setfilecon: %s", __func__, strerror(errno));
- out:
- if (new_tty_ctx != NULL)
- freecon(new_tty_ctx);
- if (old_tty_ctx != NULL)
- freecon(old_tty_ctx);
- if (user_ctx != NULL)
- freecon(user_ctx);
- debug3("%s: done", __func__);
-}
-
-void
-ssh_selinux_change_context(const char *newname)
-{
- char *oldctx, *newctx, *cx, *cx2;
- LogLevel log_level = SYSLOG_LEVEL_INFO;
-
- if (!ssh_selinux_enabled())
- return;
-
- if (getcon(&oldctx) < 0) {
- logit_f("getcon failed with %s", strerror(errno));
- return;
- }
- if ((cx = strchr(oldctx, ':')) == NULL ||
- (cx = strchr(cx + 1, ':')) == NULL ||
- (cx - oldctx) >= INT_MAX) {
- logit_f("unparsable context %s", oldctx);
- return;
- }
-
- /*
- * Check whether we are attempting to switch away from an unconfined
- * security context.
- */
- if (strncmp(cx, SSH_SELINUX_UNCONFINED_TYPE,
- sizeof(SSH_SELINUX_UNCONFINED_TYPE) - 1) == 0)
- log_level = SYSLOG_LEVEL_DEBUG3;
-
- cx2 = strchr(cx + 1, ':');
- xasprintf(&newctx, "%.*s%s%s", (int)(cx - oldctx + 1), oldctx,
- newname, cx2 == NULL ? "" : cx2);
-
- debug3_f("setting context from '%s' to '%s'", oldctx, newctx);
- if (setcon(newctx) < 0)
- do_log2_f(log_level, "setcon %s from %s failed with %s",
- newctx, oldctx, strerror(errno));
- free(oldctx);
- free(newctx);
-}
-
-void
-ssh_selinux_setfscreatecon(const char *path)
-{
- char *context;
- struct selabel_handle *shandle = NULL;
-
- if (!ssh_selinux_enabled())
- return;
- if (path == NULL) {
- setfscreatecon(NULL);
- return;
- }
- if ((shandle = selabel_open(SELABEL_CTX_FILE, NULL, 0)) == NULL) {
- debug_f("selabel_open failed");
- return;
- }
- if (selabel_lookup(shandle, &context, path, 0700) == 0)
- setfscreatecon(context);
- selabel_close(shandle);
-}
-
-#endif /* WITH_SELINUX */
-
#ifdef LINUX_OOM_ADJUST
/*
* The magic "don't kill me" values, old and new, as documented in eg:
--
To stop receiving notification emails like this one, please contact
djm at mindrot.org.
More information about the openssh-commits
mailing list