Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package busybox for openSUSE:Factory checked 
in at 2026-10-02 23:02:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/busybox (Old)
 and      /work/SRC/openSUSE:Factory/.busybox.new.1631729 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "busybox"

Fri Oct  2 23:02:21 2026 rev:100 rq:1381941 version:1.38.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/busybox/busybox.changes  2026-08-26 
19:51:23.058785158 +0200
+++ /work/SRC/openSUSE:Factory/.busybox.new.1631729/busybox.changes     
2026-10-02 23:02:57.836338968 +0200
@@ -1,0 +2,30 @@
+Thu Oct  1 00:00:00 UTC 2026 - Radoslav Kolev <[email protected]>
+
+- Fix pre-authentication heap buffer overflow in TLS caused by unit
+  confusion in the Montgomery reduction buffer allocation
+  (CVE-2026-88830, bsc#1282575)
+  * 0001-tls-fix-undersized-buffer-calculation.patch
+- Fix httpd silently failing open when IP deny rules contain an
+  invalid CIDR prefix length (CVE-2026-88831, bsc#1282550)
+  * 0001-httpd-fix-handling-of-D-1.2.3-999.patch
+- Fix heap buffer overflow when parsing the volume ID of crafted
+  romfs filesystem images (CVE-2026-88832, bsc#1282576)
+  * 0001-volume_id-romfs-limit-the-maximum-size-of-label-to-V.patch
+- Fix out-of-bounds read in dpkg read_package_field() stepping past
+  the NUL terminator on malformed .deb packages
+  (CVE-2026-88835, bsc#1282551)
+  * 0001-dpkg-free-results-of-read_package_field-preliminary-.patch
+  * 0002-dpkg-reformat-code-in-read_package_field-exposing-wh.patch
+  * 0003-dpkg-fix-cases-where-read_package_field-returns-offs.patch
+- Fix out-of-bounds read and silent corruption of the dpkg status
+  file caused by write_status_file() not resetting the field_start
+  cursor between package stanzas (CVE-2026-88841, bsc#1282653)
+  * 0004-dpkg-fix-field-handling-in-write_status_file.patch
+- Fix httpd misidentifying yescrypt password hashes as plaintext
+  (CVE-2026-88837, bsc#1282552)
+  * 0001-httpd-allow-yescrypt-passwords-y.patch
+- Fix out-of-bounds write of heap pointers in the passwd/group parser
+  due to a stale tokenize() endpoint (CVE-2026-88839, bsc#1282568)
+  * 0001-libpwdgrp-tokenizer-fix-for-trailing-whitespace-remo.patch
+
+-------------------------------------------------------------------

New:
----
  0001-dpkg-free-results-of-read_package_field-preliminary-.patch
  0001-httpd-allow-yescrypt-passwords-y.patch
  0001-httpd-fix-handling-of-D-1.2.3-999.patch
  0001-libpwdgrp-tokenizer-fix-for-trailing-whitespace-remo.patch
  0001-tls-fix-undersized-buffer-calculation.patch
  0001-volume_id-romfs-limit-the-maximum-size-of-label-to-V.patch
  0002-dpkg-reformat-code-in-read_package_field-exposing-wh.patch
  0003-dpkg-fix-cases-where-read_package_field-returns-offs.patch
  0004-dpkg-fix-field-handling-in-write_status_file.patch

----------(New B)----------
  New:  (CVE-2026-88835, bsc#1282551)
  * 0001-dpkg-free-results-of-read_package_field-preliminary-.patch
  * 0002-dpkg-reformat-code-in-read_package_field-exposing-wh.patch
  New:  (CVE-2026-88837, bsc#1282552)
  * 0001-httpd-allow-yescrypt-passwords-y.patch
- Fix out-of-bounds write of heap pointers in the passwd/group parser
  New:  invalid CIDR prefix length (CVE-2026-88831, bsc#1282550)
  * 0001-httpd-fix-handling-of-D-1.2.3-999.patch
- Fix heap buffer overflow when parsing the volume ID of crafted
  New:  due to a stale tokenize() endpoint (CVE-2026-88839, bsc#1282568)
  * 0001-libpwdgrp-tokenizer-fix-for-trailing-whitespace-remo.patch
  New:  (CVE-2026-88830, bsc#1282575)
  * 0001-tls-fix-undersized-buffer-calculation.patch
- Fix httpd silently failing open when IP deny rules contain an
  New:  romfs filesystem images (CVE-2026-88832, bsc#1282576)
  * 0001-volume_id-romfs-limit-the-maximum-size-of-label-to-V.patch
- Fix out-of-bounds read in dpkg read_package_field() stepping past
  New:  * 0001-dpkg-free-results-of-read_package_field-preliminary-.patch
  * 0002-dpkg-reformat-code-in-read_package_field-exposing-wh.patch
  * 0003-dpkg-fix-cases-where-read_package_field-returns-offs.patch
  New:  * 0002-dpkg-reformat-code-in-read_package_field-exposing-wh.patch
  * 0003-dpkg-fix-cases-where-read_package_field-returns-offs.patch
- Fix out-of-bounds read and silent corruption of the dpkg status
  New:  cursor between package stanzas (CVE-2026-88841, bsc#1282653)
  * 0004-dpkg-fix-field-handling-in-write_status_file.patch
- Fix httpd misidentifying yescrypt password hashes as plaintext
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ busybox.spec ++++++
--- /var/tmp/diff_new_pack.OkofVy/_old  2026-10-02 23:02:59.254398320 +0200
+++ /var/tmp/diff_new_pack.OkofVy/_new  2026-10-02 23:02:59.257398445 +0200
@@ -60,6 +60,25 @@
 Patch11:        0001-ash-fix-out-of-bounds-read-in-ifsbreakup.patch
 # PATCH-FIX-UPSTREAM - Fix bsc#1271548 (CVE-2026-38755), stack exhaustion on 
deep ash function recursion
 Patch12:        ash-fix-evalfun.patch
+# PATCH-FIX-UPSTREAM - Fix bsc#1282575 (CVE-2026-88830), undersized buffer in 
TLS Montgomery reduction (upstream commit 89ac82774)
+Patch13:        0001-tls-fix-undersized-buffer-calculation.patch
+# PATCH-FIX-UPSTREAM - Fix bsc#1282550 (CVE-2026-88831), httpd fails open on 
invalid CIDR prefix in deny rules (upstream commit 339e3c62f)
+Patch14:        0001-httpd-fix-handling-of-D-1.2.3-999.patch
+# PATCH-FIX-UPSTREAM - Fix bsc#1282576 (CVE-2026-88832), heap buffer overflow 
in romfs volume ID parsing (upstream commit 9073c1d15)
+Patch15:        0001-volume_id-romfs-limit-the-maximum-size-of-label-to-V.patch
+# We don't really need the 4 dpkg patches below, as building dpkg is disabled 
in the config, but since they are upstream add them just in case
+# PATCH-FIX-UPSTREAM - Prerequisite for the dpkg fixes below (upstream commit 
e2c5cc042)
+Patch16:        0001-dpkg-free-results-of-read_package_field-preliminary-.patch
+# PATCH-FIX-UPSTREAM - Prerequisite for the dpkg fixes below (upstream commit 
43a9d7d31)
+Patch17:        0002-dpkg-reformat-code-in-read_package_field-exposing-wh.patch
+# PATCH-FIX-UPSTREAM - Fix bsc#1282551 (CVE-2026-88835), dpkg 
read_package_field() OOB read past NUL (upstream commit f5a4a02a1)
+Patch18:        0003-dpkg-fix-cases-where-read_package_field-returns-offs.patch
+# PATCH-FIX-UPSTREAM - Fix bsc#1282653 (CVE-2026-88841), dpkg 
write_status_file() OOB read/status file corruption (upstream commit d5cc94063)
+Patch19:        0004-dpkg-fix-field-handling-in-write_status_file.patch
+# PATCH-FIX-UPSTREAM - Fix bsc#1282552 (CVE-2026-88837), httpd misidentifies 
yescrypt hashes as plaintext (upstream commit 9f5cbdcaa)
+Patch20:        0001-httpd-allow-yescrypt-passwords-y.patch
+# PATCH-FIX-UPSTREAM - Fix bsc#1282568 (CVE-2026-88839), passwd/group parser 
OOB write on stale tokenize() endpoint (upstream commit c2dec52d3)
+Patch21:        0001-libpwdgrp-tokenizer-fix-for-trailing-whitespace-remo.patch
 
 # other patches
 Patch100:       busybox.install.patch

++++++ 0001-dpkg-free-results-of-read_package_field-preliminary-.patch ++++++
>From e2c5cc04206008acc82d28dac4fcb1963e8f0acf Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <[email protected]>
Date: Mon, 21 Sep 2026 16:16:47 +0200
Subject: [PATCH] dpkg: free results of read_package_field(), preliminary
 cleanups in read_package_field()

function                                             old     new   delta
dpkg_main                                           3910    3943     +33
write_buffer_no_status                                92     114     +22
read_package_field                                   204     184     -20
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 55/-20)             Total: 35 bytes

Signed-off-by: Denys Vlasenko <[email protected]>
---
 archival/dpkg.c | 80 +++++++++++++++++++++++++++----------------------
 1 file changed, 45 insertions(+), 35 deletions(-)

diff --git a/archival/dpkg.c b/archival/dpkg.c
index eda5ec7eb..4ca1daf9b 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -531,26 +531,31 @@ static void free_package(common_node_t *node)
 }
 
 /*
- * Gets the next package field from package_buffer, separated into the field 
name
- * and field value, it returns the int offset to the first character of the 
next field
+ * Gets the next package field from package_buffer:
+ * "Name:<whitespace>VALUE{\n|NUL}"
+ * "Name:<whitespace>\n
+ * " VALUE{\n|NUL}"
+ * separated into "NAME" and "VALUE", both strdup()ed.
+ * Returns the int offset to the first character of the next field.
+ * The package_buffer parameter is NUL-terminated.
  */
 static int read_package_field(const char *package_buffer, char **field_name, 
char **field_value)
 {
        int offset_name_start = 0;
        int offset_name_end = 0;
        int offset_value_start = 0;
-       int offset_value_end = 0;
        int offset = 0;
        int next_offset;
        int name_length;
        int value_length;
        int exit_flag = FALSE;
 
+       *field_name = NULL;
+       *field_value = NULL;
        if (package_buffer == NULL) {
-               *field_name = NULL;
-               *field_value = NULL;
                return -1;
        }
+
        while (1) {
                next_offset = offset + 1;
                switch (package_buffer[offset]) {
@@ -566,14 +571,14 @@ static int read_package_field(const char *package_buffer, 
char **field_name, cha
                                 * immediately after name */
                                break;
                        case '\n':
-                               /* TODO: The char next_offset may be out of 
bounds */
                                if (package_buffer[next_offset] != ' ') {
                                        exit_flag = TRUE;
                                        break;
                                }
+                               /* fall through */
                        case '\t':
                        case ' ':
-                               /* increment the value start point if its a 
just filler */
+                               /* increment start points if it is just a 
filler */
                                if (offset_name_start == offset) {
                                        offset_name_start++;
                                }
@@ -584,9 +589,8 @@ static int read_package_field(const char *package_buffer, 
char **field_name, cha
                }
                if (exit_flag) {
                        /* Check that the names are valid */
-                       offset_value_end = offset;
                        name_length = offset_name_end - offset_name_start;
-                       value_length = offset_value_end - offset_value_start;
+                       value_length = offset - offset_value_start;
                        if (name_length == 0) {
                                break;
                        }
@@ -594,27 +598,26 @@ static int read_package_field(const char *package_buffer, 
char **field_name, cha
                                break;
                        }
 
-                       /* If not valid, start fresh with next field */
+                       /* Not valid: start fresh with next field */
                        exit_flag = FALSE;
                        offset_name_start = offset + 1;
                        offset_name_end = 0;
                        offset_value_start = offset + 1;
-                       offset_value_end = offset + 1;
                        offset++;
                }
                offset++;
-       }
-       *field_name = NULL;
-       if (name_length) {
+       } /* while (1) */
+
+       if (name_length > 0) {
                *field_name = xstrndup(&package_buffer[offset_name_start], 
name_length);
        }
-       *field_value = NULL;
        if (value_length > 0) {
                *field_value = xstrndup(&package_buffer[offset_value_start], 
value_length);
        }
        return next_offset;
 }
 
+/* The parameter is NUL-terminated */
 static unsigned fill_package_struct(char *control_buffer)
 {
        static const char field_names[] ALIGN1 =
@@ -623,14 +626,14 @@ static unsigned fill_package_struct(char *control_buffer)
                "Conflicts\0""Suggests\0""Recommends\0""Enhances\0";
 
        common_node_t *new_node = xzalloc(sizeof(common_node_t));
-       char *field_name;
-       char *field_value;
        int field_start = 0;
-       int num = -1;
        int buffer_length = strlen(control_buffer);
+       int num;
 
        new_node->version = search_name_hashtable("unknown");
        while (field_start < buffer_length) {
+               char *field_name;
+               char *field_value;
                unsigned field_num;
 
                field_start += read_package_field(&control_buffer[field_start],
@@ -799,7 +802,7 @@ static void write_buffer_no_status(FILE *new_status_file, 
const char *control_bu
        char *name;
        char *value;
        int start = 0;
-       while (1) {
+       while (control_buffer[start]) {
                start += read_package_field(&control_buffer[start], &name, 
&value);
                if (name == NULL) {
                        break;
@@ -807,6 +810,8 @@ static void write_buffer_no_status(FILE *new_status_file, 
const char *control_bu
                if (strcmp(name, "Status") != 0) {
                        fprintf(new_status_file, "%s: %s\n", name, value);
                }
+               free(name);
+               free(value);
        }
 }
 
@@ -815,34 +820,35 @@ static void write_status_file(deb_file_t **deb_file)
 {
        FILE *old_status_file = xfopen_for_read("/var/lib/dpkg/status");
        FILE *new_status_file = xfopen_for_write("/var/lib/dpkg/status.udeb");
-       char *package_name;
-       char *status_from_file;
-       char *control_buffer = NULL;
-       char *tmp_string;
-       int status_num;
+       char *control_buffer;
        int field_start = 0;
-       int write_flag;
-       int i = 0;
+       int status_num;
+       int i;
 
        /* Update previously known packages */
        while ((control_buffer = xmalloc_fgetline_str(old_status_file, "\n\n")) 
!= NULL) {
+               char *package_name;
+               char *status_from_file;
+               char *tmp_string;
+               int write_flag;
+//FIXME: "int field_start = 0;" should be _here_, right?
+
                tmp_string = strstr(control_buffer, "Package:");
                if (tmp_string == NULL) {
+                       free(control_buffer);
                        continue;
                }
-
                tmp_string += 8;
                tmp_string += strspn(tmp_string, " \n\t");
                package_name = xstrndup(tmp_string, strcspn(tmp_string, "\n"));
+
                write_flag = FALSE;
+               status_from_file = NULL;
                tmp_string = strstr(control_buffer, "Status:");
                if (tmp_string != NULL) {
-                       /* Separate the status value from the control buffer */
                        tmp_string += 7;
                        tmp_string += strspn(tmp_string, " \n\t");
                        status_from_file = xstrndup(tmp_string, 
strcspn(tmp_string, "\n"));
-               } else {
-                       status_from_file = NULL;
                }
 
                /* Find this package in the status hashtable */
@@ -870,7 +876,7 @@ static void write_status_file(deb_file_t **deb_file)
                                                }
                                                i++;
                                        }
-                                       /* This is temperary, debugging only */
+                                       /* This is temporary, debugging only */
                                        if (deb_file[i] == NULL) {
                                                bb_error_msg_and_die("ALERT: 
cannot find a control file, "
                                                        "your status file may 
be broken, status may be "
@@ -882,7 +888,7 @@ static void write_status_file(deb_file_t **deb_file)
                                        fprintf(new_status_file, "Package: 
%s\n", package_name);
                                        fprintf(new_status_file, "Status: 
%s\n", status_from_hashtable);
 
-                                       while (1) {
+                                       while (control_buffer[field_start]) {
                                                char *field_name;
                                                char *field_value;
                                                field_start += 
read_package_field(&control_buffer[field_start], &field_name, &field_value);
@@ -894,13 +900,15 @@ static void write_status_file(deb_file_t **deb_file)
                                                ) {
                                                        
fprintf(new_status_file, "%s: %s\n", field_name, field_value);
                                                }
+                                               free(field_name);
+                                               free(field_value);
                                        }
                                        write_flag = TRUE;
                                        fputs("\n", new_status_file);
                                }
                                else if (strcmp("config-files", 
name_hashtable[state_status]) == 0) {
                                        /* only change the status line */
-                                       while (1) {
+                                       while (control_buffer[field_start]) {
                                                char *field_name;
                                                char *field_value;
                                                field_start += 
read_package_field(&control_buffer[field_start], &field_name, &field_value);
@@ -913,13 +921,15 @@ static void write_status_file(deb_file_t **deb_file)
                                                } else {
                                                        
fprintf(new_status_file, "%s: %s\n", field_name, field_value);
                                                }
+                                               free(field_name);
+                                               free(field_value);
                                        }
                                        write_flag = TRUE;
                                        fputs("\n", new_status_file);
                                }
                        }
                }
-               /* If the package from the status file wasn't handle above, do 
it now*/
+               /* If the package from the status file wasn't handled above, do 
it now */
                if (!write_flag) {
                        fprintf(new_status_file, "%s\n\n", control_buffer);
                }
@@ -927,7 +937,7 @@ static void write_status_file(deb_file_t **deb_file)
                free(status_from_file);
                free(package_name);
                free(control_buffer);
-       }
+       } /* while (control_buffer) */
 
        /* Write any new packages */
        for (i = 0; deb_file[i] != NULL; i++) {

++++++ 0001-httpd-allow-yescrypt-passwords-y.patch ++++++
>From 9f5cbdcaa5972d58503c59cd0da13da1e5bb272b Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <[email protected]>
Date: Tue, 22 Sep 2026 01:14:47 +0200
Subject: [PATCH] httpd: allow yescrypt passwords ("$y$....")

function                                             old     new   delta
check_user_passwd                                    439     444      +5

Signed-off-by: Denys Vlasenko <[email protected]>
---
 loginutils/Config.src | 2 +-
 networking/httpd.c    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/loginutils/Config.src b/loginutils/Config.src
index a7812bd32..5559992da 100644
--- a/loginutils/Config.src
+++ b/loginutils/Config.src
@@ -96,7 +96,7 @@ config USE_BB_CRYPT_YES
        default y
        depends on USE_BB_CRYPT
        help
-       Enable this if you have passwords starting with "$y$" or
+       Enable this if you have passwords starting with "$y$"
        in your /etc/passwd or /etc/shadow files. These passwords
        are hashed using yescrypt algorithms.
        With this option off, login will fail password check for any
diff --git a/networking/httpd.c b/networking/httpd.c
index a5dfb38af..842574e0e 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -2247,7 +2247,7 @@ static int check_user_passwd(const char *path, char 
*user_and_passwd)
                        }
                        /* Else: passwd is from httpd.conf, it is either 
plaintext or encrypted */
 
-                       if (passwd[0] == '$' && isdigit(passwd[1])) {
+                       if (passwd[0] == '$' && (isdigit(passwd[1]) || 
passwd[1] == 'y')) {
                                char *encrypted;
 # if !ENABLE_PAM
  check_encrypted:

++++++ 0001-httpd-fix-handling-of-D-1.2.3-999.patch ++++++
>From 339e3c62f5bcf252839c8abca5325f48a22f21aa Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <[email protected]>
Date: Mon, 21 Sep 2026 04:40:37 +0200
Subject: [PATCH] httpd: fix handling of "D:1.2.3/999"

An error in allow/deny rule should be interpreted as D:0/0
("deny all") but was interpreted as D:IP/0. Fix this.

function                                             old     new   delta
parse_conf                                          1323    1330      +7

Signed-off-by: Denys Vlasenko <[email protected]>
---
 networking/httpd.c | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/networking/httpd.c b/networking/httpd.c
index ad59493d7..bc446a838 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -41,7 +41,7 @@
  * H:/serverroot     # define the server root. It will override -h
  * A:172.20.         # Allow address from 172.20.0.0/16
  * A:10.0.0.0/25     # Allow any address from 10.0.0.0-10.0.0.127
- * A:10.0.0.0/255.255.255.128  # Allow any address that previous set
+ * A:10.0.0.0/255.255.255.128  # Same as the previous
  * A:127.0.0.1       # Allow local loopback connections
  * D:*               # Deny from other IP connections
  * E404:/path/e404.html # /path/e404.html is the 404 (not found) error page
@@ -63,7 +63,7 @@
  * Deny/Allow IP logic:
  *  - Default is to allow all (Allow all (A:*) is a no-op).
  *  - Deny rules take precedence over allow rules.
- *  - "Deny all" rule (D:*) is applied last.
+ *  - However, "Deny all" rule (D:*) is applied last.
  *
  * Example:
  *   1. Allow only specified addresses
@@ -381,8 +381,8 @@ typedef struct Htaccess {
 /* Must have "next" as a first member */
 typedef struct Htaccess_IP {
        struct Htaccess_IP *next;
-       unsigned ip;
-       unsigned mask;
+       uint32_t ip;   /* host-endian */
+       uint32_t mask; /* host-endian */
        int allow_deny;
 } Htaccess_IP;
 #endif
@@ -653,11 +653,11 @@ static ALWAYS_INLINE void 
free_Htaccess_IP_list(Htaccess_IP **pptr)
 #if ENABLE_FEATURE_HTTPD_ACL_IP
 /* Returns presumed mask width in bits or < 0 on error.
  * Updates strp, stores IP at provided pointer */
-static int scan_ip(const char **strp, unsigned *ipp, unsigned char endc)
+static int scan_ip(const char **strp, uint32_t *ipp, unsigned char endc)
 {
        const char *p = *strp;
        int auto_mask = 8;
-       unsigned ip = 0;
+       uint32_t ip = 0;
        int j;
 
        if (*p == '/')
@@ -695,10 +695,10 @@ static int scan_ip(const char **strp, unsigned *ipp, 
unsigned char endc)
 }
 
 /* Returns 0 on success. Stores IP and mask at provided pointers */
-static int scan_ip_mask(const char *str, unsigned *ipp, unsigned *maskp)
+static int scan_ip_mask(const char *str, uint32_t *ipp, uint32_t *maskp)
 {
        int i;
-       unsigned mask;
+       uint32_t mask;
        char *p;
 
        i = scan_ip(&str, ipp, '/');
@@ -713,15 +713,16 @@ static int scan_ip_mask(const char *str, unsigned *ipp, 
unsigned *maskp)
                        /* (return 0 (success) only if it has N.N.N.N form) */
                        return scan_ip(&str, maskp, '\0') - 32;
                }
-               if (*p)
+               if (*p) /* 'xxx' had something apart from just digits */
                        return -1;
        }
+       //else: i = "automask" (the count of explicit IP components: "10.0[.]" 
= 16)
 
        if (i > 32)
                return -1;
 
-       if (sizeof(unsigned) == 4 && i == 32) {
-               /* mask >>= 32 below may not work */
+       if (i == 32) {
+               /* mask >>= 32 below may not work (according to C standard) */
                mask = 0;
        } else {
                mask = 0xffffffff;
@@ -890,15 +891,18 @@ static int parse_conf(const char *path, int flag)
                        if (scan_ip_mask(after_colon, &pip->ip, &pip->mask)) {
                                /* IP{/mask} syntax error detected, protect all 
*/
                                ch = 'D';
+                               //bb_error_msg("ERR");
+                               pip->ip = 0; /* could be set before error is 
detected - zero it (again) */
                                pip->mask = 0;
                        }
+                       //bb_error_msg_and_die("ip:0x%08x mask:0x%08x", 
pip->ip, pip->mask);
                        pip->allow_deny = ch;
                        if (ch == 'D') {
                                /* Deny:from_IP - prepend */
                                pip->next = G.ip_a_d;
                                G.ip_a_d = pip;
                        } else {
-                               /* A:from_IP - append (thus all D's precedes 
A's) */
+                               /* A:from_IP - append (thus all D's precede 
A's) */
                                Htaccess_IP *prev_IP = G.ip_a_d;
                                if (prev_IP == NULL) {
                                        G.ip_a_d = pip;
@@ -2045,7 +2049,7 @@ static NOINLINE void send_file_and_exit(const char *url, 
int what)
 }
 
 #if ENABLE_FEATURE_HTTPD_ACL_IP
-static void if_ip_denied_send_HTTP_FORBIDDEN_and_exit(unsigned remote_ip)
+static void if_ip_denied_send_HTTP_FORBIDDEN_and_exit(uint32_t remote_ip)
 {
        Htaccess_IP *cur;
 
@@ -2337,7 +2341,7 @@ static void handle_incoming_and_exit(const 
len_and_sockaddr *fromAddr)
        char *urlp;
        char *tptr;
 #if ENABLE_FEATURE_HTTPD_ACL_IP
-       unsigned remote_ip;
+       uint32_t remote_ip;
 #endif
 #if ENABLE_FEATURE_HTTPD_CGI
        unsigned total_headers_len;

++++++ 0001-libpwdgrp-tokenizer-fix-for-trailing-whitespace-remo.patch ++++++
>From c2dec52d37380d27d89827cf01a770f6b3b04e3a Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <[email protected]>
Date: Tue, 22 Sep 2026 02:19:06 +0200
Subject: [PATCH] libpwdgrp: tokenizer fix for trailing whitespace removeal.

The tokenize() function trims trailing whitespace via
overlapping_strcpy() but continues to reference the stale *end
pointer. Fixing this.

function                                             old     new   delta
tokenize                                             120     119      -1

Signed-off-by: Denys Vlasenko <[email protected]>
---
 libpwdgrp/pwd_grp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libpwdgrp/pwd_grp.c b/libpwdgrp/pwd_grp.c
index 10debbcdb..48a49fc24 100644
--- a/libpwdgrp/pwd_grp.c
+++ b/libpwdgrp/pwd_grp.c
@@ -171,7 +171,7 @@ static int tokenize(char *buffer, int ch)
                        if (p != end)
                                overlapping_strcpy(p, end);
                        num_fields++;
-                       if (*end == '\0') {
+                       if (*p == '\0') {
                                S.tokenize_end = p + 1;
                                return num_fields;
                        }

++++++ 0001-tls-fix-undersized-buffer-calculation.patch ++++++
>From 89ac82774f90e270d04ed5299e5cf05dfbc314c1 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <[email protected]>
Date: Mon, 21 Sep 2026 03:19:28 +0200
Subject: [PATCH] tls: fix undersized buffer calculation

All callers of pstm_montgomery_reduce() are currently in pstm_exptmod()
and they all pass a preallocated temporary buffer, so the incorrect code
is unreachable. But fix it anyway.

function                                             old     new   delta
pstm_montgomery_reduce                               431     430      -1

Signed-off-by: Denys Vlasenko <[email protected]>
---
 networking/tls_pstm_montgomery_reduce.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/networking/tls_pstm_montgomery_reduce.c 
b/networking/tls_pstm_montgomery_reduce.c
index e63e590db..36882425a 100644
--- a/networking/tls_pstm_montgomery_reduce.c
+++ b/networking/tls_pstm_montgomery_reduce.c
@@ -370,6 +370,7 @@ int32 FAST_FUNC pstm_montgomery_reduce(psPool_t *pool, 
pstm_int *a, pstm_int *m,
        pstm_digit      *c, *_c, *tmpm, mu;
        int32           oldused, x, y;
        int             pa; //bbox: was int16
+       uint32          cSize;
 
        pa = m->used;
        if (pa > a->alloc) {
@@ -377,11 +378,13 @@ int32 FAST_FUNC pstm_montgomery_reduce(psPool_t *pool, 
pstm_int *a, pstm_int *m,
                return PS_LIMIT_FAIL;
        }
 
-       if (paD && paDlen >= (uint32)2*pa+1) {
+       cSize = (2 * pa + 1) * sizeof(pstm_digit);
+       if (paD && paDlen >= cSize) {
                c = paD;
                memset(c, 0x0, paDlen);
        } else {
-               c = xzalloc(2*pa+1);//bbox
+               //bbox: dead code, all callers always pass paD:
+               c = xzalloc(cSize); //bbox
        }
        /* copy the input */
        oldused = a->used;
@@ -441,7 +444,8 @@ int32 FAST_FUNC pstm_montgomery_reduce(psPool_t *pool, 
pstm_int *a, pstm_int *m,
                        x = PS_MEM_FAIL;
                }
        }
-       if (paDlen < (uint32)2*pa+1) {
+       //bbox: dead code, all callers always pass paD:
+       if (c != paD) {
                psFree(c, pool);
        }
        return x;

++++++ 0001-volume_id-romfs-limit-the-maximum-size-of-label-to-V.patch ++++++
>From 9073c1d15c9953c6f1e39145815fc5dccfa6081c Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <[email protected]>
Date: Mon, 21 Sep 2026 05:34:19 +0200
Subject: [PATCH] volume_id/romfs: limit the maximum size of label to
 VOLUME_ID_LABEL_SIZE

function                                             old     new   delta
volume_id_set_label_string                            71      81     +10
volume_id_probe_romfs                                 94      97      +3
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 13/0)               Total: 13 bytes

Signed-off-by: Denys Vlasenko <[email protected]>
---
 util-linux/volume_id/romfs.c | 4 ++--
 util-linux/volume_id/util.c  | 4 ++++
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/util-linux/volume_id/romfs.c b/util-linux/volume_id/romfs.c
index bd74fda8d..475144c43 100644
--- a/util-linux/volume_id/romfs.c
+++ b/util-linux/volume_id/romfs.c
@@ -44,8 +44,8 @@ int FAST_FUNC volume_id_probe_romfs(struct volume_id *id 
/*,uint64_t off*/)
        if (rfs == NULL)
                return -1;
 
-       if (memcmp(rfs->magic, "-rom1fs-", 4) == 0) {
-               size_t len = strlen((char *)rfs->name);
+       if (memcmp(rfs->magic, "-rom1fs-", 8) == 0) {
+               size_t len = strnlen((char *)rfs->name, VOLUME_ID_LABEL_SIZE);
 
                if (len) {
 //                     volume_id_set_label_raw(id, rfs->name, len);
diff --git a/util-linux/volume_id/util.c b/util-linux/volume_id/util.c
index b59aa99b2..a2bee28ab 100644
--- a/util-linux/volume_id/util.c
+++ b/util-linux/volume_id/util.c
@@ -116,6 +116,10 @@ void volume_id_set_label_string(struct volume_id *id, 
const uint8_t *buf, size_t
 {
        unsigned i;
 
+       /* Do not overflow label[VOLUME_ID_LABEL_SIZE+1] */
+       if (count > VOLUME_ID_LABEL_SIZE)
+               count = VOLUME_ID_LABEL_SIZE;
+
        memcpy(id->label, buf, count);
 
        /* remove trailing whitespace */

++++++ 0002-dpkg-reformat-code-in-read_package_field-exposing-wh.patch ++++++
>From 43a9d7d31560ad4e9d6a341207b1aa191cb9b0db Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <[email protected]>
Date: Mon, 21 Sep 2026 16:32:43 +0200
Subject: [PATCH] dpkg: reformat code in read_package_field(), exposing why
 it's buggy

function                                             old     new   delta
read_package_field                                   184     169     -15

Signed-off-by: Denys Vlasenko <[email protected]>
---
 archival/dpkg.c | 56 +++++++++++++++++++------------------------------
 1 file changed, 22 insertions(+), 34 deletions(-)

diff --git a/archival/dpkg.c b/archival/dpkg.c
index 4ca1daf9b..860256f0e 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -548,20 +548,13 @@ static int read_package_field(const char *package_buffer, 
char **field_name, cha
        int next_offset;
        int name_length;
        int value_length;
-       int exit_flag = FALSE;
 
        *field_name = NULL;
        *field_value = NULL;
-       if (package_buffer == NULL) {
-               return -1;
-       }
 
        while (1) {
                next_offset = offset + 1;
                switch (package_buffer[offset]) {
-                       case '\0':
-                               exit_flag = TRUE;
-                               break;
                        case ':':
                                if (offset_name_end == 0) {
                                        offset_name_end = offset;
@@ -572,8 +565,7 @@ static int read_package_field(const char *package_buffer, 
char **field_name, cha
                                break;
                        case '\n':
                                if (package_buffer[next_offset] != ' ') {
-                                       exit_flag = TRUE;
-                                       break;
+                                       goto end_of_value;
                                }
                                /* fall through */
                        case '\t':
@@ -586,35 +578,31 @@ static int read_package_field(const char *package_buffer, 
char **field_name, cha
                                        offset_value_start++;
                                }
                                break;
-               }
-               if (exit_flag) {
-                       /* Check that the names are valid */
-                       name_length = offset_name_end - offset_name_start;
-                       value_length = offset - offset_value_start;
-                       if (name_length == 0) {
-                               break;
-                       }
-                       if ((name_length > 0) && (value_length > 0)) {
+                       case '\0':
+ end_of_value:
+                               /* Check that the names are valid */
+                               name_length = offset_name_end - 
offset_name_start;
+                               value_length = offset - offset_value_start;
+                               if ((name_length > 0) && (value_length > 0)) {
+                                       if (name_length > 0) {
+                                               *field_name = 
xstrndup(&package_buffer[offset_name_start], name_length);
+                                       }
+                                       if (value_length > 0) {
+                                               *field_value = 
xstrndup(&package_buffer[offset_value_start], value_length);
+                                       }
+                                       return next_offset;
+                               }
+                               if (!package_buffer[offset])
+                                       return next_offset; //BUG! past NUL
+                               /* Not valid: start fresh with next field */
+                               offset_name_start = offset + 1;
+                               offset_name_end = 0;
+                               offset_value_start = offset + 1;
+                               offset++; //BUG?
                                break;
-                       }
-
-                       /* Not valid: start fresh with next field */
-                       exit_flag = FALSE;
-                       offset_name_start = offset + 1;
-                       offset_name_end = 0;
-                       offset_value_start = offset + 1;
-                       offset++;
                }
                offset++;
        } /* while (1) */
-
-       if (name_length > 0) {
-               *field_name = xstrndup(&package_buffer[offset_name_start], 
name_length);
-       }
-       if (value_length > 0) {
-               *field_value = xstrndup(&package_buffer[offset_value_start], 
value_length);
-       }
-       return next_offset;
 }
 
 /* The parameter is NUL-terminated */

++++++ 0003-dpkg-fix-cases-where-read_package_field-returns-offs.patch ++++++
>From f5a4a02a157e250d28976e2ba4ea61a2fa7eb51f Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <[email protected]>
Date: Mon, 21 Sep 2026 16:59:56 +0200
Subject: [PATCH] dpkg: fix cases where read_package_field() returns offset
 past NUL

function                                             old     new   delta
read_package_field                                   169     211     +42

Signed-off-by: Denys Vlasenko <[email protected]>
---
 archival/dpkg.c | 63 +++++++++++++++++++++++--------------------------
 1 file changed, 30 insertions(+), 33 deletions(-)

diff --git a/archival/dpkg.c b/archival/dpkg.c
index 860256f0e..b8d8eb648 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -532,8 +532,8 @@ static void free_package(common_node_t *node)
 
 /*
  * Gets the next package field from package_buffer:
- * "Name:<whitespace>VALUE{\n|NUL}"
- * "Name:<whitespace>\n
+ * "<whitespace>Name:<whitespace>VALUE{\n|NUL}"
+ * "<whitespace>Name:<whitespace>\n
  * " VALUE{\n|NUL}"
  * separated into "NAME" and "VALUE", both strdup()ed.
  * Returns the int offset to the first character of the next field.
@@ -541,64 +541,61 @@ static void free_package(common_node_t *node)
  */
 static int read_package_field(const char *package_buffer, char **field_name, 
char **field_value)
 {
-       int offset_name_start = 0;
-       int offset_name_end = 0;
-       int offset_value_start = 0;
-       int offset = 0;
-       int next_offset;
-       int name_length;
-       int value_length;
+       int offset_name_start;
+       int offset_name_end;
+       int offset_value_start = offset_value_start;
+       int offset;
 
        *field_name = NULL;
        *field_value = NULL;
 
+       offset = 0;
+       offset_name_start = 0;
+       offset_name_end = 0; /* "we did not see ':' yet" */
        while (1) {
-               next_offset = offset + 1;
-               switch (package_buffer[offset]) {
+               char ch = package_buffer[offset];
+               switch (ch) {
                        case ':':
                                if (offset_name_end == 0) {
-                                       offset_name_end = offset;
-                                       offset_value_start = next_offset;
+                                       offset_name_end = offset + 1; /* points 
AFTER ':' - think of empty NAME case */
+                                       offset_value_start = offset + 1;
                                }
-                               /* TODO: Name might still have trailing spaces 
if ':' isn't
+                               /* TODO: NAME might still have trailing spaces 
if ':' isn't
                                 * immediately after name */
                                break;
                        case '\n':
-                               if (package_buffer[next_offset] != ' ') {
+                               if (package_buffer[offset + 1] != ' ')
                                        goto end_of_value;
-                               }
                                /* fall through */
                        case '\t':
                        case ' ':
                                /* increment start points if it is just a 
filler */
-                               if (offset_name_start == offset) {
+                               if (offset_name_start == offset)
                                        offset_name_start++;
-                               }
-                               if (offset_value_start == offset) {
+                               if (offset_value_start == offset)
                                        offset_value_start++;
-                               }
                                break;
                        case '\0':
  end_of_value:
-                               /* Check that the names are valid */
-                               name_length = offset_name_end - 
offset_name_start;
-                               value_length = offset - offset_value_start;
-                               if ((name_length > 0) && (value_length > 0)) {
-                                       if (name_length > 0) {
+                               /* Did we see the ':'? */
+                               if (offset_name_end != 0) {
+                                       /* Yes. Check that NAME and VALUE exist 
and not empty */
+                                       int name_length = (offset_name_end - 1) 
- offset_name_start;
+                                       int value_length = offset - 
offset_value_start;
+                                       if ((name_length > 0) && (value_length 
> 0)) {
                                                *field_name = 
xstrndup(&package_buffer[offset_name_start], name_length);
-                                       }
-                                       if (value_length > 0) {
                                                *field_value = 
xstrndup(&package_buffer[offset_value_start], value_length);
+                                               if (ch)
+                                                       offset++; /* skip '\n' 
*/
+                                               return offset;
                                        }
-                                       return next_offset;
                                }
-                               if (!package_buffer[offset])
-                                       return next_offset; //BUG! past NUL
+                               if (!ch)
+                                       return offset; /* stop at NUL */
+
                                /* Not valid: start fresh with next field */
                                offset_name_start = offset + 1;
-                               offset_name_end = 0;
-                               offset_value_start = offset + 1;
-                               offset++; //BUG?
+                               offset_name_end = 0; /* "we did not see ':' 
yet" */
                                break;
                }
                offset++;

++++++ 0004-dpkg-fix-field-handling-in-write_status_file.patch ++++++
>From d5cc94063b2bb5b54fe1021e54600cbcbce6a350 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <[email protected]>
Date: Tue, 22 Sep 2026 01:04:32 +0200
Subject: [PATCH] dpkg: fix field handling in write_status_file()

function                                             old     new   delta
dpkg_main                                           3943    3934      -9

Signed-off-by: Denys Vlasenko <[email protected]>
---
[Backport note: dropped the upstream comment-only hunk that renames
"Name" to "NAME" in the read_package_field() description, as it depends
on the unrelated variable-renaming commit 7c611860d.]
---
 archival/dpkg.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/archival/dpkg.c b/archival/dpkg.c
index 3abc810c8..6a65f16a4 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -809,7 +809,6 @@ static void write_status_file(deb_file_t **deb_file)
        FILE *old_status_file = xfopen_for_read("/var/lib/dpkg/status");
        FILE *new_status_file = xfopen_for_write("/var/lib/dpkg/status.udeb");
        char *control_buffer;
-       int field_start = 0;
        int status_num;
        int i;
 
@@ -819,23 +818,20 @@ static void write_status_file(deb_file_t **deb_file)
                char *status_from_file;
                char *tmp_string;
                int write_flag;
-//FIXME: "int field_start = 0;" should be _here_, right?
 
                tmp_string = strstr(control_buffer, "Package:");
                if (tmp_string == NULL) {
                        free(control_buffer);
                        continue;
                }
-               tmp_string += 8;
-               tmp_string += strspn(tmp_string, " \n\t");
+               tmp_string = skip_whitespace(tmp_string + 8);
                package_name = xstrndup(tmp_string, strcspn(tmp_string, "\n"));
 
                write_flag = FALSE;
                status_from_file = NULL;
                tmp_string = strstr(control_buffer, "Status:");
                if (tmp_string != NULL) {
-                       tmp_string += 7;
-                       tmp_string += strspn(tmp_string, " \n\t");
+                       tmp_string = skip_whitespace(tmp_string + 7);
                        status_from_file = xstrndup(tmp_string, 
strcspn(tmp_string, "\n"));
                }
 
@@ -872,6 +868,8 @@ static void write_status_file(deb_file_t **deb_file)
                                        }
                                }
                                else if (strcmp("not-installed", 
name_hashtable[state_status]) == 0) {
+                                       int field_start = 0;
+
                                        /* Only write the Package, Status, 
Priority and Section lines */
                                        fprintf(new_status_file, "Package: 
%s\n", package_name);
                                        fprintf(new_status_file, "Status: 
%s\n", status_from_hashtable);
@@ -880,6 +878,8 @@ static void write_status_file(deb_file_t **deb_file)
                                                char *field_name;
                                                char *field_value;
                                                field_start += 
read_package_field(&control_buffer[field_start], &field_name, &field_value);
+//FIXME: the questionable ": VALUE" lines (empty NAME)
+//probably should not stop parsing of the entire file?
                                                if (field_name == NULL) {
                                                        break;
                                                }
@@ -895,6 +895,8 @@ static void write_status_file(deb_file_t **deb_file)
                                        fputs("\n", new_status_file);
                                }
                                else if (strcmp("config-files", 
name_hashtable[state_status]) == 0) {
+                                       int field_start = 0;
+
                                        /* only change the status line */
                                        while (control_buffer[field_start]) {
                                                char *field_name;

Reply via email to