Accepting request 1034974 from home:hpjansson:openssh-tw

- Update openssh-8.1p1-audit.patch: Merge fix for race condition
  (bsc#1115550, bsc#1174162).
- Add openssh-do-not-send-empty-message.patch, which prevents
  superfluous newlines with empty MOTD files (bsc#1192439).

OBS-URL: https://build.opensuse.org/request/show/1034974
OBS-URL: https://build.opensuse.org/package/show/network/openssh?expand=0&rev=242
This commit is contained in:
Marcus Meissner 2022-11-15 15:28:59 +00:00 committed by Git OBS Bridge
parent cb5c9c99b3
commit 4038ff6c0f
4 changed files with 187 additions and 21 deletions

View File

@ -1550,7 +1550,7 @@ Index: openssh-8.9p1/monitor_wrap.c
sshbuf_free(m);
}
#endif /* SSH_AUDIT_EVENTS */
@@ -1074,3 +1114,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc
@@ -1074,3 +1114,130 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc
}
#endif /* GSSAPI */
@ -1633,6 +1633,53 @@ Index: openssh-8.9p1/monitor_wrap.c
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, m);
+ sshbuf_free(m);
+}
+
+int mm_forward_audit_messages(int fdin)
+{
+ u_char buf[4];
+ u_int blen, msg_len;
+ struct sshbuf *m;
+ int ret = 0;
+
+ debug3("%s: entering", __func__);
+ m = sshbuf_new();
+ do {
+ int r;
+
+ blen = atomicio(read, fdin, buf, sizeof(buf));
+ if (blen == 0) /* closed pipe */
+ break;
+ if (blen != sizeof(buf)) {
+ error("%s: Failed to read the buffer from child", __func__);
+ ret = -1;
+ break;
+ }
+
+ msg_len = get_u32(buf);
+ if (msg_len > 256 * 1024)
+ fatal("%s: read: bad msg_len %d", __func__, msg_len);
+ sshbuf_reset(m);
+ if ((r = sshbuf_reserve(m, msg_len, NULL)) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ if (atomicio(read, fdin, sshbuf_mutable_ptr(m), msg_len) != msg_len) {
+ error("%s: Failed to read the the buffer conent from the child", __func__);
+ ret = -1;
+ break;
+ }
+ if (atomicio(vwrite, pmonitor->m_recvfd, buf, blen) != blen ||
+ atomicio(vwrite, pmonitor->m_recvfd, sshbuf_mutable_ptr(m), msg_len) != msg_len) {
+ error("%s: Failed to write the messag to the monitor", __func__);
+ ret = -1;
+ break;
+ }
+ } while (1);
+ sshbuf_free(m);
+ return ret;
+}
+void mm_set_monitor_pipe(int fd)
+{
+ pmonitor->m_recvfd = fd;
+}
+#endif /* SSH_AUDIT_EVENTS */
Index: openssh-8.9p1/monitor_wrap.h
===================================================================
@ -1649,7 +1696,7 @@ Index: openssh-8.9p1/monitor_wrap.h
const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **);
#ifdef GSSAPI
@@ -83,7 +85,12 @@ void mm_sshpam_free_ctx(void *);
@@ -83,7 +85,14 @@ void mm_sshpam_free_ctx(void *);
#ifdef SSH_AUDIT_EVENTS
#include "audit.h"
void mm_audit_event(struct ssh *, ssh_audit_event_t);
@ -1660,6 +1707,8 @@ Index: openssh-8.9p1/monitor_wrap.h
+void mm_audit_kex_body(struct ssh *, int, char *, char *, char *, char *, pid_t, uid_t);
+void mm_audit_session_key_free_body(struct ssh *, int, pid_t, uid_t);
+void mm_audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t);
+int mm_forward_audit_messages(int);
+void mm_set_monitor_pipe(int);
#endif
struct Session;
@ -1689,7 +1738,12 @@ Index: openssh-8.9p1/packet.c
/*
* Returns the IP-address of the remote host as a string. The returned
* string must not be freed.
@@ -583,22 +591,19 @@ ssh_packet_close_internal(struct ssh *ss
@@ -579,26 +587,23 @@ ssh_packet_rdomain_in(struct ssh *ssh)
/* Closes the connection and clears and frees internal data structures. */
static void
-ssh_packet_close_internal(struct ssh *ssh, int do_close)
+ssh_packet_close_internal(struct ssh *ssh, int do_close, int do_audit)
{
struct session_state *state = ssh->state;
u_int mode;
@ -1721,7 +1775,7 @@ Index: openssh-8.9p1/packet.c
#endif /* WITH_ZLIB */
cipher_free(state->send_context);
cipher_free(state->receive_context);
+ if (had_keys && state->server_side) {
+ if (do_audit && had_keys && state->server_side) {
+ /* Assuming this is called only from privsep child */
+ audit_session_key_free(ssh, MODE_MAX);
+ }
@ -1736,7 +1790,29 @@ Index: openssh-8.9p1/packet.c
free(ssh->local_ipaddr);
ssh->local_ipaddr = NULL;
free(ssh->remote_ipaddr);
@@ -892,6 +907,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod
@@ -650,13 +665,19 @@ ssh_packet_close_internal(struct ssh *ss
void
ssh_packet_close(struct ssh *ssh)
{
- ssh_packet_close_internal(ssh, 1);
+ ssh_packet_close_internal(ssh, 1, 1);
}
void
ssh_packet_clear_keys(struct ssh *ssh)
{
- ssh_packet_close_internal(ssh, 0);
+ ssh_packet_close_internal(ssh, 0, 1);
+}
+
+void
+ssh_packet_clear_keys_noaudit(struct ssh *ssh)
+{
+ ssh_packet_close_internal(ssh, 0, 0);
}
/* Sets remote side protocol flags. */
@@ -892,6 +913,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod
(unsigned long long)state->p_send.bytes,
(unsigned long long)state->p_send.blocks);
kex_free_newkeys(state->newkeys[mode]);
@ -1744,7 +1820,7 @@ Index: openssh-8.9p1/packet.c
state->newkeys[mode] = NULL;
}
/* note that both bytes and the seqnr are not reset */
@@ -2183,6 +2199,73 @@ ssh_packet_get_output(struct ssh *ssh)
@@ -2183,6 +2205,73 @@ ssh_packet_get_output(struct ssh *ssh)
return (void *)ssh->state->output;
}
@ -1822,7 +1898,15 @@ Index: openssh-8.9p1/packet.h
===================================================================
--- openssh-8.9p1.orig/packet.h
+++ openssh-8.9p1/packet.h
@@ -220,4 +220,5 @@ const u_char *sshpkt_ptr(struct ssh *, s
@@ -102,6 +102,7 @@ int ssh_packet_get_connection_out(s
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_newkeys(struct ssh *, int);
int ssh_packet_is_rekeying(struct ssh *);
@@ -220,4 +221,5 @@ const u_char *sshpkt_ptr(struct ssh *, s
# undef EC_POINT
#endif
@ -1841,7 +1925,18 @@ Index: openssh-8.9p1/session.c
extern struct sshbuf *loginmsg;
extern struct sshauthopt *auth_opts;
extern char *tun_fwd_ifnames; /* serverloop.c */
@@ -642,6 +642,14 @@ do_exec_pty(struct ssh *ssh, Session *s,
@@ -157,6 +157,10 @@ static Session *sessions = NULL;
login_cap_t *lc;
#endif
+#ifdef SSH_AUDIT_EVENTS
+int paudit[2];
+#endif
+
static int is_child = 0;
static int in_chroot = 0;
@@ -642,6 +646,14 @@ do_exec_pty(struct ssh *ssh, Session *s,
/* Parent. Close the slave side of the pseudo tty. */
close(ttyfd);
@ -1856,7 +1951,7 @@ Index: openssh-8.9p1/session.c
/* Enter interactive session. */
s->ptymaster = ptymaster;
ssh_packet_set_interactive(ssh, 1,
@@ -706,15 +714,19 @@ do_exec(struct ssh *ssh, Session *s, con
@@ -706,15 +718,21 @@ do_exec(struct ssh *ssh, Session *s, con
s->self);
#ifdef SSH_AUDIT_EVENTS
@ -1875,23 +1970,66 @@ Index: openssh-8.9p1/session.c
}
+ if (s->command != NULL && s->ptyfd == -1)
+ s->command_handle = PRIVSEP(audit_run_command(ssh, s->command));
+ if (pipe(paudit) < 0)
+ fatal("pipe: %s", strerror(errno));
#endif
if (s->ttyfd != -1)
ret = do_exec_pty(ssh, s, command);
@@ -1533,8 +1545,11 @@ do_child(struct ssh *ssh, Session *s, co
@@ -730,6 +748,20 @@ do_exec(struct ssh *ssh, Session *s, con
*/
sshbuf_reset(loginmsg);
+#ifdef SSH_AUDIT_EVENTS
+ close(paudit[1]);
+ if (use_privsep && ret == 0) {
+ /*
+ * Read the audit messages from forked child and send them
+ * back to monitor. We don't want to communicate directly,
+ * because the messages might get mixed up.
+ * Continue after the pipe gets closed (all messages sent).
+ */
+ ret = mm_forward_audit_messages(paudit[0]);
+ }
+ close(paudit[0]);
+#endif /* SSH_AUDIT_EVENTS */
+
return ret;
}
@@ -1530,11 +1562,30 @@ do_child(struct ssh *ssh, Session *s, co
int env_size;
int r = 0;
+#ifdef SSH_AUDIT_EVENTS
+ int pparent = paudit[1];
+ close(paudit[0]);
+ /* Hack the monitor pipe to avoid race condition with parent */
+ if (use_privsep)
+ mm_set_monitor_pipe(pparent);
+#endif
+
sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
/* remove hostkey from the child's memory */
- destroy_sensitive_data();
+ destroy_sensitive_data(ssh, 1);
ssh_packet_clear_keys(ssh);
+ /* Don't audit this - both us and the parent would be talking to the
+ monitor over a single socket, with no synchronization. */
- ssh_packet_clear_keys(ssh);
+ destroy_sensitive_data(ssh, use_privsep);
+ ssh_packet_clear_keys_noaudit(ssh);
+ /*
+ * We can audit this, because we hacked the pipe to direct the
+ * messages over postauth child. But this message requires an answer
+ * which we can't do using a one-way pipe.
+ */
+ packet_destroy_all(ssh, 0, 1);
+
+#ifdef SSH_AUDIT_EVENTS
+ /* Notify parent that we are done */
+ close(pparent);
+#endif
/* Force a password change */
if (s->authctxt->force_pwchange) {
@@ -1743,6 +1758,9 @@ session_unused(int id)
@@ -1743,6 +1794,9 @@ session_unused(int id)
sessions[id].ttyfd = -1;
sessions[id].ptymaster = -1;
sessions[id].x11_chanids = NULL;
@ -1901,7 +2039,7 @@ Index: openssh-8.9p1/session.c
sessions[id].next_unused = sessions_first_unused;
sessions_first_unused = id;
}
@@ -1822,6 +1840,19 @@ session_open(Authctxt *authctxt, int cha
@@ -1822,6 +1876,19 @@ session_open(Authctxt *authctxt, int cha
}
Session *
@ -1921,7 +2059,7 @@ Index: openssh-8.9p1/session.c
session_by_tty(char *tty)
{
int i;
@@ -2429,6 +2460,32 @@ session_exit_message(struct ssh *ssh, Se
@@ -2429,6 +2496,32 @@ session_exit_message(struct ssh *ssh, Se
chan_write_failed(ssh, c);
}
@ -1954,7 +2092,7 @@ Index: openssh-8.9p1/session.c
void
session_close(struct ssh *ssh, Session *s)
{
@@ -2470,6 +2527,10 @@ session_close(struct ssh *ssh, Session *
@@ -2470,6 +2563,10 @@ session_close(struct ssh *ssh, Session *
if (s->ttyfd != -1)
session_pty_cleanup(s);
@ -1965,7 +2103,7 @@ Index: openssh-8.9p1/session.c
free(s->term);
free(s->display);
free(s->x11_chanids);
@@ -2544,14 +2605,14 @@ session_close_by_channel(struct ssh *ssh
@@ -2544,14 +2641,14 @@ session_close_by_channel(struct ssh *ssh
}
void
@ -1982,7 +2120,7 @@ Index: openssh-8.9p1/session.c
else
session_close(ssh, s);
}
@@ -2677,6 +2738,15 @@ do_authenticated2(struct ssh *ssh, Authc
@@ -2677,6 +2774,15 @@ do_authenticated2(struct ssh *ssh, Authc
server_loop2(ssh, authctxt);
}
@ -1998,7 +2136,7 @@ Index: openssh-8.9p1/session.c
void
do_cleanup(struct ssh *ssh, Authctxt *authctxt)
{
@@ -2740,7 +2810,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au
@@ -2740,7 +2846,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au
* or if running in monitor.
*/
if (!use_privsep || mm_is_monitor())

View File

@ -0,0 +1,19 @@
--- openssh-8.4p1.orig/auth-pam.c 2020-09-27 09:25:01.000000000 +0200
+++ openssh-8.4p1/auth-pam.c 2022-03-04 13:02:23.447712697 +0100
@@ -638,10 +638,12 @@
switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:
- if ((r = sshbuf_putf(loginmsg, "%s\n",
- PAM_MSG_MEMBER(msg, i, msg))) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ if (strlen(PAM_MSG_MEMBER(msg, i, msg)) != 0) {
+ if ((r = sshbuf_putf(loginmsg, "%s\n",
+ PAM_MSG_MEMBER(msg, i, msg))) != 0)
+ fatal("%s: buffer error: %s",
+ __func__, ssh_err(r));
+ }
reply[i].resp_retcode = PAM_SUCCESS;
break;
default:

View File

@ -1,3 +1,11 @@
-------------------------------------------------------------------
Thu Nov 10 02:18:08 UTC 2022 - Hans Petter Jansson <hpj@suse.com>
- Update openssh-8.1p1-audit.patch: Merge fix for race condition
(bsc#1115550, bsc#1174162).
- Add openssh-do-not-send-empty-message.patch, which prevents
superfluous newlines with empty MOTD files (bsc#1192439).
-------------------------------------------------------------------
Mon Aug 8 07:36:55 UTC 2022 - Thorsten Kukuk <kukuk@suse.com>

View File

@ -109,6 +109,7 @@ Patch45: openssh-8.4p1-ssh_config_d.patch
Patch46: openssh-whitelist-syscalls.patch
Patch47: openssh-8.4p1-vendordir.patch
Patch48: openssh-8.4p1-pam_motd.patch
Patch49: openssh-do-not-send-empty-message.patch
BuildRequires: audit-devel
BuildRequires: automake
BuildRequires: groff