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