Antonio Larrosa
da2c6cc517
* No changes for askpass, see main package changelog for details. - Fix a dbus connection leaked in the logind patch that was missing a sd_bus_unref call (found by Matthias Gerstner): * logind_set_tty.patch - Add a patch that fixes a small memory leak when parsing the subsystem configuration option: * fix-memleak-in-process_server_config_line_depth.patch - Update to openssh 9.8p1: = Security * 1) Race condition in sshd(8) (bsc#1226642, CVE-2024-6387). A critical vulnerability in sshd(8) was present in Portable OpenSSH versions between 8.5p1 and 9.7p1 (inclusive) that may allow arbitrary code execution with root privileges. Successful exploitation has been demonstrated on 32-bit Linux/glibc systems with ASLR. Under lab conditions, the attack requires on average 6-8 hours of continuous connections up to the maximum the server will accept. Exploitation on 64-bit systems is believed to be possible but has not been demonstrated at this time. It's likely that these attacks will be improved upon. Exploitation on non-glibc systems is conceivable but has not been examined. Systems that lack ASLR or users of downstream Linux distributions that have modified OpenSSH to disable per-connection ASLR re-randomisation (yes - this is a thing, no - we don't understand why) may potentially have an easier path to exploitation. OpenBSD is not vulnerable. OBS-URL: https://build.opensuse.org/package/show/network/openssh?expand=0&rev=272
281 lines
9.3 KiB
Diff
281 lines
9.3 KiB
Diff
Index: openssh-9.3p2/auth2-pubkey.c
|
|
===================================================================
|
|
--- openssh-9.3p2.orig/auth2-pubkey.c
|
|
+++ openssh-9.3p2/auth2-pubkey.c
|
|
@@ -72,6 +72,9 @@
|
|
|
|
/* import */
|
|
extern ServerOptions options;
|
|
+extern int inetd_flag;
|
|
+extern int rexeced_flag;
|
|
+extern Authctxt *the_authctxt;
|
|
extern struct authmethod_cfg methodcfg_pubkey;
|
|
|
|
static char *
|
|
@@ -459,7 +462,8 @@ match_principals_command(struct passwd *
|
|
if ((pid = subprocess("AuthorizedPrincipalsCommand", command,
|
|
ac, av, &f,
|
|
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
|
|
- runas_pw, temporarily_use_uid, restore_uid)) == 0)
|
|
+ runas_pw, temporarily_use_uid, restore_uid,
|
|
+ inetd_flag, the_authctxt)) == 0)
|
|
goto out;
|
|
|
|
uid_swapped = 1;
|
|
@@ -727,7 +731,8 @@ user_key_command_allowed2(struct passwd
|
|
if ((pid = subprocess("AuthorizedKeysCommand", command,
|
|
ac, av, &f,
|
|
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
|
|
- runas_pw, temporarily_use_uid, restore_uid)) == 0)
|
|
+ runas_pw, temporarily_use_uid, restore_uid,
|
|
+ inetd_flag, the_authctxt)) == 0)
|
|
goto out;
|
|
|
|
uid_swapped = 1;
|
|
Index: openssh-9.3p2/misc.c
|
|
===================================================================
|
|
--- openssh-9.3p2.orig/misc.c
|
|
+++ openssh-9.3p2/misc.c
|
|
@@ -2637,7 +2637,8 @@ stdfd_devnull(int do_stdin, int do_stdou
|
|
pid_t
|
|
subprocess(const char *tag, const char *command,
|
|
int ac, char **av, FILE **child, u_int flags,
|
|
- struct passwd *pw, privdrop_fn *drop_privs, privrestore_fn *restore_privs)
|
|
+ struct passwd *pw, privdrop_fn *drop_privs,
|
|
+ privrestore_fn *restore_privs, int inetd, void *the_authctxt)
|
|
{
|
|
FILE *f = NULL;
|
|
struct stat st;
|
|
@@ -2771,7 +2772,7 @@ subprocess(const char *tag, const char *
|
|
_exit(1);
|
|
}
|
|
#ifdef WITH_SELINUX
|
|
- if (sshd_selinux_setup_env_variables() < 0) {
|
|
+ if (sshd_selinux_setup_env_variables(inetd, the_authctxt) < 0) {
|
|
error ("failed to copy environment: %s",
|
|
strerror(errno));
|
|
_exit(127);
|
|
Index: openssh-9.3p2/misc.h
|
|
===================================================================
|
|
--- openssh-9.3p2.orig/misc.h
|
|
+++ openssh-9.3p2/misc.h
|
|
@@ -110,7 +110,7 @@ typedef void privrestore_fn(void);
|
|
#define SSH_SUBPROCESS_UNSAFE_PATH (1<<3) /* Don't check for safe cmd */
|
|
#define SSH_SUBPROCESS_PRESERVE_ENV (1<<4) /* Keep parent environment */
|
|
pid_t subprocess(const char *, const char *, int, char **, FILE **, u_int,
|
|
- struct passwd *, privdrop_fn *, privrestore_fn *);
|
|
+ struct passwd *, privdrop_fn *, privrestore_fn *, int, void *);
|
|
|
|
typedef struct arglist arglist;
|
|
struct arglist {
|
|
Index: openssh-9.3p2/openbsd-compat/port-linux.h
|
|
===================================================================
|
|
--- openssh-9.3p2.orig/openbsd-compat/port-linux.h
|
|
+++ openssh-9.3p2/openbsd-compat/port-linux.h
|
|
@@ -25,8 +25,8 @@ void ssh_selinux_setfscreatecon(const ch
|
|
|
|
int sshd_selinux_enabled(void);
|
|
void sshd_selinux_copy_context(void);
|
|
-void sshd_selinux_setup_exec_context(char *);
|
|
-int sshd_selinux_setup_env_variables(void);
|
|
+void sshd_selinux_setup_exec_context(char *, int, int(char *, const char *), void *, int);
|
|
+int sshd_selinux_setup_env_variables(int inetd, void *);
|
|
void sshd_selinux_change_privsep_preauth_context(void);
|
|
#endif
|
|
|
|
Index: openssh-9.3p2/openbsd-compat/port-linux-sshd.c
|
|
===================================================================
|
|
--- openssh-9.3p2.orig/openbsd-compat/port-linux-sshd.c
|
|
+++ openssh-9.3p2/openbsd-compat/port-linux-sshd.c
|
|
@@ -49,10 +49,6 @@
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
-extern ServerOptions options;
|
|
-extern Authctxt *the_authctxt;
|
|
-extern int inetd_flag;
|
|
-
|
|
/* Wrapper around is_selinux_enabled() to log its return value once only */
|
|
int
|
|
sshd_selinux_enabled(void)
|
|
@@ -223,7 +218,8 @@ get_user_context(const char *sename, con
|
|
}
|
|
|
|
static void
|
|
-ssh_selinux_get_role_level(char **role, const char **level)
|
|
+ssh_selinux_get_role_level(char **role, const char **level,
|
|
+ Authctxt *the_authctxt)
|
|
{
|
|
*role = NULL;
|
|
*level = NULL;
|
|
@@ -241,8 +237,8 @@ ssh_selinux_get_role_level(char **role,
|
|
|
|
/* Return the default security context for the given username */
|
|
static int
|
|
-sshd_selinux_getctxbyname(char *pwname,
|
|
- security_context_t *default_sc, security_context_t *user_sc)
|
|
+sshd_selinux_getctxbyname(char *pwname, security_context_t *default_sc,
|
|
+ security_context_t *user_sc, int inetd, Authctxt *the_authctxt)
|
|
{
|
|
char *sename, *lvl;
|
|
char *role;
|
|
@@ -250,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname,
|
|
int r = 0;
|
|
context_t con = NULL;
|
|
|
|
- ssh_selinux_get_role_level(&role, &reqlvl);
|
|
+ ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt);
|
|
|
|
#ifdef HAVE_GETSEUSERBYNAME
|
|
if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
|
|
@@ -272,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname,
|
|
|
|
if (r == 0) {
|
|
/* If launched from xinetd, we must use current level */
|
|
- if (inetd_flag) {
|
|
+ if (inetd) {
|
|
security_context_t sshdsc=NULL;
|
|
|
|
if (getcon_raw(&sshdsc) < 0)
|
|
@@ -333,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname,
|
|
|
|
/* Setup environment variables for pam_selinux */
|
|
static int
|
|
-sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
|
|
+sshd_selinux_setup_variables(int(*set_it)(char *, const char *), int inetd,
|
|
+ Authctxt *the_authctxt)
|
|
{
|
|
const char *reqlvl;
|
|
char *role;
|
|
@@ -342,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it
|
|
|
|
debug3_f("setting execution context");
|
|
|
|
- ssh_selinux_get_role_level(&role, &reqlvl);
|
|
+ ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt);
|
|
|
|
rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : "");
|
|
|
|
- if (inetd_flag) {
|
|
+ if (inetd) {
|
|
use_current = "1";
|
|
} else {
|
|
use_current = "";
|
|
@@ -362,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it
|
|
}
|
|
|
|
static int
|
|
-sshd_selinux_setup_pam_variables(void)
|
|
+sshd_selinux_setup_pam_variables(int inetd,
|
|
+ int(pam_setenv)(char *, const char *), Authctxt *the_authctxt)
|
|
{
|
|
- return sshd_selinux_setup_variables(do_pam_putenv);
|
|
+ return sshd_selinux_setup_variables(pam_setenv, inetd, the_authctxt);
|
|
}
|
|
|
|
static int
|
|
@@ -374,25 +372,28 @@ do_setenv(char *name, const char *value)
|
|
}
|
|
|
|
int
|
|
-sshd_selinux_setup_env_variables(void)
|
|
+sshd_selinux_setup_env_variables(int inetd, void *the_authctxt)
|
|
{
|
|
- return sshd_selinux_setup_variables(do_setenv);
|
|
+ Authctxt *authctxt = (Authctxt *) the_authctxt;
|
|
+ return sshd_selinux_setup_variables(do_setenv, inetd, authctxt);
|
|
}
|
|
|
|
/* Set the execution context to the default for the specified user */
|
|
void
|
|
-sshd_selinux_setup_exec_context(char *pwname)
|
|
+sshd_selinux_setup_exec_context(char *pwname, int inetd,
|
|
+ int(pam_setenv)(char *, const char *), void *the_authctxt, int use_pam)
|
|
{
|
|
security_context_t user_ctx = NULL;
|
|
int r = 0;
|
|
security_context_t default_ctx = NULL;
|
|
+ Authctxt *authctxt = (Authctxt *) the_authctxt;
|
|
|
|
if (!sshd_selinux_enabled())
|
|
return;
|
|
|
|
- if (options.use_pam) {
|
|
+ if (use_pam) {
|
|
/* do not compute context, just setup environment for pam_selinux */
|
|
- if (sshd_selinux_setup_pam_variables()) {
|
|
+ if (sshd_selinux_setup_pam_variables(inetd, pam_setenv, authctxt)) {
|
|
switch (security_getenforce()) {
|
|
case -1:
|
|
fatal_f("security_getenforce() failed");
|
|
@@ -408,7 +409,7 @@ sshd_selinux_setup_exec_context(char *pw
|
|
|
|
debug3_f("setting execution context");
|
|
|
|
- r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
|
|
+ r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx, inetd, authctxt);
|
|
if (r >= 0) {
|
|
r = setexeccon(user_ctx);
|
|
if (r < 0) {
|
|
Index: openssh-9.3p2/platform.c
|
|
===================================================================
|
|
--- openssh-9.3p2.orig/platform.c
|
|
+++ openssh-9.3p2/platform.c
|
|
@@ -34,6 +34,8 @@
|
|
#include "openbsd-compat/openbsd-compat.h"
|
|
|
|
extern ServerOptions options;
|
|
+extern int inetd_flag;
|
|
+extern Authctxt *the_authctxt;
|
|
|
|
/* return 1 if we are running with privilege to swap UIDs, 0 otherwise */
|
|
int
|
|
@@ -185,7 +187,9 @@ platform_setusercontext_post_groups(stru
|
|
}
|
|
#endif /* HAVE_SETPCRED */
|
|
#ifdef WITH_SELINUX
|
|
- sshd_selinux_setup_exec_context(pw->pw_name);
|
|
+ sshd_selinux_setup_exec_context(pw->pw_name,
|
|
+ inetd_flag, do_pam_putenv, the_authctxt,
|
|
+ options.use_pam);
|
|
#endif
|
|
}
|
|
|
|
Index: openssh-9.3p2/sshd-session.c
|
|
===================================================================
|
|
--- openssh-9.3p2.orig/sshd-session.c
|
|
+++ openssh-9.3p2/sshd-session.c
|
|
@@ -166,7 +166,7 @@ int debug_flag = 0;
|
|
int debug_flag = 0;
|
|
|
|
/* Flag indicating that the daemon is being started from inetd. */
|
|
-static int inetd_flag = 0;
|
|
+int inetd_flag = 0;
|
|
|
|
/* debug goes to stderr unless inetd_flag is set */
|
|
static int log_stderr = 0;
|
|
@@ -2396,7 +2396,9 @@ main(int ac, char **av)
|
|
}
|
|
#endif
|
|
#ifdef WITH_SELINUX
|
|
- sshd_selinux_setup_exec_context(authctxt->pw->pw_name);
|
|
+ sshd_selinux_setup_exec_context(authctxt->pw->pw_name,
|
|
+ inetd_flag, do_pam_putenv, the_authctxt,
|
|
+ options.use_pam);
|
|
#endif
|
|
#ifdef USE_PAM
|
|
if (options.use_pam) {
|
|
Index: openssh-9.3p2/sshconnect.c
|
|
===================================================================
|
|
--- openssh-9.3p2.orig/sshconnect.c
|
|
+++ openssh-9.3p2/sshconnect.c
|
|
@@ -893,7 +893,7 @@ load_hostkeys_command(struct hostkeys *h
|
|
|
|
if ((pid = subprocess(tag, command, ac, av, &f,
|
|
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_UNSAFE_PATH|
|
|
- SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL)) == 0)
|
|
+ SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL, 0, NULL)) == 0)
|
|
goto out;
|
|
|
|
load_hostkeys_file(hostkeys, hostfile_hostname, tag, f, 1);
|