Bug 3401 - Illegal hardware instruction
Summary: Illegal hardware instruction
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: sshd (show other bugs)
Version: 8.9p1
Hardware: All Linux
: P5 security
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks: V_9_0
  Show dependency treegraph
 
Reported: 2022-03-10 15:54 AEDT by Carlos Ramirez
Modified: 2022-04-08 12:12 AEST (History)
1 user (show)

See Also:


Attachments
PoC configuration file for ssh. Usage: "sshd -t -f poc.conf" (61 bytes, text/plain)
2022-03-10 15:54 AEDT, Carlos Ramirez
no flags Details
Check for scaling underflow in scan_scaled. (505 bytes, patch)
2022-03-10 17:36 AEDT, Darren Tucker
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Carlos Ramirez 2022-03-10 15:54:47 AEDT
Created attachment 3578 [details]
PoC configuration file for ssh. Usage: "sshd -t -f poc.conf"

* LOW RISK/Further testing is required to understand the issue.

An illegal hardware instruction that crashes sshd occurs under some circumstances when input is provided through its configuration file. The problem resides in the "RekeyLimit" configuration option, when maximum amount of time that may pass before the session key is renegotiated is provided.

The biggest risk is Availability of sshd, particularly for cases where mass configuration of servers is done through automated pipelines that dynamically generate the configuration files and might generate a input value that that triggers the issue.

=========================
PoC Command output:
=========================

valgrind sshd -t -f poc.conf

Valgrind output: 
...
...
==3348611== Process terminating with default action of signal 4 (SIGILL)
==3348611==  Illegal opcode at address 0x1857A5
==3348611==    at 0x1857A5: UnknownInlinedFun (fmt_scaled.c:122)
==3348611==    by 0x1857A5: process_server_config_line_depth (servconf.c:1682)
==3348611==    by 0x185EA6: parse_server_config_depth (servconf.c:2687)
==3348611==    by 0x186F39: parse_server_config (servconf.c:2704)
==3348611==    by 0x1576CC: main (sshd.c:1742)
...
...
zsh: illegal hardware instruction

=========================

See attached file poc.conf

---
Carlos Andres Ramirez
Comment 1 Darren Tucker 2022-03-10 16:45:35 AEDT
The problematic line is:

RekeyLimit -.060000000000000000E.0

Smells like either integer overflow trapped by -ftrapv or divide-by-zero somewhere.

It's more easily reproduced with ssh, which takes the same keyword:

$ cat poc.conf 
RekeyLimit -.060000000000000000E.0

$ gdb --args ./ssh -F poc.conf localhost
Reading symbols from ./ssh...
(gdb) run
[...]
Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:49
49	  return ret;
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:49
#1  0x00007ffff7a9c8a4 in __GI_abort () at abort.c:79
#2  0x0000555555602fc4 in __mulvdi3 ()
#3  0x00005555555fc5ea in scan_scaled (
    scaled=scaled@entry=0x555555662ba0 "-.06", '0' <repeats 16 times>, "E.0", 
    result=result@entry=0x7fffffffa930)
    at ../../../openbsd-compat/fmt_scaled.c:198
#4  0x000055555556de97 in process_config_line_depth (
    options=options@entry=0x555555652360 <options>, 
    pw=pw@entry=0x55555565d550, host=host@entry=0x55555565de10 "localhost", 
    original_host=original_host@entry=0x555555661970 "localhost", 
    line=<optimized out>, filename=filename@entry=0x555555656350 "poc.conf", 
    linenum=1, activep=0x7fffffffb424, flags=2, 
    want_final_pass=0x7fffffffc504, depth=0) at ../../readconf.c:1175
#5  0x000055555556e570 in read_config_file_depth (
    filename=0x555555656350 "poc.conf", pw=0x55555565d550, 
    host=0x55555565de10 "localhost", original_host=0x555555661970 "localhost", 
    options=0x555555652360 <options>, flags=2, activep=0x7fffffffb424, 
    want_final_pass=0x7fffffffc504, depth=0) at ../../readconf.c:2285
#6  0x000055555556e79d in read_config_file (filename=<optimized out>, 
    pw=<optimized out>, host=<optimized out>, original_host=<optimized out>, 
    options=<optimized out>, flags=<optimized out>, 
    want_final_pass=0x7fffffffc504) at ../../readconf.c:2238
--Type <RET> for more, q to quit, c to continue without paging--
#7  0x0000555555564eb7 in process_config_files (
    host_name=0x555555661970 "localhost", pw=0x55555565d550, final_pass=0, 
    want_final_pass=0x7fffffffc504) at ../../ssh.c:555
#8  0x00005555555603cc in main (ac=<optimized out>, av=<optimized out>)
    at ../../ssh.c:1146
(gdb) frame 3
#3  0x00005555555fc5ea in scan_scaled (
    scaled=scaled@entry=0x555555662ba0 "-.06", '0' <repeats 16 times>, "E.0", 
    result=result@entry=0x7fffffffa930)
    at ../../../openbsd-compat/fmt_scaled.c:198
198				fpart *= scale_fact;
(gdb) print fpart
$1 = -60000000000000000
(gdb) print scale_fact
$2 = 1152921504606846976
(gdb) 

yep, a trapped integer overflow.  In the case where it's built w/out -ftrapv you'll you'll get an unexpected and possibly useless value for RekeyLimit, but otherwise I don't think it'll have any effect.
Comment 2 Darren Tucker 2022-03-10 17:36:00 AEDT
Created attachment 3579 [details]
Check for scaling underflow in scan_scaled.

This should fix it.

$ ./ssh -F poc.conf localhost
poc.conf line 1: RekeyLimit too small
poc.conf: terminating, 1 bad configuration options
Comment 3 Carlos Ramirez 2022-03-10 18:00:10 AEDT
Yes, I just had the time to check, it is an integer underflow.

A script in the automatic config generation was subtracting bigger time values from a smaller values and then generating text configuration files - I had to manually test several systems and identify the issue and suggest/provide a fix.

For the sake of case tracking, do you think this can be assigned a CVE ID to this issue?
Comment 4 Darren Tucker 2022-03-10 19:07:51 AEDT
(In reply to Carlos Ramirez from comment #3)
> For the sake of case tracking, do you think this can be assigned a
> CVE ID to this issue?

No, I don't think so.  It's at worst a self-DoS requiring root access on the server side, and root has an infinite number of ways it can break sshd's config.
Comment 5 Carlos Ramirez 2022-03-10 19:41:41 AEDT
Understood, scope is very limited and comes down to automated deployment systems not making any mistakes when generating the configuration - so this falls into a QA/bug category.

Thank you Darren for the promptly action and patch!

---
Carlos Andres Ramirez
Comment 6 Darren Tucker 2022-03-10 20:51:02 AEDT
(In reply to Carlos Ramirez from comment #5)
> Understood, scope is very limited and comes down to automated
> deployment systems not making any mistakes when generating the
> configuration

It's also triggered in config-test mode.  Any system that deploys new configs should be using this to test that they're valid:

$ `pwd`/sshd -t -f poc.conf
Aborted
$ echo $?
134

so to be affected you'd have to implement an automated config generation and deployment system that performs no validation.
Comment 7 Darren Tucker 2022-03-11 19:00:57 AEDT
This has been committed (both to master and V_8_9 branch) and will be in the next release.  Thanks for the report.
Comment 8 Damien Miller 2022-04-08 12:12:55 AEST
closing bug resolved during openssh-9.0 release cycle