Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package openssh for openSUSE:Factory checked in at 2024-04-08 17:37:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/openssh (Old) and /work/SRC/openSUSE:Factory/.openssh.new.1905 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "openssh" Mon Apr 8 17:37:41 2024 rev:172 rq:1166157 version:9.6p1 Changes: -------- --- /work/SRC/openSUSE:Factory/openssh/openssh.changes 2024-04-04 22:25:29.305609598 +0200 +++ /work/SRC/openSUSE:Factory/.openssh.new.1905/openssh.changes 2024-04-08 17:37:59.570053154 +0200 @@ -1,0 +2,23 @@ +Fri Apr 5 11:10:18 UTC 2024 - Antonio Larrosa <alarr...@suse.com> + +- Add missing bugzilla/CVE references to the changelog + +------------------------------------------------------------------- +Thu Apr 4 12:23:13 UTC 2024 - Antonio Larrosa <alarr...@suse.com> + +- Add patch from SLE which was missing in Factory: + * Mon Jun 7 20:54:09 UTC 2021 - Hans Petter Jansson <h...@suse.com> +- Add openssh-mitigate-lingering-secrets.patch (bsc#1186673), which + attempts to mitigate instances of secrets lingering in memory + after a session exits. (bsc#1213004 bsc#1213008) +- Rebase patch: + * openssh-6.6p1-privsep-selinux.patch + +------------------------------------------------------------------- +Tue Apr 2 13:07:43 UTC 2024 - Martin Sirringhaus <martin.sirringh...@suse.com> + +- Rebase openssh-7.7p1-fips.patch (bsc#1221928) + Remove OPENSSL_HAVE_EVPGCM-ifdef, which is no longer supported by + upstream + +------------------------------------------------------------------- @@ -30 +53,2 @@ - would not be able to detect that messages were deleted. + would not be able to detect that messages were deleted + (bsc#1217950, CVE-2023-48795). @@ -282 +306 @@ -- Update to openssh 9.3p2 (bsc#1213504, CVE-2023-38408): +- Update to openssh 9.3p2: @@ -286 +310 @@ - Fix CVE-2023-38408 - a condition where specific libaries loaded via + Fix a condition where specific libaries loaded via @@ -289 +313 @@ - conditions are met: + conditions are met (bsc#1213504, CVE-2023-38408): @@ -1045 +1069 @@ - gain unintended privilege. + gain unintended privilege (bsc#1190975, CVE-2021-41617). @@ -1244 +1268 @@ - with access to the agent socket. + with access to the agent socket (bsc#1183137, CVE-2021-28041) @@ -2273 +2297,3 @@ - * openssh-7.7p1-fips_checks.patch + * openssh-7.7p1-fips_checks.patch . Close the right + filedescriptor to avoid fd leads, and also close fdh in + read_hmac (bsc#1209536). New: ---- openssh-mitigate-lingering-secrets.patch BETA DEBUG BEGIN: New:/work/SRC/openSUSE:Factory/.openssh.new.1905/openssh.changes- * Mon Jun 7 20:54:09 UTC 2021 - Hans Petter Jansson <h...@suse.com> /work/SRC/openSUSE:Factory/.openssh.new.1905/openssh.changes:- Add openssh-mitigate-lingering-secrets.patch (bsc#1186673), which /work/SRC/openSUSE:Factory/.openssh.new.1905/openssh.changes- attempts to mitigate instances of secrets lingering in memory BETA DEBUG END: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ openssh.spec ++++++ --- /var/tmp/diff_new_pack.VpsQer/_old 2024-04-08 17:38:06.902323789 +0200 +++ /var/tmp/diff_new_pack.VpsQer/_new 2024-04-08 17:38:06.902323789 +0200 @@ -116,6 +116,7 @@ Patch50: openssh-openssl-3.patch Patch51: wtmpdb.patch Patch52: logind_set_tty.patch +Patch54: openssh-mitigate-lingering-secrets.patch Patch100: fix-missing-lz.patch Patch102: openssh-7.8p1-role-mls.patch Patch103: openssh-6.6p1-privsep-selinux.patch ++++++ openssh-6.6p1-privsep-selinux.patch ++++++ --- /var/tmp/diff_new_pack.VpsQer/_old 2024-04-08 17:38:06.986326890 +0200 +++ /var/tmp/diff_new_pack.VpsQer/_new 2024-04-08 17:38:06.990327037 +0200 @@ -114,7 +114,7 @@ if (privsep_chroot) { /* Change our root directory */ @@ -602,6 +606,9 @@ privsep_postauth(struct ssh *ssh, Authct - { + #ifdef DISABLE_FD_PASSING if (1) { +#elif defined(WITH_SELINUX) ++++++ openssh-7.7p1-fips.patch ++++++ --- /var/tmp/diff_new_pack.VpsQer/_old 2024-04-08 17:38:07.022328218 +0200 +++ /var/tmp/diff_new_pack.VpsQer/_new 2024-04-08 17:38:07.026328366 +0200 @@ -39,7 +39,7 @@ #ifdef WITH_OPENSSL #ifndef OPENSSL_NO_DES { "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc }, -@@ -110,8 +113,52 @@ static const struct sshcipher ciphers[] +@@ -110,8 +113,50 @@ static const struct sshcipher ciphers[] { NULL, 0, 0, 0, 0, 0, NULL } }; @@ -53,12 +53,10 @@ + { "aes128-ctr", 16, 16, 0, 0, 0, EVP_aes_128_ctr }, + { "aes192-ctr", 16, 24, 0, 0, 0, EVP_aes_192_ctr }, + { "aes256-ctr", 16, 32, 0, 0, 0, EVP_aes_256_ctr }, -+# ifdef OPENSSL_HAVE_EVPGCM + { "aes128-...@openssh.com", + 16, 16, 12, 16, 0, EVP_aes_128_gcm }, + { "aes256-...@openssh.com", + 16, 32, 12, 16, 0, EVP_aes_256_gcm }, -+# endif /* OPENSSL_HAVE_EVPGCM */ +#else + { "aes128-ctr", 16, 16, 0, 0, CFLAG_AESCTR, NULL }, + { "aes192-ctr", 16, 24, 0, 0, CFLAG_AESCTR, NULL }, ++++++ openssh-mitigate-lingering-secrets.patch ++++++ Index: openssh-9.3p2/kex.c =================================================================== --- openssh-9.3p2.orig/kex.c +++ openssh-9.3p2/kex.c @@ -1564,16 +1564,16 @@ enc_destroy(struct sshenc *enc) return; if (enc->key) { - memset(enc->key, 0, enc->key_len); + explicit_bzero(enc->key, enc->key_len); free(enc->key); } if (enc->iv) { - memset(enc->iv, 0, enc->iv_len); + explicit_bzero(enc->iv, enc->iv_len); free(enc->iv); } - memset(enc, 0, sizeof(*enc)); + explicit_bzero(enc, sizeof(*enc)); } void @@ -1584,7 +1584,7 @@ newkeys_destroy(struct newkeys *newkeys) enc_destroy(&newkeys->enc); mac_destroy(&newkeys->mac); - memset(&newkeys->comp, 0, sizeof(newkeys->comp)); + explicit_bzero(&newkeys->comp, sizeof(newkeys->comp)); } /* Index: openssh-9.3p2/mac.c =================================================================== --- openssh-9.3p2.orig/mac.c +++ openssh-9.3p2/mac.c @@ -284,11 +284,11 @@ mac_destroy(struct sshmac *mac) return; if (mac->key) { - memset(mac->key, 0, mac->key_len); + explicit_bzero(mac->key, mac->key_len); free(mac->key); } - memset(mac, 0, sizeof(*mac)); + explicit_bzero(mac, sizeof(*mac)); } /* XXX copied from ciphers_valid */ Index: openssh-9.3p2/monitor.c =================================================================== --- openssh-9.3p2.orig/monitor.c +++ openssh-9.3p2/monitor.c @@ -1789,8 +1789,12 @@ mm_answer_audit_end_command(struct ssh * void monitor_clear_keystate(struct ssh *ssh, struct monitor *pmonitor) { - ssh_clear_newkeys(ssh, MODE_IN); - ssh_clear_newkeys(ssh, MODE_OUT); + u_int mode; + + for (mode = 0; mode < MODE_MAX; mode++) { + ssh_clear_curkeys(ssh, mode); /* current keys */ + ssh_clear_newkeys(ssh, mode); /* next keys */ + } sshbuf_free(child_state); child_state = NULL; } Index: openssh-9.3p2/packet.c =================================================================== --- openssh-9.3p2.orig/packet.c +++ openssh-9.3p2/packet.c @@ -655,6 +655,7 @@ ssh_packet_close_internal(struct ssh *ss ssh->local_ipaddr = NULL; free(ssh->remote_ipaddr); ssh->remote_ipaddr = NULL; + explicit_bzero(ssh->state, sizeof(*ssh->state)); free(ssh->state); ssh->state = NULL; kex_free(ssh->kex); @@ -783,8 +784,10 @@ compress_buffer(struct ssh *ssh, struct case Z_OK: /* Append compressed data to output_buffer. */ if ((r = sshbuf_put(out, buf, sizeof(buf) - - ssh->state->compression_out_stream.avail_out)) != 0) + ssh->state->compression_out_stream.avail_out)) != 0) { + explicit_bzero(buf, sizeof(buf)); return r; + } break; case Z_STREAM_ERROR: default: @@ -819,8 +822,10 @@ uncompress_buffer(struct ssh *ssh, struc switch (status) { case Z_OK: if ((r = sshbuf_put(out, buf, sizeof(buf) - - ssh->state->compression_in_stream.avail_out)) != 0) + ssh->state->compression_in_stream.avail_out)) != 0) { + explicit_bzero(buf, sizeof(buf)); return r; + } break; case Z_BUF_ERROR: /* @@ -870,6 +875,17 @@ uncompress_buffer(struct ssh *ssh, struc #endif /* WITH_ZLIB */ void +ssh_clear_curkeys(struct ssh *ssh, int mode) +{ + struct session_state *state = ssh->state; + + if (state && state->newkeys[mode]) { + kex_free_newkeys(state->newkeys[mode]); + state->newkeys[mode] = NULL; + } +} + +void ssh_clear_newkeys(struct ssh *ssh, int mode) { if (ssh->kex && ssh->kex->newkeys[mode]) { @@ -1418,7 +1434,9 @@ ssh_packet_read_seqnr(struct ssh *ssh, u } /* Append it to the buffer. */ - if ((r = ssh_packet_process_incoming(ssh, buf, len)) != 0) + r = ssh_packet_process_incoming(ssh, buf, len); + explicit_bzero(buf, len); + if (r != 0) goto out; } out: @@ -2375,9 +2393,12 @@ ssh_packet_get_state(struct ssh *ssh, st (r = sshbuf_put_u32(m, state->p_read.packets)) != 0 || (r = sshbuf_put_u64(m, state->p_read.bytes)) != 0 || (r = sshbuf_put_stringb(m, state->input)) != 0 || - (r = sshbuf_put_stringb(m, state->output)) != 0) + (r = sshbuf_put_stringb(m, state->output)) != 0) { + sshbuf_obfuscate(m); return r; + } + sshbuf_obfuscate(m); return 0; } @@ -2496,6 +2517,8 @@ ssh_packet_set_state(struct ssh *ssh, st size_t ilen, olen; int r; + sshbuf_unobfuscate(m); + if ((r = kex_from_blob(m, &ssh->kex)) != 0 || (r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 || (r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 || @@ -2509,7 +2532,7 @@ ssh_packet_set_state(struct ssh *ssh, st (r = sshbuf_get_u64(m, &state->p_read.blocks)) != 0 || (r = sshbuf_get_u32(m, &state->p_read.packets)) != 0 || (r = sshbuf_get_u64(m, &state->p_read.bytes)) != 0) - return r; + goto out; /* * We set the time here so that in post-auth privsep child we * count from the completion of the authentication. @@ -2518,10 +2541,10 @@ ssh_packet_set_state(struct ssh *ssh, st /* XXX ssh_set_newkeys overrides p_read.packets? XXX */ if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0 || (r = ssh_set_newkeys(ssh, MODE_OUT)) != 0) - return r; + goto out; if ((r = ssh_packet_set_postauth(ssh)) != 0) - return r; + goto out; sshbuf_reset(state->input); sshbuf_reset(state->output); @@ -2529,12 +2552,19 @@ ssh_packet_set_state(struct ssh *ssh, st (r = sshbuf_get_string_direct(m, &output, &olen)) != 0 || (r = sshbuf_put(state->input, input, ilen)) != 0 || (r = sshbuf_put(state->output, output, olen)) != 0) - return r; + goto out; - if (sshbuf_len(m)) - return SSH_ERR_INVALID_FORMAT; + if (sshbuf_len(m)) { + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + + r = 0; +out: + if (r != 0) + sshbuf_obfuscate(m); debug3_f("done"); - return 0; + return r; } /* NEW API */ Index: openssh-9.3p2/packet.h =================================================================== --- openssh-9.3p2.orig/packet.h +++ openssh-9.3p2/packet.h @@ -103,6 +103,7 @@ void ssh_packet_close(struct ssh *); void ssh_packet_set_input_hook(struct ssh *, ssh_packet_hook_fn *, void *); void ssh_packet_clear_keys(struct ssh *); void ssh_packet_clear_keys_noaudit(struct ssh *); +void ssh_clear_curkeys(struct ssh *, int); void ssh_clear_newkeys(struct ssh *, int); int ssh_packet_is_rekeying(struct ssh *); Index: openssh-9.3p2/sshbuf.c =================================================================== --- openssh-9.3p2.orig/sshbuf.c +++ openssh-9.3p2/sshbuf.c @@ -309,6 +309,31 @@ sshbuf_mutable_ptr(const struct sshbuf * return buf->d + buf->off; } +/* Trivially obfuscate the buffer. This is used to make sensitive data + * (e.g. keystate) slightly less obvious if found lingering in kernel + * memory after being sent from the privsep child to its parent. + * + * Longer term we should consider using a one-time pad or a stream cipher + * here. */ +void +sshbuf_obfuscate(struct sshbuf *buf) +{ + size_t i; + + if (sshbuf_check_sanity(buf) != 0 || buf->readonly || buf->refcount > 1) + return; + + for (i = buf->off; i < buf->size; i++) { + buf->d [i] ^= 0xaa; + } +} + +void +sshbuf_unobfuscate(struct sshbuf *buf) +{ + sshbuf_obfuscate(buf); +} + int sshbuf_check_reserve(const struct sshbuf *buf, size_t len) { Index: openssh-9.3p2/sshbuf.h =================================================================== --- openssh-9.3p2.orig/sshbuf.h +++ openssh-9.3p2/sshbuf.h @@ -298,6 +298,9 @@ int sshbuf_write_file(const char *path, int sshbuf_read(int, struct sshbuf *, size_t, size_t *) __attribute__((__nonnull__ (2))); +void sshbuf_obfuscate(struct sshbuf *buf); +void sshbuf_unobfuscate(struct sshbuf *buf); + /* Macros for decoding/encoding integers */ #define PEEK_U64(p) \ (((u_int64_t)(((const u_char *)(p))[0]) << 56) | \ Index: openssh-9.3p2/sshd.c =================================================================== --- openssh-9.3p2.orig/sshd.c +++ openssh-9.3p2/sshd.c @@ -272,6 +272,19 @@ static void do_ssh2_kex(struct ssh *); static char *listener_proctitle; /* + * Clear some stack space. This is a bit naive, but hopefully helps mitigate + * information leaks due to registers and other data having been stored on + * the stack. Called after fork() and before exit(). + */ +static void +clobber_stack(void) +{ + char data [32768]; + + explicit_bzero(data, 32768); +} + +/* * Close all listening sockets */ static void @@ -430,6 +443,8 @@ destroy_sensitive_data(struct ssh *ssh, sensitive_data.host_certificates[i] = NULL; } } + + clobber_stack(); } /* Demote private to public keys for network child */ @@ -600,6 +615,8 @@ privsep_preauth(struct ssh *ssh) static void privsep_postauth(struct ssh *ssh, Authctxt *authctxt) { + clobber_stack(); + #ifdef DISABLE_FD_PASSING if (1) { #else @@ -2360,6 +2377,7 @@ main(int ac, char **av) if (use_privsep) { mm_send_keystate(ssh, pmonitor); ssh_packet_clear_keys(ssh); + clobber_stack(); exit(0); } @@ -2436,6 +2454,7 @@ main(int ac, char **av) if (use_privsep) mm_terminate(); + clobber_stack(); exit(0); } @@ -2596,8 +2615,10 @@ cleanup_exit(int i) /* cleanup_exit can be called at the very least from the privsep wrappers used for auditing. Make sure we don't recurse indefinitely. */ - if (in_cleanup) + if (in_cleanup) { + clobber_stack(); _exit(i); + } in_cleanup = 1; if (the_active_state != NULL && the_authctxt != NULL) { do_cleanup(the_active_state, the_authctxt); @@ -2623,5 +2644,7 @@ cleanup_exit(int i) (!use_privsep || mm_is_monitor())) audit_event(the_active_state, SSH_CONNECTION_ABANDON); #endif + + clobber_stack(); _exit(i); }