[Git][debian-proftpd-team/proftpd][bullseye] CVE-2026-42167 for proftp 1.3.7a.

Hilmar Preuße (@hilmar) gitlab at salsa.debian.org
Wed Apr 29 21:45:09 BST 2026



Hilmar Preuße pushed to branch bullseye at Debian ProFTPD Team / proftpd


Commits:
fbc39c8f by Hilmar Preuße at 2026-04-29T22:44:57+02:00
CVE-2026-42167 for proftp 1.3.7a.

- - - - -


3 changed files:

- debian/changelog
- + debian/patches/2052_pghmcfc.diff
- debian/patches/series


Changes:

=====================================
debian/changelog
=====================================
@@ -1,3 +1,9 @@
+proftpd-dfsg (1.3.7a+dfsg-12+deb11u6) UNRELEASED; urgency=medium
+
+  * Add patch for CVE-2026-42167 (Closes: #1135119).
+
+ -- Hilmar Preuße <hille42 at debian.org>  Wed, 29 Apr 2026 22:43:03 +0200
+
 proftpd-dfsg (1.3.7a+dfsg-12+deb11u5) bullseye-security; urgency=high
 
   * LTS Team upload


=====================================
debian/patches/2052_pghmcfc.diff
=====================================
@@ -0,0 +1,184 @@
+From 415395b795436ae47cc25b2394e80033b80f11be Mon Sep 17 00:00:00 2001
+From: TJ Saunders <tj at castaglia.org>
+Date: Mon, 27 Apr 2026 12:13:09 -0700
+Subject: [PATCH] Issue #2052: When resolving any variable whose value is
+ supplied by the client, make sure we **always** escape that value text.
+
+---
+ contrib/mod_sql.c | 103 ++++++++++++++++++++++++++++------------------
+ 1 file changed, 64 insertions(+), 39 deletions(-)
+
+--- proftpd.orig/contrib/mod_sql.c
++++ proftpd/contrib/mod_sql.c
+@@ -753,40 +753,46 @@
+ }
+ 
+ static int sql_resolved_append_text(pool *p, struct sql_resolved *resolved,
+-    const char *text, size_t text_len) {
+-  char *new_text;
+-  size_t new_textlen;
++    const char *text, size_t text_len, int already_escaped) {
++  char *new_text = NULL;
++  size_t new_textlen = 0;
+ 
+   if (text == NULL ||
+       text_len == 0) {
+     return 0;
+   }
+ 
+-  /* For backward compatibility (see Issue #1149), we indulge in a little
+-   * heuristic here, and only escape the text if it hasn't already been
+-   * escaped.  How to properly tell?  If the first and last characters of
+-   * the given text are `'`, AND there are no other occurrences of that
+-   * character in the text, assume it has already been quoted.
+-   */
+-  if (is_escaped_text(text, text_len) == FALSE) {
+-    modret_t *mr;
++  new_text = (char *) text;
++  new_textlen = text_len;
+ 
+-    mr = sql_dispatch(sql_make_cmd(p, 2, resolved->conn_name, text),
+-      "sql_escapestring");
+-    if (check_response(mr, resolved->conn_flags) < 0) {
+-      errno = EIO;
+-      return -1;
+-    }
++  if (already_escaped == FALSE) {
++    /* For backward compatibility (see Issue #1149), we indulge in a little
++     * heuristic here, and only escape the text if it hasn't already been
++     * escaped.  How to properly tell?  If the first and last characters of
++     * the given text are `'`, AND there are no other occurrences of that
++     * character in the text, assume it has already been quoted.
++     *
++     * Per Issue #2052, we refine this to use this heuristic only if we do
++     * not already know that the text has been escaped.  Some callers may
++     * have already escaped the provided text for us.
++     */
++    if (is_escaped_text(text, text_len) == FALSE) {
++      modret_t *mr;
+ 
+-    new_text = (char *) mr->data;
+-    new_textlen = strlen(new_text);
++      mr = sql_dispatch(sql_make_cmd(p, 2, resolved->conn_name, text),
++        "sql_escapestring");
++      if (check_response(mr, resolved->conn_flags) < 0) {
++        errno = EIO;
++        return -1;
++      }
+ 
+-  } else {
+-    pr_trace_msg(trace_channel, 17,
+-      "text '%s' is already escaped, skipping escaping it again", text);
++      new_text = (char *) mr->data;
++      new_textlen = strlen(new_text);
+ 
+-    new_text = (char *) text;
+-    new_textlen = text_len;
++    } else {
++      pr_trace_msg(trace_channel, 17,
++        "text '%s' is already escaped, skipping escaping it again", text);
++    }
+   }
+ 
+   if (new_textlen > resolved->buflen) {
+@@ -804,7 +810,7 @@
+ 
+ static int sql_resolve_on_meta(pool *p, pr_jot_ctx_t *jot_ctx,
+     unsigned char logfmt_id, const char *jot_hint, const void *val) {
+-  int res = 0;
++  int res = 0, already_escaped = FALSE;
+   struct sql_resolved *resolved;
+ 
+   resolved = jot_ctx->log;
+@@ -963,35 +969,53 @@
+         break;
+       }
+ 
++      /* Per Issue #2052, the following variable values can all be supplied
++       * remotely by the client.  As such, they should be escaped preemptively.
++       */
+       case LOGFMT_META_ANON_PASS:
+       case LOGFMT_META_BASENAME:
+-      case LOGFMT_META_CLASS:
+       case LOGFMT_META_CMD_PARAMS:
+       case LOGFMT_META_COMMAND:
+       case LOGFMT_META_DIR_NAME:
+       case LOGFMT_META_DIR_PATH:
++      case LOGFMT_META_FILENAME:
++      case LOGFMT_META_IDENT_USER:
++      case LOGFMT_META_METHOD:
++      case LOGFMT_META_ORIGINAL_USER:
++      case LOGFMT_META_RESPONSE_STR:
++      case LOGFMT_META_REMOTE_HOST:
++      case LOGFMT_META_RENAME_FROM:
++      case LOGFMT_META_USER:
++      case LOGFMT_META_XFER_PATH: {
++        modret_t *mr;
++
++        mr = sql_dispatch(sql_make_cmd(p, 2, resolved->conn_name,
++          (const char *) val), "sql_escapestring");
++        if (check_response(mr, resolved->conn_flags) < 0) {
++          errno = EIO;
++          return -1;
++        }
++
++        text = (char *) mr->data;
++        text_len = strlen(text);
++        already_escaped = TRUE;
++        break;
++      }
++
++      case LOGFMT_META_CLASS:
+       case LOGFMT_META_ENV_VAR:
+       case LOGFMT_META_EOS_REASON:
+-      case LOGFMT_META_FILENAME:
+       case LOGFMT_META_GROUP:
+-      case LOGFMT_META_IDENT_USER:
+       case LOGFMT_META_ISO8601:
+       case LOGFMT_META_LOCAL_FQDN:
+       case LOGFMT_META_LOCAL_IP:
+       case LOGFMT_META_LOCAL_NAME:
+-      case LOGFMT_META_METHOD:
+       case LOGFMT_META_NOTE_VAR:
+-      case LOGFMT_META_ORIGINAL_USER:
+       case LOGFMT_META_PROTOCOL:
+-      case LOGFMT_META_REMOTE_HOST:
+       case LOGFMT_META_REMOTE_IP:
+-      case LOGFMT_META_RENAME_FROM:
+-      case LOGFMT_META_RESPONSE_STR:
+-      case LOGFMT_META_USER:
+       case LOGFMT_META_VERSION:
+       case LOGFMT_META_VHOST_IP:
+       case LOGFMT_META_XFER_FAILURE:
+-      case LOGFMT_META_XFER_PATH:
+       case LOGFMT_META_XFER_STATUS:
+       case LOGFMT_META_XFER_TYPE:
+       default:
+@@ -1004,7 +1028,8 @@
+       text_len = strlen(text);
+     }
+ 
+-    res = sql_resolved_append_text(p, resolved, text, text_len);
++    res = sql_resolved_append_text(p, resolved, text, text_len,
++      already_escaped);
+   }
+ 
+   return res;
+@@ -1067,7 +1092,7 @@
+         break;
+     }
+ 
+-    res = sql_resolved_append_text(p, resolved, text, text_len);
++    res = sql_resolved_append_text(p, resolved, text, text_len, FALSE);
+   }
+ 
+   return res;
+@@ -3164,7 +3189,7 @@
+       }
+ 
+       text_len = strlen(text);
+-      res = sql_resolved_append_text(p, resolved, text, text_len);
++      res = sql_resolved_append_text(p, resolved, text, text_len, FALSE);
+ 
+     } else {
+       res = sql_resolve_on_meta(p, jot_ctx, logfmt_id, jot_hint, val);


=====================================
debian/patches/series
=====================================
@@ -22,3 +22,4 @@ bcec15efe6c53dac40420731013f1cd2fd54123b.diff
 issue-1171.patch
 CVE-2024-57392.patch
 0036-Fix-blastradius-followup.patch
+2052_pghmcfc.diff



View it on GitLab: https://salsa.debian.org/debian-proftpd-team/proftpd/-/commit/fbc39c8f40b5e57dadf6f691fd863959e3960e29

-- 
View it on GitLab: https://salsa.debian.org/debian-proftpd-team/proftpd/-/commit/fbc39c8f40b5e57dadf6f691fd863959e3960e29
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help




More information about the Pkg-proftpd-maintainers mailing list