Bug#924050: poppler-utils: pdfsig segfaults on signed PDF

Bernhard Übelacker bernhardu at mailbox.org
Tue Apr 16 23:44:27 BST 2019


Dear Maintainer,
tried to have another look with the original input file.

In my minimal test VM I came again across the segfault I
described in message #10, which is not the
problem Wesley hit and got sumitted in #926404 too.
So I had to start firefox once to have a profile
in the home directory.

Then I could successfully reproduce the crash, see the
backtrace below with debug information.

For this I could not find a upstream bug report.
But upstream commit [1] changed method SignatureInfo::setSubjectDN
to avoid it.

Therefore tried to build with this patch and found that it
touches the same area as [2] from message #10, therefore
included that too before.

With both applied pdfsig gives information for this file
without crashing, with or without a .mozilla directory.

Kind regards,
Bernhard


#926404 https://bugs.debian.org/926404
[1] https://gitlab.freedesktop.org/poppler/poppler/commit/7486e4995d66f1a8676f3e65e408e8cdab049f6b
[2] https://gitlab.freedesktop.org/poppler/poppler/commit/a85c2ed8f4359341adb94887c4b551a761244fdb


(gdb) bt
#0  __strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:120
#1  0x00007ffff7a1bfee in __GI___strdup (s=s at entry=0x0) at strdup.c:41
#2  0x00007ffff7e8340d in SignatureInfo::setSubjectDN (this=this at entry=0x5555555a3e80, subjectDN=0x0) at ./poppler/SignatureInfo.cc:127
#3  0x00007ffff7df3e19 in FormFieldSignature::validateSignature (forceRevalidation=<optimized out>, validationTime=-1, doVerifyCert=true, this=0x5555555a07f0) at ./poppler/Form.cc:1749
#4  FormFieldSignature::validateSignature (this=0x5555555a07f0, doVerifyCert=<optimized out>, forceRevalidation=<optimized out>, validationTime=-1) at ./poppler/Form.cc:1689
#5  0x0000555555556a5d in main (argc=<optimized out>, argv=<optimized out>) at /usr/include/c++/8/bits/stl_vector.h:979


(gdb) list SignatureInfo.cc:124,128
124     void SignatureInfo::setSubjectDN(const char *subjectDN)
125     {
126       free(subject_dn);
127       subject_dn = strdup(subjectDN);
128     }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: a85c2ed8f4359341adb94887c4b551a761244fdb-adapted-to-debian.patch
Type: text/x-patch
Size: 1432 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/pkg-freedesktop-maintainers/attachments/20190417/ff21b7c1/attachment-0002.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 7486e4995d66f1a8676f3e65e408e8cdab049f6b-adapted-to-debian.patch
Type: text/x-patch
Size: 9457 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/pkg-freedesktop-maintainers/attachments/20190417/ff21b7c1/attachment-0003.bin>
-------------- next part --------------

# Buster amd64 qemu VM 2019-04-16

apt update
apt dist-upgrade


apt install dpkg-dev devscripts systemd-coredump mc colordiff gdb poppler-utils poppler-utils-dbgsym libpoppler82-dbgsym libnss3-dbgsym
apt build-dep poppler





mkdir /tmp/source/poppler/orig -p
cd    /tmp/source/poppler/orig
apt source poppler
cd




wget "https://bugs.debian.org/cgi-bin/bugreport.cgi?att=1;bug=924050;filename=bar.pdf;msg=27" -O bar.pdf




gdb -q --args /usr/bin/pdfsig bar.pdf

set width 0
set pagination off
directory /tmp/source/poppler/orig/poppler-0.71.0
run



#########


benutzer at debian:~$ gdb -q --args /usr/bin/pdfsig bar.pdf
Reading symbols from /usr/bin/pdfsig...Reading symbols from /usr/lib/debug/.build-id/5f/ce5695b347676a643ad15d59bd7cd19e30360d.debug...done.
done.
(gdb) set width 0
(gdb) set pagination off
(gdb) directory /tmp/source/libnss3/orig/nss-3.42.1/nss/lib/pk11wrap
Warning: /tmp/source/libnss3/orig/nss-3.42.1/nss/lib/pk11wrap: Datei oder Verzeichnis nicht gefunden.
Source directories searched: /tmp/source/libnss3/orig/nss-3.42.1/nss/lib/pk11wrap:$cdir:$cwd
(gdb) run
Starting program: /usr/bin/pdfsig bar.pdf
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Digital Signature Info of: bar.pdf
Internal Error (0): couldn't find default Firefox Folder

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff731bc84 in SECMOD_ReferenceModule (module=0x0) at pk11util.c:847
847     pk11util.c: Datei oder Verzeichnis nicht gefunden.
(gdb) bt
#0  0x00007ffff731bc84 in SECMOD_ReferenceModule (module=0x0) at pk11util.c:847
#1  0x00007ffff731c1fc in SECMOD_AddModule (newModule=0x5555555ca6b0) at pk11util.c:541
#2  SECMOD_AddModule (newModule=0x5555555ca6b0) at pk11util.c:519
#3  0x00007ffff731c2a0 in SECMOD_AddNewModuleEx (moduleName=0x7ffff7f46e7d "Root Certs", dllPath=0x7ffff7f46e6f "libnssckbi.so", defaultMechanismFlags=0, cipherEnableFlags=0, modparms=<optimized out>, nssparms=<optimized out>) at pk11util.c:695
#4  0x00007ffff7efb199 in SignatureHandler::SignatureHandler (this=0x7fffffffe1b0, p7=0x5555555bdc20 "\232\375\240\067\060\031\022\313\301:\227_\260\251\302Ή", p7_length=13680) at ./poppler/SignatureHandler.cc:136
#5  0x00007ffff7df5b16 in FormFieldSignature::validateSignature (forceRevalidation=<optimized out>, validationTime=-1, doVerifyCert=true, this=0x5555555a07f0) at ./poppler/Form.cc:1722
#6  FormFieldSignature::validateSignature (this=0x5555555a07f0, doVerifyCert=<optimized out>, forceRevalidation=<optimized out>, validationTime=-1) at ./poppler/Form.cc:1689
#7  0x0000555555556a5d in main (argc=<optimized out>, argv=<optimized out>) at /usr/include/c++/8/bits/stl_vector.h:979


##########


apt install xserver-xorg lightdm openbox firefox-esr

systemctl start lightdm

export DISPLAY=:0
firefox&

# and open it, now ".mozilla" exists



##########



benutzer at debian:~$ strace -f /usr/bin/pdfsig bar.pdf 2>&1 | grep -E "/etc|\.mozilla" | grep -v ENOENT
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/localtime", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/home/benutzer/.mozilla/firefox/", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 4
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/home/benutzer/.mozilla/firefox/fcj3gzah.default/pkcs11.txt", O_RDONLY) = 4
stat("/etc/passwd", {st_mode=S_IFREG|0644, st_size=1540, ...}) = 0
openat(AT_FDCWD, "/etc/passwd", O_RDONLY) = 4
access("/home/benutzer/.mozilla/firefox/fcj3gzah.default/cert9.db", F_OK) = 0
lstat("/home/benutzer/.mozilla/firefox/fcj3gzah.default/cert9.db", {st_mode=S_IFREG|0600, st_size=28672, ...}) = 0
openat(AT_FDCWD, "/home/benutzer/.mozilla/firefox/fcj3gzah.default/cert9.db", O_RDONLY|O_CLOEXEC) = 4
stat("/home/benutzer/.mozilla/firefox/fcj3gzah.default/cert9.db", {st_mode=S_IFREG|0600, st_size=28672, ...}) = 0
statfs("/home/benutzer/.mozilla/firefox/fcj3gzah.default/cert9.db", {f_type=EXT2_SUPER_MAGIC, f_bsize=4096, f_blocks=4869796, f_bfree=4251199, f_bavail=3998067, f_files=1245184, f_ffree=1159260, f_fsid={val=[1006509210, 1119322840]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_RELATIME}) = 0
access("/home/benutzer/.mozilla/firefox/fcj3gzah.default/key4.db", F_OK) = 0
lstat("/home/benutzer/.mozilla/firefox/fcj3gzah.default/key4.db", {st_mode=S_IFREG|0600, st_size=36864, ...}) = 0
stat("/home/benutzer/.mozilla/firefox/fcj3gzah.default/key4.db", {st_mode=S_IFREG|0600, st_size=36864, ...}) = 0
openat(AT_FDCWD, "/home/benutzer/.mozilla/firefox/fcj3gzah.default/key4.db", O_RDONLY|O_CLOEXEC) = 5
stat("/home/benutzer/.mozilla/firefox/fcj3gzah.default/key4.db", {st_mode=S_IFREG|0600, st_size=36864, ...}) = 0
statfs("/home/benutzer/.mozilla/firefox/fcj3gzah.default/key4.db", {f_type=EXT2_SUPER_MAGIC, f_bsize=4096, f_blocks=4869796, f_bfree=4251199, f_bavail=3998067, f_files=1245184, f_ffree=1159260, f_fsid={val=[1006509210, 1119322840]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_RELATIME}) = 0
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6



##########


benutzer at debian:~$ gdb -q --args /usr/bin/pdfsig bar.pdf
Reading symbols from /usr/bin/pdfsig...Reading symbols from /usr/lib/debug/.build-id/5f/ce5695b347676a643ad15d59bd7cd19e30360d.debug...done.
done.
(gdb) set width 0
(gdb) set pagination off
(gdb) directory /tmp/source/poppler/orig/poppler-0.71.0
Source directories searched: /tmp/source/poppler/orig/poppler-0.71.0:$cdir:$cwd
(gdb) run
Starting program: /usr/bin/pdfsig bar.pdf
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Digital Signature Info of: bar.pdf
Internal Error (0): Input couldn't be parsed as a CMS signature

Program received signal SIGSEGV, Segmentation fault.
__strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:120
120     ../sysdeps/x86_64/multiarch/../strlen.S: Datei oder Verzeichnis nicht gefunden.

(gdb) bt
#0  __strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:120
#1  0x00007ffff7a1bfee in __GI___strdup (s=s at entry=0x0) at strdup.c:41
#2  0x00007ffff7e8340d in SignatureInfo::setSubjectDN (this=this at entry=0x5555555a3e80, subjectDN=0x0) at ./poppler/SignatureInfo.cc:127
#3  0x00007ffff7df3e19 in FormFieldSignature::validateSignature (forceRevalidation=<optimized out>, validationTime=-1, doVerifyCert=true, this=0x5555555a07f0) at ./poppler/Form.cc:1749
#4  FormFieldSignature::validateSignature (this=0x5555555a07f0, doVerifyCert=<optimized out>, forceRevalidation=<optimized out>, validationTime=-1) at ./poppler/Form.cc:1689
#5  0x0000555555556a5d in main (argc=<optimized out>, argv=<optimized out>) at /usr/include/c++/8/bits/stl_vector.h:979



(gdb) list SignatureInfo.cc:124,128
124     void SignatureInfo::setSubjectDN(const char *subjectDN)
125     {
126       free(subject_dn);
127       subject_dn = strdup(subjectDN);
128     }

(gdb) print subjectDN
$1 = 0x0
(gdb) print subject_dn
$2 = 0x0




(gdb) up
#3  0x00007ffff7df3e19 in FormFieldSignature::validateSignature (forceRevalidation=<optimized out>, validationTime=-1, doVerifyCert=true, this=0x5555555a07f0) at ./poppler/Form.cc:1749
1749      signature_info->setSubjectDN(signature_handler.getSignerSubjectDN());

(gdb) list Form.cc:1689,1766
1689    SignatureInfo *FormFieldSignature::validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime)
1690    {
1691    #ifdef ENABLE_NSS3
1692      if (!signature_info->isSubfilterSupported()) {
1693        error(errUnimplemented, 0, "Unable to validate this type of signature");
1694        return signature_info;
1695      }
1696
1697      if (signature_info->getSignatureValStatus() != SIGNATURE_NOT_VERIFIED && !forceRevalidation) {
1698        return signature_info;
1699      }
1700
1701      if (signature == nullptr) {
1702        error(errSyntaxError, 0, "Invalid or missing Signature string");
1703        return signature_info;
1704      }
1705
1706      if (!byte_range.isArray()) {
1707        error(errSyntaxError, 0, "Invalid or missing ByteRange array");
1708        return signature_info;
1709      }
1710
1711      int arrayLen = byte_range.arrayGetLength();
1712      if (arrayLen < 2) {
1713        error(errSyntaxError, 0, "Too few elements in ByteRange array");
1714        return signature_info;
1715      }
1716
1717      NSSCMSVerificationStatus sig_val_state;
1718      SECErrorCodes cert_val_state;
1719      const int signature_len = signature->getLength();
1720      unsigned char *signatureuchar = (unsigned char *)gmalloc(signature_len);
1721      memcpy(signatureuchar, signature->getCString(), signature_len);
1722      SignatureHandler signature_handler(signatureuchar, signature_len);
1723
1724      Goffset fileLength = doc->getBaseStream()->getLength();
1725      for (int i = 0; i < arrayLen/2; i++) {
1726        Object offsetObj = byte_range.arrayGet(i*2);
1727        Object lenObj = byte_range.arrayGet(i*2+1);
1728
1729        if (!offsetObj.isIntOrInt64() || !lenObj.isIntOrInt64()) {
1730          error(errSyntaxError, 0, "Illegal values in ByteRange array");
1731          return signature_info;
1732        }
1733
1734        Goffset offset = offsetObj.getIntOrInt64();
1735        Goffset len = lenObj.getIntOrInt64();
1736
1737        if (offset < 0 || offset >= fileLength || len < 0 || len > fileLength || offset + len > fileLength) {
1738          error(errSyntaxError, 0, "Illegal values in ByteRange array");
1739          return signature_info;
1740        }
1741
1742        doc->getBaseStream()->setPos(offset);
1743        hashSignedDataBlock(&signature_handler, len);
1744      }
1745
1746      sig_val_state = signature_handler.validateSignature();
1747      signature_info->setSignatureValStatus(SignatureHandler::NSS_SigTranslate(sig_val_state));
1748      signature_info->setSignerName(signature_handler.getSignerName());
1749      signature_info->setSubjectDN(signature_handler.getSignerSubjectDN());
1750      signature_info->setHashAlgorithm(signature_handler.getHashAlgorithm());
1751
1752      // verify if signature contains a 'signing time' attribute
1753      if (signature_handler.getSigningTime() != 0) {
1754        signature_info->setSigningTime(signature_handler.getSigningTime());
1755      }
1756
1757      if (sig_val_state != NSSCMSVS_GoodSignature || !doVerifyCert) {
1758        return signature_info;
1759      }
1760
1761      cert_val_state = signature_handler.validateCertificate(validationTime);
1762      signature_info->setCertificateValStatus(SignatureHandler::NSS_CertTranslate(cert_val_state));
1763
1764    #endif
1765      return signature_info;
1766    }





https://gitlab.freedesktop.org/poppler/poppler/commit/7486e4995d66f1a8676f3e65e408e8cdab049f6b




#########


cd /tmp/source/poppler
cp orig try1 -a
cd try1
wget "https://bugs.debian.org/cgi-bin/bugreport.cgi?att=1;bug=924050;filename=a85c2ed8f4359341adb94887c4b551a761244fdb-adapted-to-debian.patch;msg=10" -O a85c2ed8f4359341adb94887c4b551a761244fdb-adapted-to-debian.patch
wget "https://gitlab.freedesktop.org/poppler/poppler/commit/7486e4995d66f1a8676f3e65e408e8cdab049f6b.patch" -O 7486e4995d66f1a8676f3e65e408e8cdab049f6b.patch
cd poppler-0.71.0
git init
git config user.name "..."
git config user.email "..."
git add .
git commit -m "Initial commit"

...


cd /tmp/source/poppler
cp orig try1 -a
cd try4/poppler-0.71.0
patch -p1 < ../../try1/a85c2ed8f4359341adb94887c4b551a761244fdb-adapted-to-debian.patch
patch -p1 < ../../try1/7486e4995d66f1a8676f3e65e408e8cdab049f6b-adapted-to-debian.patch
dpkg-buildpackage -b


dpkg -i /tmp/source/poppler/try4/{libpoppler82,libpoppler82-dbgsym,poppler-utils,poppler-utils-dbgsym}_0.71.0-3_amd64.deb



benutzer at debian:~$ /usr/bin/pdfsig bar.pdf
Digital Signature Info of: bar.pdf
Internal Error (0): Input couldn't be parsed as a CMS signature
Signature #1:
  - Signer Certificate Common Name: (null)
  - Signer full Distinguished Name: (null)
  - Signing Time: Mar 08 2019 11:10:19
  - Signing Hash Algorithm: unknown
  - Signature Type: adbe.pkcs7.detached
  - Signed Ranges: [0 - 12877], [40303 - 123158]
  - Total document signed
  - Signature Validation: Unknown Validation Failure.



More information about the Pkg-freedesktop-maintainers mailing list