Bug 1488083 - segfaults when cleaning up session due to some error
Summary: segfaults when cleaning up session due to some error
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: openssh
Version: 7.4
Hardware: Unspecified
OS: Unspecified
Target Milestone: rc
: ---
Assignee: Jakub Jelen
QA Contact: Stefan Dordevic
Mirek Jahoda
Depends On:
Blocks: 1476743 1520852
TreeView+ depends on / blocked
Reported: 2017-09-04 09:42 UTC by Renaud Métrich
Modified: 2018-04-10 18:20 UTC (History)
7 users (show)

Fixed In Version: openssh-7.4p1-15.el7
Doc Type: Bug Fix
Doc Text:
*OpenSSH* servers without Privilege Separation no longer crash Prior to this update, a pointer had been dereferenced before its validity was checked. Consequently, *OpenSSH* servers with the "Privilege Separation" option turned off crashed during the session cleanup. With this update, pointers are checked properly, and *OpenSSH* servers no longer crash while running without "Privilege Separation" due the described bug. Note that disabling *OpenSSH* "Privilege Separation" is not recommended.
Clone Of:
: 1520852 (view as bug list)
Last Closed: 2018-04-10 18:19:11 UTC
Target Upstream Version:

Attachments (Terms of Use)

System ID Priority Status Summary Last Updated
OpenSSH Project 2773 None None None 2019-04-16 12:24:54 UTC
Red Hat Product Errata RHSA-2018:0980 None None None 2018-04-10 18:20:29 UTC

Description Renaud Métrich 2017-09-04 09:42:00 UTC
Description of problem:

When connection gets closed because of "Too many authentication failures", sshd core dumps when trying to log remote IP address in the audit log.

Version-Release number of selected component (if applicable):


How reproducible:

Don't know, didn't try

Additional info:

Program terminated with signal 11, Segmentation fault.
#0  0x0000561b9d18982c in ssh_remote_ipaddr (ssh=ssh@entry=0x561b9e5bbf20) at packet.c:513
513		const int sock = ssh->state->connection_in;

(gdb) bt
#0  0x0000561b9d18982c in ssh_remote_ipaddr (ssh=ssh@entry=0x561b9e5bbf20) at packet.c:513
#1  0x0000561b9d14663f in audit_event (event=event@entry=SSH_CONNECTION_ABANDON) at audit-linux.c:270
#2  0x0000561b9d145030 in cleanup_exit (i=i@entry=255) at sshd.c:2465
#3  0x0000561b9d18df89 in ssh_packet_disconnect (ssh=0x561b9e5bbf20, fmt=fmt@entry=0x561b9d1b88e3 "%s")
    at packet.c:2174
#4  0x0000561b9d18e8ed in packet_disconnect (fmt=fmt@entry=0x561b9d1b9c70 "Too many authentication failures")
    at opacket.c:324
#5  0x0000561b9d14e8c1 in auth_maxtries_exceeded (authctxt=authctxt@entry=0x561b9e5b9270) at auth.c:357
#6  0x0000561b9d15097e in userauth_finish (authctxt=authctxt@entry=0x561b9e5b9270, authenticated=0, 
    method=<optimized out>, method@entry=0x561b9d1b6e89 "keyboard-interactive", 
    submethod=submethod@entry=0x561b9d1b859d "pam") at auth2.c:393
#7  0x0000561b9d15713c in input_userauth_info_response (type=<optimized out>, seq=<optimized out>, 
    ctxt=0x561b9e5b9270) at auth2-chall.c:350
#8  0x0000561b9d192899 in ssh_dispatch_run (ssh=ssh@entry=0x561b9e5bbf20, mode=mode@entry=0, 
    done=done@entry=0x561b9e5b9270, ctxt=ctxt@entry=0x561b9e5b9270) at dispatch.c:119
#9  0x0000561b9d1928e9 in ssh_dispatch_run_fatal (ssh=0x561b9e5bbf20, mode=mode@entry=0, 
    done=done@entry=0x561b9e5b9270, ctxt=ctxt@entry=0x561b9e5b9270) at dispatch.c:140
#10 0x0000561b9d150099 in do_authentication2 (authctxt=authctxt@entry=0x561b9e5b9270) at auth2.c:175
#11 0x0000561b9d142227 in main (ac=<optimized out>, av=<optimized out>) at sshd.c:2191

Connection is getting closed because of "Too many authentication failures"

(gdb) print ssh->state
$2 = (struct session_state *) 0x0

Reason for the crash is ssh->state == NULL pointer, so cannot access "connection_in" field

2139 void
2140 ssh_packet_disconnect(struct ssh *ssh, const char *fmt,...)
2141 {
2172         /* Close the connection. */
2173         ssh_packet_close(ssh);
2174         cleanup_exit(255);
2175 }

ssh_packet_disconnect() calls ssh_packet_close(), then cleanup_exit().

Looking at ssh_packet_close(), we can see that ssh->state is set to NULL upon end of function.

 564 void
 565 ssh_packet_close(struct ssh *ssh)
 566 {
 619         free(ssh->state);
 620         ssh->state = NULL;
 621 }

Due to that, ssh_remote_ipaddr() called by audit_event() has no ssh->state anymore.

227 void
228 audit_event(ssh_audit_event_t event)
229 {
230         struct ssh *ssh = active_state; /* XXX */
268         case SSH_CONNECTION_ABANDON:
269         case SSH_INVALID_USER:
270                 linux_audit_user_logxxx(-1, audit_username(), NULL,
271                         ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN);

Comment 2 Jakub Jelen 2017-09-04 10:53:51 UTC
Thank you for a verbose report.
Yes, it looks like you found the problem. There was some code path that was caching the IP address so it is accessible even after it got closed, but dereferencing null pointer will prevent us from doing that. Something like the follwing patch should resolve the problem:

--- packet.c	2017-09-04 12:49:41.086968750 +0200
+++ packet.c.new	2017-09-04 12:49:35.665934589 +0200
@@ -510,11 +510,12 @@
 const char *
 ssh_remote_ipaddr(struct ssh *ssh)
-	const int sock = ssh->state->connection_in;
+	const int sock;
 	/* Check whether we have cached the ipaddr. */
 	if (ssh->remote_ipaddr == NULL) {
 		if (ssh_packet_connection_is_on_socket(ssh)) {
+			sock = ssh->state->connection_in;
 			ssh->remote_ipaddr = get_peer_ipaddr(sock);
 			ssh->remote_port = get_peer_port(sock);
 			ssh->local_ipaddr = get_local_ipaddr(sock);

I see the same issue in the upstream master, so I will fill a bug report. I believe this should be fix no later than with 7.5 update.

Comment 18 errata-xmlrpc 2018-04-10 18:19:11 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.


Note You need to log in before you can comment on or make changes to this bug.