[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#914081: stretch-pu: package jdupes/1.7-2



Package: release.debian.org
Severity: normal
Tags: stretch
User: release.debian.org@packages.debian.org
Usertags: pu

>From the jdupes upstream:

"All versions from 1.5.1 up to 1.7 have potentially serious bugs in the
internal memory allocator which caused crashes on Debian ARM and macOS
Sierra. These should be updated to a minimum of v1.8 if at all possible.

If that isn't possible, the following commits improving/fixing the internal
memory allocator should be patched into the old versions:

e2bebfdbadd0474a6b5f16f46ce1b48201d75150
78e06c3eb1f1cfdebf8ca555f5c699b69b3a9aad
1f2fe4a0c1bca7486cfc5aa84877246e90d1321a
1498a04e2ad5ba6cef6e94c5f64408d35670f7b8"

This upload will close #914078

Thanks in advance.

Regards,

Eriberto
diff -Nru jdupes-1.7/debian/changelog jdupes-1.7/debian/changelog
--- jdupes-1.7/debian/changelog	2017-02-06 22:19:51.000000000 -0200
+++ jdupes-1.7/debian/changelog	2018-11-19 00:10:16.000000000 -0200
@@ -1,3 +1,10 @@
+jdupes (1.7-2+deb9u1) stretch; urgency=medium
+
+  * debian/patches/20_fix-crash-arm.patch: add to fix a potential crash in
+    ARM. Thanks to Jody Bruchon <jody@jodybruchon.com>. (Closes: #914078)
+
+ -- Joao Eriberto Mota Filho <eriberto@debian.org>  Mon, 19 Nov 2018 00:10:16 -0200
+
 jdupes (1.7-2) unstable; urgency=medium
 
   * debian/patches/10_fix-segfault.patch: added to fix a segmentation fault in
diff -Nru jdupes-1.7/debian/patches/20_fix-crash-arm.patch jdupes-1.7/debian/patches/20_fix-crash-arm.patch
--- jdupes-1.7/debian/patches/20_fix-crash-arm.patch	1969-12-31 21:00:00.000000000 -0300
+++ jdupes-1.7/debian/patches/20_fix-crash-arm.patch	2018-11-19 00:10:16.000000000 -0200
@@ -0,0 +1,250 @@
+Description: fix a potential crash in ARM.
+ From the jdupes upstream:
+
+ "All versions from 1.5.1 up to 1.7 have potentially serious bugs in the
+ internal memory allocator which caused crashes on Debian ARM and macOS
+ Sierra. These should be updated to a minimum of v1.8 if at all possible.
+
+ If that isn't possible, the following commits improving/fixing the internal
+ memory allocator should be patched into the old versions:
+
+ e2bebfdbadd0474a6b5f16f46ce1b48201d75150
+ 78e06c3eb1f1cfdebf8ca555f5c699b69b3a9aad
+ 1f2fe4a0c1bca7486cfc5aa84877246e90d1321a
+ 1498a04e2ad5ba6cef6e94c5f64408d35670f7b8
+Author: Jody Bruchon <jody@jodybruchon.com>
+Origin: upstream
+        https://github.com/jbruchon/jdupes/commit/e2bebfdbadd0474a6b5f16f46ce1b48201d75150.patch
+        https://github.com/jbruchon/jdupes/commit/78e06c3eb1f1cfdebf8ca555f5c699b69b3a9aad.patch
+        https://github.com/jbruchon/jdupes/commit/1f2fe4a0c1bca7486cfc5aa84877246e90d1321a.patch
+        https://github.com/jbruchon/jdupes/commit/1498a04e2ad5ba6cef6e94c5f64408d35670f7b8.patch
+Bug-Debian: https://bugs.debian.org/914078
+Last-Update: 2017-01-19
+--- jdupes-1.7.orig/jdupes.c
++++ jdupes-1.7/jdupes.c
+@@ -501,18 +501,24 @@ extern int check_conditions(const file_t
+ }
+ 
+ 
+-/* Create a new traversal check object */
+-static int travdone_alloc(struct travdone **trav, const char * const restrict dir)
++/* Create a new traversal check object and initialize its values */
++static struct travdone *travdone_alloc(const jdupes_ino_t inode, const dev_t device)
+ {
+-  *trav = string_malloc(sizeof(struct travdone));
+-  if (*trav == NULL) {
++  struct travdone *trav;
++
++  LOUD(fprintf(stderr, "travdone_alloc(%jd, %jd)\n", (intmax_t)inode, (intmax_t)device);)
++
++  trav = (struct travdone *)string_malloc(sizeof(struct travdone));
++  if (trav == NULL) {
+     LOUD(fprintf(stderr, "travdone_alloc: malloc returned NULL\n");)
+-    return -1;
++    return NULL;
+   }
+-  (*trav)->left = NULL;
+-  (*trav)->right = NULL;
+-  if (getdirstats(dir, &((*trav)->inode), &((*trav)->device)) != 0) return -1;
+-  return 0;
++  trav->left = NULL;
++  trav->right = NULL;
++  trav->inode = inode;
++  trav->device = device;
++  LOUD(fprintf(stderr, "travdone_alloc returned %p\n", (void *)trav);)
++  return trav;
+ }
+ 
+ 
+@@ -545,22 +551,23 @@ static void grokdir(const char * const r
+   LOUD(fprintf(stderr, "grokdir: scanning '%s' (order %d)\n", dir, user_dir_count));
+ 
+   /* Double traversal prevention tree */
++  if (getdirstats(dir, &inode, &device) != 0) goto error_travdone;
+   if (travdone_head == NULL) {
+-    if (travdone_alloc(&travdone_head, dir) != 0) goto error_travdone;
++    travdone_head = travdone_alloc(inode, device);
++    if (travdone_head == NULL) goto error_travdone;
+   } else {
+-    if (getdirstats(dir, &inode, &device) != 0) goto error_travdone;
+     traverse = travdone_head;
+     while (1) {
+       /* Don't re-traverse directories we've already seen */
+       if (inode == traverse->inode && device == traverse->device) {
+         LOUD(fprintf(stderr, "already seen dir '%s', skipping\n", dir);)
+         return;
+-      }
+-      if (inode >= traverse->inode) {
++      } else if (inode > traverse->inode || (inode == traverse->inode && device > traverse->device)) {
+         /* Traverse right */
+         if (traverse->right == NULL) {
+           LOUD(fprintf(stderr, "traverse dir right '%s'\n", dir);)
+-          if (travdone_alloc(&(traverse->right), dir) != 0) goto error_travdone;
++          traverse->right = travdone_alloc(inode, device);
++          if (traverse->right == NULL) goto error_travdone;
+           break;
+         }
+         traverse = traverse->right;
+@@ -569,7 +576,8 @@ static void grokdir(const char * const r
+         /* Traverse left */
+         if (traverse->left == NULL) {
+           LOUD(fprintf(stderr, "traverse dir left '%s'\n", dir);)
+-          if (travdone_alloc(&(traverse->left), dir) != 0) goto error_travdone;
++          traverse->left = travdone_alloc(inode, device);
++          if (traverse->left == NULL) goto error_travdone;
+           break;
+         }
+         traverse = traverse->left;
+--- jdupes-1.7.orig/string_malloc.c
++++ jdupes-1.7/string_malloc.c
+@@ -30,7 +30,7 @@
+ #endif
+ 
+ static void *sma_head = NULL;
+-static uintptr_t *sma_curpage = NULL;
++static uintptr_t *sma_lastpage = NULL;
+ static unsigned int sma_pages = 0;
+ static void *sma_freelist[SMA_MAX_FREE];
+ static int sma_freelist_cnt = 0;
+@@ -52,9 +52,9 @@ uintmax_t sma_free_tails = 0;
+ /* Scan the freed chunk list for a suitably sized object */
+ static inline void *scan_freelist(const size_t size)
+ {
+-	size_t *object, *min_p;
++	size_t *min_p, *object;
+ 	size_t sz, min = 0;
+-	int i, used = 0, min_i = -1;
++	int i, used = 0;
+ 
+ 	/* Don't bother scanning if the list is empty */
+ 	if (sma_freelist_cnt == 0) return NULL;
+@@ -74,9 +74,9 @@ static inline void *scan_freelist(const
+ 		/* Skip smaller objects */
+ 		if (sz < size) continue;
+ 		/* Object is big enough; record if it's the new minimum */
+-		if (min == 0 || sz <= min) {
++		if (min == 0 || sz < min) {
+ 			min = sz;
+-			min_i = i;
++			min_p = object;
+ 			/* Always stop scanning if exact sized object found */
+ 			if (sz == size) break;
+ 		}
+@@ -85,9 +85,8 @@ static inline void *scan_freelist(const
+ 	/* Enhancement TODO: split the free item if it's big enough */
+ 
+ 	/* Return smallest object found and delete from free list */
+-	if (min_i != -1) {
+-		min_p = sma_freelist[min_i];
+-		sma_freelist[min_i] = NULL;
++	if (min != 0) {
++		sma_freelist[i] = NULL;
+ 		sma_freelist_cnt--;
+ 		min_p++;
+ 		return (void *)min_p;
+@@ -108,10 +107,10 @@ static inline void *string_malloc_page(v
+ 	*pageptr = (uintptr_t)NULL;
+ 
+ 	/* Link previous page to this page, if applicable */
+-	if (sma_curpage != NULL) *sma_curpage = (uintptr_t)pageptr;
++	if (sma_lastpage != NULL) *sma_lastpage = (uintptr_t)pageptr;
+ 
+ 	/* Update last page pointers and total page counter */
+-	sma_curpage = pageptr;
++	sma_lastpage = pageptr;
+ 	sma_pages++;
+ 
+ 	return (void *)pageptr;
+@@ -120,7 +119,7 @@ static inline void *string_malloc_page(v
+ 
+ void *string_malloc(size_t len)
+ {
+-	const void * restrict page = (char *)sma_curpage;
++	const void * restrict page = (char *)sma_lastpage;
+ 	static size_t *address;
+ 
+ 	/* Calling with no actual length is invalid */
+@@ -131,6 +130,8 @@ void *string_malloc(size_t len)
+ 		len &= ~(sizeof(uintptr_t) - 1);
+ 		len += sizeof(uintptr_t);
+ 	}
++	/* Make room for size prefix */
++	len += sizeof(size_t);
+ 
+ 	/* Pass-through allocations larger than maximum object size to malloc() */
+ 	if (len > (SMA_PAGE_SIZE - sizeof(uintptr_t) - sizeof(size_t))) {
+@@ -150,7 +151,7 @@ void *string_malloc(size_t len)
+ 		for (int i = 0; i < SMA_MAX_FREE; i++) sma_freelist[i] = NULL;
+ 		/* Allocate first page and set up for first allocation */
+ 		sma_head = string_malloc_page();
+-		if (sma_head == NULL) return NULL;
++		if (!sma_head) return NULL;
+ 		sma_nextfree = sizeof(uintptr_t);
+ 		page = sma_head;
+ 	}
+@@ -163,20 +164,17 @@ void *string_malloc(size_t len)
+ 	}
+ 
+ 	/* Allocate new page if this object won't fit */
+-	if ((sma_nextfree + len + sizeof(size_t)) > SMA_PAGE_SIZE) {
++	if ((sma_nextfree + len) > SMA_PAGE_SIZE) {
+ 		size_t sz;
+ 		size_t *tailaddr;
+ 		/* See if remaining space is usable */
+-		if (sma_freelist_cnt < SMA_MAX_FREE && (sma_nextfree + sizeof(size_t)) < SMA_PAGE_SIZE) {
+-			/* Get remaining space size minus page linkage and obj size prefix */
+-			sz = sma_nextfree + sizeof(size_t) + SMA_MIN_SLACK;
+-
+-			if (sz <= SMA_PAGE_SIZE) {
+-				sz = SMA_PAGE_SIZE - sma_nextfree - sizeof(size_t);
++		if (sma_freelist_cnt < SMA_MAX_FREE && sma_nextfree < SMA_PAGE_SIZE) {
++			/* Get total remaining space size */
++			sz = SMA_PAGE_SIZE - sma_nextfree;
++			if (sz >= (SMA_MIN_SLACK + sizeof(size_t))) {
+ 				tailaddr = (size_t *)((uintptr_t)page + sma_nextfree);
+-				*tailaddr = (size_t)sz;
+-				tailaddr++;
+-				string_free(tailaddr);
++				*tailaddr = sz;
++				string_free(tailaddr + 1);
+ 				DBG(sma_free_tails++;)
+ 			}
+ 		}
+@@ -190,7 +188,7 @@ void *string_malloc(size_t len)
+ 	/* Prefix object with its size */
+ 	*address = len;
+ 	address++;
+-	sma_nextfree += len + sizeof(size_t);
++	sma_nextfree += len;
+ 
+ 	DBG(sma_allocs++;)
+ 	return (void *)address;
+@@ -208,7 +206,7 @@ void string_free(void * const restrict a
+ 		goto sf_failed;
+ 
+ 	/* Tiny objects keep big ones from being freed; ignore them */
+-	if (*(size_t *)((uintptr_t)addr - sizeof(size_t)) < SMA_MIN_SLACK)
++	if (*(size_t *)((uintptr_t)addr - sizeof(size_t)) < (SMA_MIN_SLACK + sizeof(size_t)))
+ 		goto sf_failed;
+ 
+ 	/* Add object to free list */
+@@ -231,15 +229,14 @@ sf_failed:
+ /* Destroy all allocated pages */
+ void string_malloc_destroy(void)
+ {
+-	void *cur;
++	uintptr_t *cur;
+ 	uintptr_t *next;
+ 
+-	cur = (void *)sma_head;
+-	if (sma_head == NULL) return;
++	cur = sma_head;
+ 	while (sma_pages > 0) {
+-		next = (uintptr_t *)*(uintptr_t *)cur;
++		next = (uintptr_t *)*cur;
+ 		free(cur);
+-		cur = (void *)next;
++		cur = next;
+ 		sma_pages--;
+ 	}
+ 	sma_head = NULL;
diff -Nru jdupes-1.7/debian/patches/series jdupes-1.7/debian/patches/series
--- jdupes-1.7/debian/patches/series	2017-02-06 22:17:30.000000000 -0200
+++ jdupes-1.7/debian/patches/series	2018-11-19 00:10:16.000000000 -0200
@@ -1 +1,2 @@
 10_fix-segfault.patch
+20_fix-crash-arm.patch

Reply to: