As promised, I've now published the full poc that achieves code
execution in evince/papers:

https://github.com/github/securitylab/tree/main/SecurityExploits/DjVuLibre/MMRDecoder_scanruns_CVE-2025-53367

Kev

On Thu, Jul 3, 2025 at 8:14 PM Kevin Backhouse
<kevinbackho...@github.com> wrote:
>
> DjVuLibre version 3.5.29 was released today. It fixes CVE-2025-53367
> (GHSL-2025-055), an out-of-bounds write in the MMRDecoder::scanruns
> method. The vulnerability could be exploited to gain code execution on
> a Linux Desktop system when the user tries to open a crafted document.
>
> DjVu is a document file format that can be used for similar purposes
> to PDF. It is supported by evince and papers, the default document
> viewers on many Linux distributions. In fact, even when a djvu file is
> given a filename with a .pdf extension, evince/papers will
> automatically detect that it is a DjVu document and run DjVuLibre to
> decode it.
>
> This vulnerability was found by my colleague Antonio Morales while
> researching the Evince document reader. He found the bug with fuzzing.
>
> I have developed a proof of concept exploit for the vulnerability, as
> demoed in this video: https://youtu.be/32kROHYhYVM. The poc works on a
> fully up-to-date Ubuntu 25.04 (x86_64) with all the standard security
> protections enabled. To explain what’s happening in the video:
>
> 1. I click on a malicious DjVu document in my ~/Downloads directory.
> 2. The file is named poc.pdf, but it’s actually in DjVu format.
> 3. The default document viewer (/usr/bin/papers) loads the document,
> detects that it’s in DjVu format, and uses DjVuLibre to decode it.
> 4. The file exploits the OOB write vulnerability and triggers a call
> to system("google-chrome https://www.youtube.com/…";).
> 5. Rick Astley appears.
>
> Although the poc is able to bypass ASLR, it's somewhat unreliable:
> it’ll work 10 times in a row and then suddenly stop working for
> several minutes. But this is only a first version, and I believe it’s
> possible to create an exploit that’s significantly more reliable.
>
> You may be wondering: why Astley, and not a calculator? That’s because
> /usr/bin/papers runs under an AppArmor profile. The profile prohibits
> you from starting an arbitrary process but makes an exception for
> google-chrome. So it was easier to play a youtube video than pop a
> calc. But the AppArmor profile is not particularly restrictive: for
> example, it lets you write arbitrary files to the user’s home
> directory, except for the really obvious one like ~/.bashrc. So it
> wouldn’t prevent a determined attacker from gaining code execution.
>
> # Vulnerability Details
>
> The MMRDecoder::scanruns method is affected by an OOB-write
> vulnerability, because it doesn't check that the xr pointer stays
> within the bounds of the allocated buffer.
>
> During the decoding process, run-length encoded data is written into
> two buffers: lineruns and prevruns:
>
> //libdjvu/MMRDecoder.h
> class DJVUAPI MMRDecoder : public GPEnabled
> {
> ...
> public:
>
>   unsigned short *lineruns;
> ...
>   unsigned short *prevruns;
> ...
>
> }
>
> The variables named pr and xr point to the current locations in those
> buffers. scanruns does not check that those pointers remain within the
> bounds of the allocated buffers.
>
> //libdjvu/MMRDecoder.cpp
> const unsigned short *
> MMRDecoder::scanruns(const unsigned short **endptr)
> {
> ...
>   // Swap run buffers
>   unsigned short *pr = lineruns;
>   unsigned short *xr = prevruns;
>   prevruns = pr;
>   lineruns = xr;
> ...
>   for(a0=0,rle=0,b1=*pr++;a0 < width;)
>     {
>      ...
>             *xr = rle; xr++; rle = 0;
>      ...
>             *xr = rle; xr++; rle = 0;
>  ...
>           *xr = inc+rle-a0;
>           xr++;
> }
>
> This can lead to writes beyond the allocated memory, resulting in a
> heap corruption condition. An out-of-bounds read with pr is also
> possible for the same reason.
>
> We will publish the source code of our proof of concept exploit in a
> couple of weeks’ time at https://github.com/github/securitylab.
>
> # Acknowledgements
>
> We would like to thank Léon Bottou and Bill Riemers for responding
> incredibly quickly and releasing a fix less than two days after we
> first contacted them!
>
> # Timeline
>
> 2025-07-01: Reported via email to the authors: Léon Bottou, Bill
> Riemers, Yann LeCun.
> 2025-07-01: Responses received from Bill Riemers and Léon Bottou.
> 2025-07-02: Fix commit added by Léon Bottou:
> https://sourceforge.net/p/djvu/djvulibre-git/ci/33f645196593d70bd5e37f55b63886c31c82c3da/
> 2025-07-03: DjVuLibre version 3.5.29 released:
> https://sourceforge.net/p/djvu/www-git/ci/9748b43794440aff40bae066132aa5c22e7fd6a3/
>
> # References
>
> Source code location:
> https://sourceforge.net/p/djvu/djvulibre-git/ci/42029c33b2fb25bc1fa98c80b2be83a2fa23cce1/tree/libdjvu/MMRDecoder.cpp

Reply via email to