Closed CiscoTalos closed 2 years ago
Any updates to this issue? Out of bounds issues (56 and 82) have proposed fixes
Does this issue have any updates regarding fix?
Please advise if there is a fix for this issue. The issue is beyond 90 days and subject to public disclosure on our end.
Should this be disclosed along with #80 without a fix?
To date, this issue is beyond 90 days and subject to public disclosure. If there are no updates to this issue, we will publish along with #80 in the first week of March
@CiscoTalos please do a public disclosure, users should be warned
Proposed fix in pull request #124
Pull request #124 merged as caa6560d5d683f827c672fd5e380f89a8ef632b6 and will be included in the upcoming release
TALOS-2021-1413
CVE-2021-40400
Gerbv RS-274X aperture macro outline primitive out-of-bounds read vulnerability
Summary
An out-of-bounds read vulnerability exists in the RS-274X aperture macro outline primitive functionality of Gerbv 2.7.0 and dev (commit b5f1eacd) and the forked version of Gerbv (commit d7f42a9a). A specially-crafted gerber file can lead to information disclosure. An attacker can provide a malicious file to trigger this vulnerability.
Tested Versions
Gerbv 2.7.0
Gerbv dev (commit b5f1eacd)
Gerbv forked dev (commit d7f42a9a)
Product URLs
https://sourceforge.net/projects/gerbv/
CVSSv3 Score
9.3 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:H
CWE
CWE-119 - Improper Restriction of Operations within the Bounds of a Memory Buffer
Details
Gerbv is an open-source software that allows to view RS-274X Gerber files, Excellon drill files and pick-n-place files. These file formats are used in industry to describe the layers of a printed circuit board and are a core part of the manufacturing process.
Some PCB (printed circuit board) manufacturers use software like Gerbv in their web interfaces as a tool to convert Gerber (or other supported) files into images. Users can upload gerber files to the manufacturer website, which are converted to an image to be displayed in the browser, so that users can verify that what has been uploaded matches their expectations. Gerbv can do such conversions using the
-x
switch (export). Moreover, gerbv can be compiled and used as a shared library. For these reasons, we consider this software as reachable via network without user interaction or privilege requirements.Gerbv uses the function
gerbv_open_image
to open files. In this advisory we're interested in the RS-274X file-type.A file is considered of type "RS-274X" if the function
gerber_is_rs274x_p
[1] returns true. When true, theparse_gerb
is called [2] to parse the input file. Let's first look at the requirements that we need to satisfy to have an input file be recognized as an RS-274X file:For an input to be considered an RS-274X file, the file must first of all contain only printing characters [3]. The other requirements can be gathered by the conditional expression at [4]. An example of a minimal RS-274X file is the following:
Even though not important for the purposes of the vulnerability itself, note that the checks use
g_strstr_len
, so all those fields can be found anywhere in the file. For example, this file is also recognized as an RS-274X file, even though it will fail later checks in the execution flow:After an RS-274X file has been recognized,
parse_gerb
is called, which in turn callsgerber_parse_file_segment
:If our file starts with "%", we end up calling
parse_rs274x
:For this advisory, we're interested in the
AM
andAD
commands. For details on the Gerber format see the specification from Ucamco.In summary,
AM
defines a "macro aperture template", which is, in other terms, a parametrized shape. It is a flexible way to define arbitrary shapes by building on top of simpler shapes (primitives). It allows to perform arithmetic operations and define variables. After a template has been defined, theAD
command is used to instantiate such template and optionally passing some parameters to customize the shape.From the specification, this is the syntax of the
AM
command:While this is the syntax for the
AD
command:For this advisory, we're interested in the "Outline" primitive (code
4
). From the specification:The outline primitive should contain the following fields:
Also the specification states that "The maximum number of vertices is 5000", which is controlled by the modified number 2. So, depending on the number of vertices, the length of this primitive will change accordingly.
In the
parse_rs274x
function, when anAM
command is found, the functionparse_aperture_macro
is called [5]. Let's see how this outline primitive is handled there:As we can see this function implements a set of opcodes for a virtual machine that is used to perform arithmetic operations, handle variable definitions and references via a virtual stack, and primitives.
Let's take an outline primitive definition as example:
As discussed before,
%AM
will land us in theparse_aperture_macro
function, andX0
is the name for the macro. The macro parsing starts with4
[7]: this is the primitive number, which is read as a decimal number until a,
is found [8]. After that, each field separated by,
is read as adouble
and added to the stack viaPUSH
[9]. These form the arguments to the primitive. When*
is found [10], the primitive instruction is added, and with%
the macro is returned.For reference, these are the prototypes for the macro and the program instructions:
Back to
parse_rs274x
, when anAD
command is found, the functionparse_aperture_definition
is called [6], which in turn callssimplify_aperture_macro
when theAD
command is using a template.For this advisory, all the
AD
commands has to do is utilize the macro that we just created, without special parameters. Let's consider the following aperture definition:For
AD
to use the template, it has to execute the template in the virtual machine. To this end, a virtual stack is allocated at [12] to handle parameters. The size of this stack depends onnuf_push
, which is incremented at [9] every time aGERBV_OPCODE_PUSH
instruction is added to the program.In the case of the sample macro previously discussed, our program will contain a serie of
GERBV_OPCODE_PUSH
instructions (pushing the numbers0,3,1,1,1
to the stack, at [13]) and aGERBV_OPCODE_PRIM
instruction for primitive 4 (outline), executed at [14].At [15] the number of vertices is taken from the second field in the stack (as per specification) and the number of parameters for the primitive is calculated. At [16] the code makes sure that
nuf_parameters
is not bigger thanAPERTURE_PARAMETERS_MAX
(102), otherwisenuf_parameters
gets limited toAPERTURE_PARAMETERS_MAX
[17]. Finally at [18] the parameters are copied from the stack into the newly allocatedsam
structure.The problem in this whole logic is that the stack buffer (
s->stack
) created at [12] has a size that depends onnuf_push
, while thememcpy
happening at [18] has a size that depends onnuf_parameters
. In the sample macro, the value ofnuf_parameters
is3
, however an attacker could use any arbitrary number, which is taken verbatim at [15] by readings->stack[1]
and used to calculatenuf_parameters
. At [17] the value ofnuf_parameters
is restricted to a maximum of 102, meaning that an attacker can set an arbitrarynuf_parameters
value from 0 to 102, causing thememcpy
at [18] to range from 0 to 816 (i.e.102 * sizeof(double)
).If
nuf_push
is smaller thannuf_parameters
, thememcpy
will cause an out-of-bounds read on thes->stack
buffer, which will lead to storing data of the nearby heap chunks intosam->parameter
. Sincesam->parameter
is used to draw the shape for the macro being evaluated, this will result in the final drawing to have a different shape, coordinate points, and rotation, depending on the values stored in the nearby heap chunks. Since an attacker might be able to read the rendered image at the end of the parsing (e.g. if the service using Gerbv is converting a.gbr
file into a.png
and returning it to the user), it would be possible to extract heap metadata or contents by reading the resulting rendered image. The quality of the information depends on thedpi
chosen for the operation, however with careful heap manipulation, in the worst case this could result in an information leak of the process' memory.Crash Information
Credit
Discovered by Claudio Bozzato of Cisco Talos.
https://talosintelligence.com/vulnerability_reports/