Denial of service in Gerbv (CVE-2023-4508)

Last updated:


Summary

A user able to control file input to Gerbv, between versions 2.4.0 and 2.10.0, can cause a crash and cause denial-of-service with a specially crafted Gerber RS-274X file.

Root cause analysis

The Gerber RS-274X format defines the IF command (INCLUDE FILE, for referencing an external file) in its User's Guide (page 28). A valid line using this command respects the format below:

%IF<filename>.<extension>*%

The implementation of this functionality leverages two utilities: - A gerb_file_t structure wrapping up details about an opened file, such as the file descriptor, filename, and data to be read; and - A gerb_fopen function (from gerb_file.c) that takes a filename and returns a (partially-initialized) gerb_fopen structure;

The relevant execution flow in the context of this issue is as follows: 1. A gerbv_open_image function (from gerbv.c) is initially called in main.c through a proxy function called main_open_project_from_filename. 2. The gerbv_open_image internally calls gerb_fopen and stores the filename as a structural member in fd->filename = g_strdup(filename). 3. In a call to gerber_is_rs274x_p, the file is checked to respect the RS-274X format. 4. If it respects the format, parse_gerb is called. 5. parse_gerb calls gerber_parse_file_segment. 6. If any command having a % is detected, parse_rs274x is called. 7. If the command is detected to be IF, then the file is read with gerb_fopen. 8. gerber_parse_file_segment is called again, this time having as argument a filename stored inside the initially-read file.

The issue resides in the fact that, compared to the second step, the eighth one does not set the filename. When the latter is accessed in further processing, an invalid address is dereferenced, which results in a crash of the program.

A code path achieving this is when the included files contain an invalid M-code (for example, M09*). Usually, despite the invalid code, the execution should continue without processing the erroneous information, but Gerbv executes the following in its parse_M_code:

gerbv_stats_printf(stats->error_list, GERBV_MESSAGE_ERROR, -1,
        _("Encountered unknown M%02d code at line %ld in file \"%s\""),
        op_int, *line_num_p, fd->filename);

As it can be observed, the fd->filename is accessed in a logging call, so the execution will crash instead of raising a warning and continuing. This will not happen if the random value found on heap and implicitly assigned to fd->filename is NULL. Most compilers have a check against this scenario, and will only print (null).

CWEs

Affected components and releases

The functionality of processing IF commands was introduced in a5b8484, which corresponds to v2.4.0.

Attack vector

An attacker must control the content of the RS-274X file processed by Gerbv.

Impact

Gerbv can be crashed when processing files.

CVSS v3.1 vector

Steps to reproduce

For reproducing this, Cisco's parse_aperture_strtok.1.poc from CVE-2021-40401 was used as the file provided as an input parameter. The content of parse_aperture_strtok.2.poc was replaced with M09*.

As the issue depends on the random value of the unitialized fd->filename, it was reproduced by launching gdb, setting a breakpoint on gerb_fopen, and setting fd->filename to the value 0x0101010101. Gerbv will generate a crash as follows:

$ gdb ./gerbv
[...]
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x0000fffff7376590 in ?? () from /lib/aarch64-linux-gnu/libc.so.6
(gdb) bt
#0  0x0000fffff7376590 in  () at /lib/aarch64-linux-gnu/libc.so.6
#1  0x0000fffff734b848 in  () at /lib/aarch64-linux-gnu/libc.so.6
#2  0x0000fffff735cd78 in  () at /lib/aarch64-linux-gnu/libc.so.6
#3  0x0000fffff73cfa3c in __vasprintf_chk () at /lib/aarch64-linux-gnu/libc.so.6
#4  0x0000fffff7648064 in g_vasprintf () at /usr/lib/aarch64-linux-gnu/libglib-2.0.so.0
#5  0x0000fffff761da88 in g_strdup_vprintf () at /usr/lib/aarch64-linux-gnu/libglib-2.0.so.0
#6  0x0000fffff7fa3d04 in gerbv_stats_printf (list=0xaaaaaab2ab20, type=GERBV_MESSAGE_ERROR, layer=-1, text=0xfffff7fb5830 "Encountered unknown M%02d code at line %ld in file \"%s\"") at gerb_stats.c:242
#7  0x0000fffff7fa7088 in parse_M_code (fd=0xaaaaaab2ced0, image=0xaaaaaab16fc0, line_num_p=0xffffffffe0f0) at gerber.c:1183
#8  0x0000fffff7fa487c in gerber_parse_file_segment
    (levelOfRecursion=2, image=0xaaaaaab16fc0, state=0xaaaaaab16f60, curr_net=0xaaaaaab2af60, stats=0xaaaaaab2aa70, fd=0xaaaaaab2ced0, directoryPath=0xaaaaaab14a60 "/home/gerbv/triggers")
    at gerber.c:172
#9  0x0000fffff7fa7f40 in parse_rs274x
    (levelOfRecursion=1, fd=0xaaaaaab149a0, image=0xaaaaaab16fc0, state=0xaaaaaab16f60, curr_net=0xaaaaaab2af60, stats=0xaaaaaab2aa70, directoryPath=0xaaaaaab14a60 "/home/gerbv/triggers", line_num_p=0xffffffffe350) at gerber.c:1459
#10 0x0000fffff7fa4bec in gerber_parse_file_segment
    (levelOfRecursion=1, image=0xaaaaaab16fc0, state=0xaaaaaab16f60, curr_net=0xaaaaaab2af60, stats=0xaaaaaab2aa70, fd=0xaaaaaab149a0, directoryPath=0xaaaaaab14a60 "/home/gerbv/triggers")
    at gerber.c:245
#11 0x0000fffff7fa60a8 in parse_gerb (fd=0xaaaaaab149a0, directoryPath=0xaaaaaab14a60 "/home/gerbv/triggers") at gerber.c:770
#12 0x0000fffff7facca0 in gerbv_open_image
    (gerbvProject=0xaaaaaab14940, filename=0xffffffffed6e "/home/gerbv/triggers/CVE-2021-40401.1.poc", idx=0, reload=0, fattr=0x0, n_fattr=0, forceLoadFile=1) at gerbv.c:527
#13 0x0000fffff7fabf44 in gerbv_open_layer_from_filename_with_color
    (gerbvProject=0xaaaaaab14940, filename=0xffffffffed6e "/home/gerbv/triggers/CVE-2021-40401.1.poc", red=29555, green=29555, blue=57054, alpha=45489) at gerbv.c:249
#14 0x0000aaaaaaacb334 in main (argc=6, argv=0xffffffffe8e8) at main.c:937

Patch

Recommended to the maintainers

The filename can be attached to the gerb_file_t structure in gerb_fopen to avoid invalid dereferencing.

Applied by the maintainers

The vulnerability was patched in the commit dfb5aa by moving the filename allocation and deallocation into the gerb_fopen and gerb_fclose functions.

The patch was made available to the users in the 2.10.0 release.