[xml/sgml-pkgs] Bug#902051: libxslt: generate-id() not returning unique IDs

ma.jiang at zte.com.cn ma.jiang at zte.com.cn
Tue Dec 3 03:21:27 GMT 2019


Dear Maintainer,
We have managed to get a unique IDs (without multi-thread). Hope this could help to get a reproducible build.

Now the ID is generated by a ptr diff. 
val = (long)((char *)cur - (char *)&base_address);
cur is the address of a xmlNsPtr node stored in a hash table(of course, eventually it's in the heap), base_address is a static variable(in a data section);

After some debug, we found there are two major disturbances that prevent a reproducible build.
First, hash functions use a random seed get from time(). So the address of nodes in hash tables(related to cur) is not stable across multi-builds.
Second, ASLR (Address Space Layout Randomization) changes the base addresses of data section and heap  every time we start a new process.

To fix the first problem, we could fake a fixed time. We currently use libfaketime, and of course eventually  something like https://gitlab.gnome.org/GNOME/libxslt/commit/e57df303eca25a2a3f9e0625c29f4b20177858cc   should be applied.

To fix the second problem, we could change the ptr diff algorithm to 
val = (long)((char *)cur -  heapStartAddr);
After this change, ALSR could not disturb ID generation anymore, because we have eliminated the base address of heap.
==========================================================================================================
We have use the following patch to make the xlstproc produce stable IDs.
--- libxslt-master/libxslt/functions.c  2010-12-24 20:30:00.000000000 +0800
+++ libxslt-master-new/libxslt/functions.c      2010-12-24 20:30:00.000000000 +0800
@@ -14,7 +14,7 @@
 #include "libxslt.h"

 #include <string.h>
-
+#include <unistd.h>
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -671,6 +671,13 @@ xsltFormatNumberFunction(xmlXPathParserC
     xmlXPathFreeObject(decimalObj);
 }

+
+static char *__heapStartAddr;
+static __attribute__((constructor)) void initHeapStart()
+{
+       __heapStartAddr = sbrk(0);
+}
+
 /**
  * xsltGenerateIdFunction:
  * @ctxt:  the XPath Parser context
@@ -681,7 +688,6 @@ xsltFormatNumberFunction(xmlXPathParserC
  */
 void
 xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
-    static char base_address;
     xmlNodePtr cur = NULL;
     xmlXPathObjectPtr obj = NULL;
     long val;
@@ -722,7 +728,8 @@ xsltGenerateIdFunction(xmlXPathParserCon
     if (obj)
         xmlXPathFreeObject(obj);

-    val = (long)((char *)cur - (char *)&base_address);
+    val = (long)((char *)cur - __heapStartAddr);
+
     if (val >= 0) {
       snprintf((char *)str, sizeof(str), "idp%ld", val);
     } else {


More information about the debian-xml-sgml-pkgs mailing list