From Daniel Roethlisberger wrote
While using the Linux drivers for the CM4040 as a reference for writing a cmx
FreeBSD driver I found two buffer overflows in the Linux drivers, one in the
write() and one in the read() handler.
When calling write() with a buffer larger than 512 bytes, the driver's write
buffer overflows, allowing to overwrite the EIP and execute arbitrary code with
In read(), we have a similar problem, but coming from the device. A malicous or
buggy device sending more than 512 bytes can overflow of the driver's read
buffer, with the same effects as above.
The write() vulnerability can only be exploited by a user with direct or
indirect write access to the cmx device special file. Normally, this is limited
to root, so this is not an issue. However, it might be possible for unprivileged
users to cause large writes indirectly via userland daemons such as those
provided by pcsc-lite or openct. Since "normal" APDU payloads are smaller than
512 bytes, this may not be an issue, but I haven't looked into that.
Furthermore, a system can be set up to allow access to the device for a special
user or group, in order to increase security by running the userland drivers
without root privileges. In such a setup, users with access to the device can
elevate privileges or cause DoS.
The problem code in cm4040_cs.c:cm4040_write() is on line 358 (current version
in Linus' git tree), when calling copy_from_user() with user supplied
bytes_to_write, which can be larger than 512 bytes. Because it does not seem to
make sense to write partial messages to this card reader, I think it is best to
return an appropriate error on write()'s larger than the write buffer. This is
what I do in the FreeBSD driver.
The problem code in cm4040_cs.c:cm4040_read() is around line 271 where
bytes_to_read is read from the card reader, and subsequently, min(count,
bytes_to_read + 5) bytes are read from the reader. min(count, bytes_to_read + 5)
can however be larger than the read buffer, which would cause an overflow.
The embargo ended on 6th of March.
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on the solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.