Package: cachefilesd
Version: 0.10.10-0.2
Severity: normal
Tags: patch
User: [email protected]
Usertags: origin-ubuntu focal ubuntu-patch

Dear Maintainer,

the build_cull_table() function scans through elements up to 
nr_in_ready_table/nr_in_build_table, and performs actions if a match was found; 
however the match detection logic simply compares the for loop index against 
nr_in_*_table - 1, which underflows when 0, resulting in incorrect if section 
being run and then segfaulting.


In Ubuntu, the attached patch was applied to achieve the following:

  * Avoid counter underflow, leading to segfault (LP: #1854054)


Thanks for considering the patch.


-- System Information:
Debian Release: buster/sid
  APT prefers eoan-updates
  APT policy: (500, 'eoan-updates'), (500, 'eoan-security'), (500, 'eoan'), 
(100, 'eoan-backports')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 5.3.0-23-generic (SMP w/24 CPU cores)
Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US 
(charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
diff -Nru cachefilesd-0.10.10/cachefilesd.c cachefilesd-0.10.10/cachefilesd.c
--- cachefilesd-0.10.10/cachefilesd.c   2019-07-19 10:55:33.000000000 -0400
+++ cachefilesd-0.10.10/cachefilesd.c   2019-11-26 08:09:57.000000000 -0500
@@ -1389,13 +1389,13 @@
                                if (cullready[loop] == child)
                                        break;
 
-                       if (loop == nr_in_ready_table - 1) {
+                       if (loop + 1 == nr_in_ready_table) {
                                /* child was oldest object */
                                cullready[--nr_in_ready_table] = (void 
*)(0x6b000000 | __LINE__);
                                put_object(child);
                                goto removed;
                        }
-                       else if (loop < nr_in_ready_table - 1) {
+                       else if (loop + 1 < nr_in_ready_table) {
                                /* child was somewhere in between */
                                memmove(&cullready[loop],
                                        &cullready[loop + 1],
@@ -1409,12 +1409,12 @@
                                if (cullbuild[loop] == child)
                                        break;
 
-                       if (loop == nr_in_build_table - 1) {
+                       if (loop + 1 == nr_in_build_table) {
                                /* child was oldest object */
                                cullbuild[--nr_in_build_table] = (void 
*)(0x6b000000 | __LINE__);
                                put_object(child);
                        }
-                       else if (loop < nr_in_build_table - 1) {
+                       else if (loop + 1 < nr_in_build_table) {
                                /* child was somewhere in between */
                                memmove(&cullbuild[loop],
                                        &cullbuild[loop + 1],

Reply via email to