Buffer Overflows in cmd.cc

"Michael Vaughan (RIT Student)" <[email protected]> Sun, 4 Apr 2021 23:53:21 -0400
Newsgroups gmane.comp.gnu.chess.bugs
Message-ID <CAG_B7gNpchuH4jZtWQ7=7XNZFZMMUEDHR5SDAMttyQ8rm6AuNg@mail.gmail.com>
--000000000000b1ac1a05bf31a55a
Content-Type: multipart/alternative; boundary="000000000000b1ac1805bf31a558"

--000000000000b1ac1805bf31a558
Content-Type: text/plain; charset="UTF-8"

Hello,

I wanted to report a potentially exploitable issue within the cmd_pgnload()
and cmd_pgnreplay() functions in cmd.cc. In the loop between lines 482-485
in the former function, a specially crafted epdline could overrun the data
buffer located here:

char data[MAXSTR]="";
char epdline[MAXSTR]="";

/* snip */

int i=0;


*while ( epdline[i] != '\n' ) {  data[i+9] = epdline[i];  ++i;*
*}*

Since this loop only ends when there is a newline within epdline, the end
of the data buffer is not checked and the program will continue to copy
bytes into and past the buffer, eventually overwriting the return address
on the stack. A PGN file that exploits this bug is potentially possible,
but it is easier to reproduce this in gdb by setting a breakpoint on the
load_pgn_as_epd() function. Then load any compliant file with the pgnload
command as follows:

pgnload *<filename>*

If you step after the SaveEPD() call but before the temporary file
".tmp.epd" is opened with fopen(), you can write to (or replace) the
temporary file with a buffer overflow payload, like two hundred of "A".
Continuing the program will cause it to open and copy this into the 128
byte data buffer, overflowing it and overwriting the return address, as
well as any stack cookie or other data in the way. This code is mirrored in
the cmd_pgnreplay() function also, and can be mitigated in the same way. It
should be reproducible there using the same steps.

I have attached a patch to this email with a potential fix to this issue. I
hope this finds you well.

Regards,

Michael Vaughan

--000000000000b1ac1805bf31a558
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hello,</div><div><br></div><div>I wanted to report a =
potentially exploitable issue within the cmd_pgnload() and cmd_pgnreplay() =
functions in cmd.cc. In the loop between lines 482-485 in the former functi=
on, a specially crafted epdline could overrun the data buffer located here:=
</div><div><br></div><div>char data[MAXSTR]=3D&quot;&quot;;<br>char epdline=
[MAXSTR]=3D&quot;&quot;;</div><div><br></div><div>/* snip */</div><div><br>=
</div><div>int i=3D0;<br><b>while ( epdline[i] !=3D &#39;\n&#39; ) {<br>=C2=
=A0 data[i+9] =3D epdline[i];<br>=C2=A0 ++i;</b></div><div><b>}</b></div><d=
iv><b><br></b></div><div>Since this loop only ends when there is a newline =
within epdline, the end of the data buffer is not checked and the program w=
ill continue to copy bytes into and past the buffer, eventually overwriting=
 the return address on the stack. A PGN file that exploits this bug is pote=
ntially possible, but it is easier to reproduce this in gdb by setting a br=
eakpoint on the load_pgn_as_epd() function. Then load any compliant file wi=
th the pgnload command as follows:</div><div><br></div><div>pgnload <i>&lt;=
filename&gt;</i></div><div><br></div><div>If you step after the SaveEPD() c=
all but before the temporary file &quot;.tmp.epd&quot; is opened with fopen=
(), you can write to (or replace) the temporary file with a buffer overflow=
 payload, like two hundred of &quot;A&quot;. Continuing the program will ca=
use it to open and copy this into the 128 byte data buffer, overflowing it =
and overwriting the return address, as well as any stack cookie or other da=
ta in the way. This code is mirrored in the cmd_pgnreplay() function also, =
and can be mitigated in the same way. It should be reproducible there using=
 the same steps.<br></div><div><br></div><div>I have attached a patch to th=
is email with a potential fix to this issue. I hope this finds you well.</d=
iv><div><br></div><div>Regards,</div><div><br></div><div>Michael Vaughan<br=
></div><div><b></b></div></div>

--000000000000b1ac1805bf31a558--

--000000000000b1ac1a05bf31a55a
Content-Type: text/x-patch; charset="US-ASCII"; name="gnuchess.patch"
Content-Disposition: attachment; filename="gnuchess.patch"
Content-Transfer-Encoding: base64
Content-ID: <f_kn414y6s0>
X-Attachment-Id: f_kn414y6s0

LS0tIC90bXAvY21kLmNjCTIwMjEtMDQtMDQgMjM6MjA6MDYuNzIwMzg4NjYxIC0wNDAwCisrKyBj
bWQuY2MJMjAyMS0wNC0wNCAyMzoxNDozNS4wOTUzNTkyNTEgLTA0MDAKQEAgLTQ4MCw4ICs0ODAs
MTMgQEAKICAgc3RyY3B5KCBkYXRhLCAic2V0Ym9hcmQgIiApOwogICBpbnQgaT0wOwogICB3aGls
ZSAoIGVwZGxpbmVbaV0gIT0gJ1xuJyApIHsKLSAgICBkYXRhW2krOV0gPSBlcGRsaW5lW2ldOwot
ICAgICsraTsKKyAgICBpZiAoKGkgKyA5KSA8IE1BWFNUUiAtIDEpIHsKKyAgICAgICAgZGF0YVtp
KzldID0gZXBkbGluZVtpXTsKKyAgICAgICAgKytpOworICAgIH0gZWxzZSB7CisgICAgICAgIHBy
aW50ZihfKCJFcnJvciByZWFkaW5nIGNvbnRlbnRzIG9mIGZpbGUgJyVzJy5cbiIpLCB0b2tlblsx
XSk7CisgICAgICAgIGJyZWFrOworICAgIH0KICAgfQogICBkYXRhW2krOV0gPSAnXDAnOwogICBT
ZXREYXRhVG9FbmdpbmUoIGRhdGEgKTsKQEAgLTUwNCw4ICs1MDksMTMgQEAKICAgc3RyY3B5KCBk
YXRhLCAic2V0Ym9hcmQgIiApOwogICBpbnQgaT0wOwogICB3aGlsZSAoIGVwZGxpbmVbaV0gIT0g
J1xuJyApIHsKLSAgICBkYXRhW2krOV0gPSBlcGRsaW5lW2ldOwotICAgICsraTsKKyAgICBpZiAo
KGkgKyA5KSA8IE1BWFNUUiAtIDEpIHsKKyAgICAgICAgZGF0YVtpKzldID0gZXBkbGluZVtpXTsK
KyAgICAgICAgKytpOworICAgIH0gZWxzZSB7CisgICAgICAgIHByaW50ZihfKCJFcnJvciByZWFk
aW5nIGNvbnRlbnRzIG9mIGZpbGUgJyVzJy5cbiIpLCB0b2tlblsxXSk7CisgICAgICAgIGJyZWFr
OworICAgIH0KICAgfQogICBkYXRhW2krOV0gPSAnXDAnOwogCg==
--000000000000b1ac1a05bf31a55a--