[System]
You are a security engineer fixing a CVE. You are given the vulnerability description (symptom only) and the vulnerable source window. Author the MINIMAL fix as a unified diff. Follow these rules exactly:
1. Target ONLY the file named in the `# Vulnerable source (...)` header — do not invent or substitute file paths.
2. Modify ONLY code visible in the shown source window.
3. Change as few lines as possible; do not rewrite surrounding logic.
4. Output only the unified diff with no other text.
5. Prefer the minimal structural change: if an existing condition is missing a check, add it inline to that condition rather than inserting a new code block. If existing code is redundant or overcomplicated, replace it — do not add more code around it.
6. Edit the most specific method or class that directly handles the vulnerable operation — not a base class, interface, or Protocol definition.

[User]
# CVE
CVE-2026-44331: SQL injection (CWE-89) in proftpd 1.3.9 mod_wrap2 module. An attacker who controls the reverse DNS lookup for their connecting IP can inject arbitrary SQL into the query string, potentially bypassing access controls enforced by the SQL-backed wrap2 table.

# Vulnerable source (contrib/mod_wrap2_sql.c)
```c

  destroy_pool(tmp_pool);
  return clients_list;
}

static array_header *sqltab_fetch_daemons_cb(wrap2_table_t *sqltab,
    const char *name) {
  array_header *daemons_list = make_array(sqltab->tab_pool, 1, sizeof(char *));

  /* Simply return the service name we're given. */
  *((char **) push_array(daemons_list)) = pstrdup(sqltab->tab_pool, name);

  return daemons_list;
}

static array_header *sqltab_fetch_options_cb(wrap2_table_t *sqltab,
    const char *name) {
  pool *tmp_pool = NULL;
  cmdtable *sql_cmdtab = NULL;
  cmd_rec *sql_cmd = NULL;
  modret_t *sql_res = NULL;
  array_header *sql_data = NULL;
  char *query = NULL, **vals = NULL;
  array_header *options_list = NULL;

  /* Allocate a temporary pool for the duration of this read. */
  tmp_pool = make_sub_pool(sqltab->tab_pool);

  query = ((char **) sqltab->tab_data)[WRAP2_SQL_OPTION_QUERY_IDX];

  /* The options-query is not necessary.  Skip if not present. */
  if (!query) {
    destroy_pool(tmp_pool);
    return NULL;
  }

  /* Find the cmdtable for the sql_lookup command. */
  sql_cmdtab = pr_stash_get_symbol2(PR_SYM_HOOK, "sql_lookup", NULL, NULL,
    NULL);
  if (sql_cmdtab == NULL) {
    wrap2_log("error: unable to find SQL hook symbol 'sql_lookup': "
      "perhaps your proftpd.conf needs 'LoadModule mod_sql.c'?");
    destroy_pool(tmp_pool);
    return NULL;
  }

  /* Prepare the SELECT query. */
  sql_cmd = sql_cmd_create(tmp_pool, 3, "sql_lookup", query, name);

  /* Call the handler. */
  sql_res = pr_module_call(sql_cmdtab->m, sql_cmdtab->handler, sql_cmd);

  /* Check the results. */
  if (!sql_res) {
    wrap2_log("SQLNamedQuery '%s' returned no data; "
      "see the mod_sql.c SQLLogFile for more details", query);
    destroy_pool(tmp_pool);
    return NULL;
  }

  if (MODRET_ISERROR(sql_res)) {
    wrap2_log("error processing SQLNamedQuery '%s': "
      "check the mod_sql.c SQLLogFile for more details", query);
    destroy_pool(tmp_pool);
    return NULL;
```

[Assistant]
diff --git a/contrib/mod_wrap2_sql.c b/contrib/mod_wrap2_sql.c
--- a/contrib/mod_wrap2_sql.c
+++ b/contrib/mod_wrap2_sql.c
@@ -233,16 +233,22 @@ static array_header *sqltab_fetch_options_cb(wrap2_table_t *sqltab,
   cmd_rec *sql_cmd = NULL;
   modret_t *sql_res = NULL;
   array_header *sql_data = NULL;
-  char *query = NULL, **vals = NULL;
+  char *escaped_name = NULL, *query = NULL, **vals = NULL;
   array_header *options_list = NULL;

   /* Allocate a temporary pool for the duration of this read. */
   tmp_pool = make_sub_pool(sqltab->tab_pool);

+  escaped_name = sqltab_get_escaped_text(tmp_pool, sqltab, name);
+  if (escaped_name == NULL) {
+    destroy_pool(tmp_pool);
+    return NULL;
+  }
+
   query = ((char **) sqltab->tab_data)[WRAP2_SQL_OPTION_QUERY_IDX];

   /* The options-query is not necessary.  Skip if not present. */
-  if (!query) {
+  if (query == NULL) {
     destroy_pool(tmp_pool);
     return NULL;
   }
@@ -258,7 +264,7 @@ static array_header *sqltab_fetch_options_cb(wrap2_table_t *sqltab,
   }

   /* Prepare the SELECT query. */
-  sql_cmd = sql_cmd_create(tmp_pool, 3, "sql_lookup", query, name);
+  sql_cmd = sql_cmd_create(tmp_pool, 3, "sql_lookup", query, escaped_name);

   /* Call the handler. */
   sql_res = pr_module_call(sql_cmdtab->m, sql_cmdtab->handler, sql_cmd);


[System]
You are a security engineer fixing a CVE. You are given the vulnerability description (symptom only) and the vulnerable source window. Author the MINIMAL fix as a unified diff. Follow these rules exactly:
1. Target ONLY the file named in the `# Vulnerable source (...)` header — do not invent or substitute file paths.
2. Modify ONLY code visible in the shown source window.
3. Change as few lines as possible; do not rewrite surrounding logic.
4. Output only the unified diff with no other text.
5. Prefer the minimal structural change: if an existing condition is missing a check, add it inline to that condition rather than inserting a new code block. If existing code is redundant or overcomplicated, replace it — do not add more code around it.
6. Edit the most specific method or class that directly handles the vulnerable operation — not a base class, interface, or Protocol definition.

[User]
# CVE
CVE-2026-44331: ProFTPD's SQL-based IP access control module constructs database lookup queries using an unsanitized host name read from a client connection, allowing an attacker to inject SQL syntax and potentially bypass access restrictions or corrupt the access control database.

# Vulnerable source (contrib/mod_wrap2_sql.c)
```c
  modret_t *sql_res = NULL;
  array_header *sql_data = NULL;
  char *query = NULL, **vals = NULL;
  array_header *options_list = NULL;

  /* Allocate a temporary pool for the duration of this read. */
  tmp_pool = make_sub_pool(sqltab->tab_pool);

  query = ((char **) sqltab->tab_data)[WRAP2_SQL_OPTION_QUERY_IDX];

  /* The options-query is not necessary.  Skip if not present. */
  if (!query) {
    destroy_pool(tmp_pool);
    return NULL;
  }

  /* Find the cmdtable for the sql_lookup command. */
  sql_cmdtab = pr_stash_get_symbol2(PR_SYM_HOOK, "sql_lookup", NULL, NULL,
    NULL);
  if (sql_cmdtab == NULL) {
    wrap2_log("error: unable to find SQL hook symbol 'sql_lookup': "
      "perhaps your proftpd.conf needs 'LoadModule mod_sql.c'?");
    destroy_pool(tmp_pool);
    return NULL;
  }

  /* Prepare the SELECT query. */
  sql_cmd = sql_cmd_create(tmp_pool, 3, "sql_lookup", query, name);

  /* Call the handler. */
  sql_res = pr_module_call(sql_cmdtab->m, sql_cmdtab->handler, sql_cmd);

  /* Check the results. */
  if (!sql_res) {
    wrap2_log("SQLNamedQuery '%s' returned no data; "
      "see the mod_sql.c SQLLogFile for more details", query);
    destroy_pool(tmp_pool);
    return NULL;
  }

  if (MODRET_ISERROR(sql_res)) {
    wrap2_log("error processing SQLNamedQuery '%s': "
      "check the mod_sql.c SQLLogFile for more details", query);
    destroy_pool(tmp_pool);
    return NULL;
  }

  /* Construct a single string, concatenating the returned client tokens
   * together.
   */
  sql_data = (array_header *) sql_res->data;
  vals = (char **) sql_data->elts;

  if (sql_data->nelts < 1) {
    wrap2_log("SQLNamedQuery '%s' returned no data; "
      "see the mod_sql.c SQLLogFile for more details", query);
    destroy_pool(tmp_pool);
    return NULL;
  }

  options_list = make_array(sqltab->tab_pool, sql_data->nelts, sizeof(char *));
  *((char **) push_array(options_list)) = pstrdup(sqltab->tab_pool, vals[0]);

  if (sql_data->nelts > 1) {
    register unsigned int i = 0;

    for (i = 1; i < sql_data->nelts; i++) {
      if (vals[i] == NULL) {
        continue;
      }

      *((char **) push_array(options_list)) = pstrdup(sqltab->tab_pool,
        vals[i]);
    }
  }

  destroy_pool(tmp_pool);
  return options_list;
}

static wrap2_table_t *sqltab_open_cb(pool *parent_pool, const char *srcinfo) {
  wrap2_table_t *tab = NULL;
  pool *tab_pool = make_sub_pool(parent_pool),
    *tmp_pool = make_sub_pool(parent_pool);
  config_rec *c = NULL;
  char *start = NULL, *finish = NULL, *query = NULL, *clients_query = NULL,
    *options_query = NULL, *info;

  tab = (wrap2_table_t *) pcalloc(tab_pool, sizeof(wrap2_table_t));
  tab->tab_pool = tab_pool;

  /* Parse the SELECT query name out of the srcinfo string.  Lookup and
   * store the query in the tab_data area, so that it need not be looked
   * up later.
   *
   * The srcinfo string for this case should look like:
   *  "/<clients-named-query>[/<options-named-query>]"
   */

  info = pstrdup(tmp_pool, srcinfo);
  start = strchr(info, '/');
  if (start == NULL) {
    wrap2_log("error: badly formatted source info '%s'", srcinfo);
    destroy_pool(tab_pool);
    destroy_pool(tmp_pool);
    errno = EINVAL;
    return NULL;
  }

  /* Find the next slash. */
  finish = strchr(++start, '/');
  if (finish != NULL) {
```

[Assistant]
diff --git a/contrib/mod_wrap2_sql.c b/contrib/mod_wrap2_sql.c
index d4fd56e69..0d52e3833 100644
--- a/contrib/mod_wrap2_sql.c
+++ b/contrib/mod_wrap2_sql.c
@@ -233,16 +233,22 @@ static array_header *sqltab_fetch_options_cb(wrap2_table_t *sqltab,
   cmd_rec *sql_cmd = NULL;
   modret_t *sql_res = NULL;
   array_header *sql_data = NULL;
-  char *query = NULL, **vals = NULL;
+  char *escaped_name = NULL, *query = NULL, **vals = NULL;
   array_header *options_list = NULL;

   /* Allocate a temporary pool for the duration of this read. */
   tmp_pool = make_sub_pool(sqltab->tab_pool);

+  escaped_name = sqltab_get_escaped_text(tmp_pool, sqltab, name);
+  if (escaped_name == NULL) {
+    destroy_pool(tmp_pool);
+    return NULL;
+  }
+
   query = ((char **) sqltab->tab_data)[WRAP2_SQL_OPTION_QUERY_IDX];

   /* The options-query is not necessary.  Skip if not present. */
-  if (!query) {
+  if (query == NULL) {
     destroy_pool(tmp_pool);
     return NULL;
   }
@@ -258,7 +264,7 @@ static array_header *sqltab_fetch_options_cb(wrap2_table_t *sqltab,
   }

   /* Prepare the SELECT query. */
-  sql_cmd = sql_cmd_create(tmp_pool, 3, "sql_lookup", query, name);
+  sql_cmd = sql_cmd_create(tmp_pool, 3, "sql_lookup", query, escaped_name);

   /* Call the handler. */
   sql_res = pr_module_call(sql_cmdtab->m, sql_cmdtab->handler, sql_cmd);


[System]
You are a security engineer fixing a CVE. You are given the vulnerability description (symptom only) and the vulnerable source window. Author the MINIMAL fix as a unified diff. Follow these rules exactly:
1. Target ONLY the file named in the `# Vulnerable source (...)` header — do not invent or substitute file paths.
2. Modify ONLY code visible in the shown source window.
3. Change as few lines as possible; do not rewrite surrounding logic.
4. Output only the unified diff with no other text.
5. Prefer the minimal structural change: if an existing condition is missing a check, add it inline to that condition rather than inserting a new code block. If existing code is redundant or overcomplicated, replace it — do not add more code around it.
6. Edit the most specific method or class that directly handles the vulnerable operation — not a base class, interface, or Protocol definition.

[User]
# CVE
CVE-2026-45190: Improper input validation (CWE-20) in the Perl module Net::CIDR::Lite. Such inputs passed the numeric validators in add() and the address packers, and were then numerically coerced and re-encoded to a different address than a strict reader would use. Affects Net::CIDR::Lite before 0.24.

# Vulnerable source (Lite.pm)
```perl
    $self->add_any($_) for @_;
    $self;
}

sub add_any {
    my $self = shift;
    for (@_) {
        tr|/|| && do { $self->add($_); next };
        tr|-|| && do { $self->add_range($_); next };
        UNIVERSAL::isa($_, 'Net::CIDR::Lite') && do {
            $self->add_cidr($_); next
        };
        $self->add_ip($_), next;
    }
    $self;
}

sub add {
    my $self = shift;
    my ($ip, $mask) = split "/", shift;
    $self->_init($ip) || confess "Can't determine ip format" unless %$self;
    confess "Bad mask $mask"
        unless $mask =~ /^\d+$/ and $mask <= $self->{NBITS}-8;
    $mask += 8;
    my $start = $self->{PACK}->($ip) & $self->{MASKS}[$mask]
        or confess "Bad ip address: $ip";
    my $end = $self->_add_bit($start, $mask);
    ++$$self{RANGES}{$start} || delete $$self{RANGES}{$start};
    --$$self{RANGES}{$end}   || delete $$self{RANGES}{$end};
    $self;
}

sub clean {
    my $self = shift;
    return $self unless $self->{RANGES};
    my $ranges = $$self{RANGES};
    my $total;
    $$self{RANGES} = {
      map { $total ? ($total+=$$ranges{$_})? () : ($_=>-1)
                   : do { $total+=$$ranges{$_}; ($_=>1) }
        /* ... */
    } elsif (_pack_ipv6($ip)) {
        $nbits = 136;
        $pack = \&_pack_ipv6;
        $unpack = \&_unpack_ipv6;
    } else {
        return;
    }
    $$self{PACK}  = $pack;
    $$self{UNPACK}  = $unpack;
    $$self{NBITS} = $nbits;
    $$self{MASKS} = $masks{$nbits} ||= [
      map { pack("B*", substr("1" x $_ . "0" x $nbits, 0, $nbits))
          } 0..$nbits
    ];
    $$self{RANGES} = {};
    $self;
}

sub _pack_ipv4 {
    my @nums = split /\./, shift(), -1;
    return unless @nums == 4;
    for (@nums) {
        return unless /^\d{1,3}$/ and !/^0\d{1,2}$/ and $_ <= 255;
    }
    pack("CC*", 0, @nums);
}

sub _unpack_ipv4 {
    join(".", unpack("xC*", shift));
}

sub _pack_ipv6 {
    my $ip = shift;
    $ip =~ s/^::$/::0/;
    return if $ip =~ /^:/ and $ip !~ s/^::/:/;
    return if $ip =~ /:$/ and $ip !~ s/::$/:/;
    my @nums = split /:/, $ip, -1;
    return unless @nums <= 8;
    my ($empty, $ipv4, $str) = (0,'','');
    for (@nums) {
        return if $ipv4;
        $str .= "0" x (4-length) . $_, next if /^[a-fA-F\d]{1,4}$/;
        do { return if $empty++ }, $str .= "X", next if $_ eq '';
        next if $ipv4 = _pack_ipv4($_);
        return;
    }
    return if $ipv4 and @nums > 6;
    return unless $empty or @nums == ($ipv4 ? 6 : 8);
    $str =~ s/X/"0" x (($ipv4 ? 25 : 33)-length($str))/e if $empty;
    pack("H*", "00" . $str).substr($ipv4, 1);
}
```

[Assistant]
diff --git a/Lite.pm b/Lite.pm
--- a/Lite.pm
+++ b/Lite.pm
@@ -37,7 +37,7 @@ sub add {
     my ($ip, $mask) = split "/", shift;
     $self->_init($ip) || confess "Can't determine ip format" unless %$self;
     confess "Bad mask $mask"
-        unless $mask =~ /^\d+$/ and $mask <= $self->{NBITS}-8;
+        unless $mask =~ /\A[0-9]+\z/ and $mask <= $self->{NBITS}-8;
     $mask += 8;
     my $start = $self->{PACK}->($ip) & $self->{MASKS}[$mask]
         or confess "Bad ip address: $ip";
@@ -181,7 +181,7 @@ sub _pack_ipv4 {
     my @nums = split /\./, shift(), -1;
     return unless @nums == 4;
     for (@nums) {
-        return unless /^\d{1,3}$/ and !/^0\d{1,2}$/ and $_ <= 255;
+        return unless /\A[0-9]{1,3}\z/ and !/\A0[0-9]{1,2}\z/ and $_ <= 255;
     }
     pack("CC*", 0, @nums);
 }
@@ -192,15 +192,15 @@ sub _unpack_ipv4 {

 sub _pack_ipv6 {
     my $ip = shift;
-    $ip =~ s/^::$/::0/;
-    return if $ip =~ /^:/ and $ip !~ s/^::/:/;
-    return if $ip =~ /:$/ and $ip !~ s/::$/:/;
+    $ip =~ s/\A::\z/::0/;
+    return if $ip =~ /\A:/ and $ip !~ s/\A::/:/;
+    return if $ip =~ /:\z/ and $ip !~ s/::\z/:/;
     my @nums = split /:/, $ip, -1;
     return unless @nums <= 8;
     my ($empty, $ipv4, $str) = (0,'','');
     for (@nums) {
         return if $ipv4;
-        $str .= "0" x (4-length) . $_, next if /^[a-fA-F\d]{1,4}$/;
+        $str .= "0" x (4-length) . $_, next if /\A[a-fA-F0-9]{1,4}\z/;
         do { return if $empty++ }, $str .= "X", next if $_ eq '';
         next if $ipv4 = _pack_ipv4($_);
         return;


[System]
You are a security engineer fixing a CVE. You are given the vulnerability description (symptom only) and the vulnerable source window. Author the MINIMAL fix as a unified diff. Follow these rules exactly:
1. Target ONLY the file named in the `# Vulnerable source (...)` header — do not invent or substitute file paths.
2. Modify ONLY code visible in the shown source window.
3. Change as few lines as possible; do not rewrite surrounding logic.
4. Output only the unified diff with no other text.
5. Prefer the minimal structural change: if an existing condition is missing a check, add it inline to that condition rather than inserting a new code block. If existing code is redundant or overcomplicated, replace it — do not add more code around it.
6. Edit the most specific method or class that directly handles the vulnerable operation — not a base class, interface, or Protocol definition.

[User]
# CVE
CVE-2026-45191: Improper input validation (CWE-20) in the Perl module Net::CIDR::Lite. When adding a network, the prefix-length portion after the slash was accepted as long as it consisted only of digits, with no rejection of a leading zero. A prefix length written with a leading zero, such as the 08 in 10.0.0.0/08 or the 00 in ::/00, was therefore accepted and read as its plain decimal value, whereas a strict reader treats a zero-padded number as malformed. A CIDR allow-list or deny-list built from attacker-influenced input consequently parses to a different prefix length than the author intended, an allow/deny-list inconsistency. Affects Net::CIDR::Lite before 0.24.

# Vulnerable source (Lite.pm)
```perl
    $self->add_any($_) for @_;
    $self;
}

sub add_any {
    my $self = shift;
    for (@_) {
        tr|/|| && do { $self->add($_); next };
        tr|-|| && do { $self->add_range($_); next };
        UNIVERSAL::isa($_, 'Net::CIDR::Lite') && do {
            $self->add_cidr($_); next
        };
        $self->add_ip($_), next;
    }
    $self;
}

sub add {
    my $self = shift;
    my ($ip, $mask) = split "/", shift;
    $self->_init($ip) || confess "Can't determine ip format" unless %$self;
    confess "Bad mask $mask"
        unless $mask =~ /\A[0-9]+\z/ and $mask <= $self->{NBITS}-8;
    $mask += 8;
    my $start = $self->{PACK}->($ip) & $self->{MASKS}[$mask]
        or confess "Bad ip address: $ip";
    my $end = $self->_add_bit($start, $mask);
    ++$$self{RANGES}{$start} || delete $$self{RANGES}{$start};
    --$$self{RANGES}{$end}   || delete $$self{RANGES}{$end};
    $self;
}

sub clean {
    my $self = shift;
    return $self unless $self->{RANGES};
    my $ranges = $$self{RANGES};
    my $total;
    $$self{RANGES} = {
      map { $total ? ($total+=$$ranges{$_})? () : ($_=>-1)
                   : do { $total+=$$ranges{$_}; ($_=>1) }
```

[Assistant]
diff --git a/Lite.pm b/Lite.pm
--- a/Lite.pm
+++ b/Lite.pm
@@ -37,7 +37,9 @@ sub add {
     my ($ip, $mask) = split "/", shift;
     $self->_init($ip) || confess "Can't determine ip format" unless %$self;
     confess "Bad mask $mask"
-        unless $mask =~ /\A[0-9]+\z/ and $mask <= $self->{NBITS}-8;
+        unless defined $mask
+        and $mask =~ /\A(?:0|[1-9][0-9]*)\z/
+        and $mask <= $self->{NBITS}-8;
     $mask += 8;
     my $start = $self->{PACK}->($ip) & $self->{MASKS}[$mask]
         or confess "Bad ip address: $ip";


[System]
You are a security engineer fixing a CVE. You are given the vulnerability description (symptom only) and the vulnerable source window. Author the MINIMAL fix as a unified diff. Follow these rules exactly:
1. Target ONLY the file named in the `# Vulnerable source (...)` header — do not invent or substitute file paths.
2. Modify ONLY code visible in the shown source window.
3. Change as few lines as possible; do not rewrite surrounding logic.
4. Output only the unified diff with no other text.
5. Prefer the minimal structural change: if an existing condition is missing a check, add it inline to that condition rather than inserting a new code block. If existing code is redundant or overcomplicated, replace it — do not add more code around it.
6. Edit the most specific method or class that directly handles the vulnerable operation — not a base class, interface, or Protocol definition.

[User]
# CVE
CVE-2026-50593: Integer underflow and resultant out-of-bounds read (CWE-191/CWE-125) in Graphite (libgraphite2) before 1.3.15. graphite2 compiles and validates a font's Graphite 'silf' passes by running the VM at face-load time, so a crafted font (tests/fonts/underflow.ttf in the upstream regression suite) whose bytecode drives the offset out of range reads past the slot map. Reproduce: shape the text 'baaaaaab' against underflow.ttf via the public API (gr_make_file_face + gr_make_seg).

# Vulnerable source (src/inc/opcodes.h)
```c
//        seg       = A reference to the Segment this code is running over.
//        is        = The current slot index
//        isb       = The original base slot index at the start of this rule
//        isf       = The first positioned slot
//        isl       = The last positioned slot
//        ip        = The current instruction pointer
//        endPos    = Position of advance of last cluster
//        dir       = writing system directionality of the font

// #define NOT_IMPLEMENTED     assert(false)
// #define NOT_IMPLEMENTED

#define binop(op)           const uint32 a = pop(); *sp = uint32(*sp) op a
#define sbinop(op)          const int32 a = pop(); *sp = int32(*sp) op a
#define use_params(n)       dp += n

#define declare_params(n)   const byte * param = dp; \
                            use_params(n);

#define push(n)             { *++sp = n; }
#define pop()               (*sp--)
#define slotat(x)           (map[(x)])
#define DIE                 { is=seg.last(); status = Machine::died_early; EXIT(1); }
#define POSITIONED          1

STARTOP(nop)
    do {} while (0);
ENDOP

STARTOP(push_byte)
    declare_params(1);
    push(int8(*param));
ENDOP

STARTOP(push_byte_u)
    declare_params(1);
    push(uint8(*param));
ENDOP

```

[Assistant]
diff --git a/src/inc/opcodes.h b/src/inc/opcodes.h
index 10ba177..f616669 100644
--- a/src/inc/opcodes.h
+++ b/src/inc/opcodes.h
@@ -53,7 +53,8 @@

 #define push(n)             { *++sp = n; }
 #define pop()               (*sp--)
-#define slotat(x)           (map[(x)])
+#define slotat(x)           ((map + (x) >= &smap[-1] && map + (x) < smap.end()) ? \
+                                map[(x)] : (status = Machine::slot_offset_out_bounds, nullptr))
 #define DIE                 { is=seg.last(); status = Machine::died_early; EXIT(1); }
 #define POSITIONED          1


[System]
You are a security engineer fixing a CVE. You are given the vulnerability description (symptom only) and the vulnerable source window. Author the MINIMAL fix as a unified diff. Follow these rules exactly:
1. Target ONLY the file named in the `# Vulnerable source (...)` header — do not invent or substitute file paths.
2. Modify ONLY code visible in the shown source window.
3. Change as few lines as possible; do not rewrite surrounding logic.
4. Output only the unified diff with no other text.
5. Prefer the minimal structural change: if an existing condition is missing a check, add it inline to that condition rather than inserting a new code block. If existing code is redundant or overcomplicated, replace it — do not add more code around it.
6. Edit the most specific method or class that directly handles the vulnerable operation — not a base class, interface, or Protocol definition.

[User]
# CVE
CVE-2026-6507: One-byte buffer overflow in dnsmasq 2.92: the DHCPv4 relay reply handler in rfc2131.c uses an off-by-one size when zeroing a DHCP option field, potentially writing one byte beyond the buffer boundary during relay processing.

# Vulnerable source (src/rfc2131.c)
```c
  struct dhcp_relay *relay;

  if (mess->giaddr.s_addr == 0 || mess->op != BOOTREPLY)
    return 0;

  for (relay = daemon->relay4; relay; relay = relay->next)
    {
      unsigned int return_iface = 0;

      if (relay->split_mode)
	{
	  unsigned char *opt, *sopt;

	  /* giaddr is our address on the returning interface in split mode. */
	  if (mess->giaddr.s_addr == relay->uplink.addr4.s_addr &&
	      (opt = option_find(mess, sz, OPTION_AGENT_ID, 1)))
	    {
	      if ((sopt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), SUBOPT_REMOTE_ID, sizeof(unsigned int))))
		return_iface = option_uint(sopt, 0, sizeof(unsigned int));

	      /* delete agent info before return RFC 3046 para 2.1 */
	      *opt = OPTION_END;
	      memset(opt + 1, 0, option_len(opt) + 2);
	    }
	}
      else if (mess->giaddr.s_addr == relay->local.addr4.s_addr)
	return_iface = relay->iface_index;

      if (return_iface && (!relay->interface || wildcard_match(relay->interface, arrival_interface)))
	return return_iface;
    }

  return 0;
}

#endif /* HAVE_DHCP */
```

[Assistant]
diff --git a/src/rfc2131.c b/src/rfc2131.c
--- a/src/rfc2131.c
+++ b/src/rfc2131.c
@@ -3248,7 +3248,7 @@ unsigned int relay_reply4(struct dhcp_packet *mess, size_t sz, char *arrival_int

 	      /* delete agent info before return RFC 3046 para 2.1 */
 	      *opt = OPTION_END;
-	      memset(opt + 1, 0, option_len(opt) + 2);
+	      memset(opt + 1, 0, option_len(opt) + 1);
 	    }
 	}
       else if (mess->giaddr.s_addr == relay->local.addr4.s_addr)
--
2.20.1


[System]
You are a security engineer fixing a CVE. You are given the vulnerability description (symptom only) and the vulnerable source window. Author the MINIMAL fix as a unified diff. Follow these rules exactly:
1. Target ONLY the file named in the `# Vulnerable source (...)` header — do not invent or substitute file paths.
2. Modify ONLY code visible in the shown source window.
3. Change as few lines as possible; do not rewrite surrounding logic.
4. Output only the unified diff with no other text.
5. Prefer the minimal structural change: if an existing condition is missing a check, add it inline to that condition rather than inserting a new code block. If existing code is redundant or overcomplicated, replace it — do not add more code around it.
6. Edit the most specific method or class that directly handles the vulnerable operation — not a base class, interface, or Protocol definition.

[User]
# CVE
CVE-2026-7598: Integer overflow (CWE-190) in libssh2 1.11.1 leading to heap-buffer-overflow. Then _libssh2_store_str() calls _libssh2_htonu32 which writes a 4-byte length prefix past the 1-byte buffer (heap-buffer-overflow). The overflow occurs during local packet construction before any network I/O, making it triggerable from the public libssh2_userauth_list() / libssh2_userauth_password() APIs without a live SSH connection.

# Vulnerable source (src/userauth.c)
```c
 * Will yield successful login if "none" happens to be allowable for this user
 * Not a common configuration for any SSH server though
 * username should be NULL, or a null terminated string
 */
static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
                           unsigned int username_len)
{
    unsigned char reply_codes[4] =
        { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE,
          SSH_MSG_USERAUTH_BANNER, 0 };
    /* packet_type(1) + username_len(4) + service_len(4) +
       service(14)"ssh-connection" + method_len(4) = 27 */
    unsigned long methods_len;
    unsigned int banner_len;
    unsigned char *s;
    int rc;

    if(session->userauth_list_state == libssh2_NB_state_idle) {
        /* Zero the whole thing out */
        memset(&session->userauth_list_packet_requirev_state, 0,
               sizeof(session->userauth_list_packet_requirev_state));

        session->userauth_list_data_len = username_len + 27;

        if(session->userauth_list_data) {
            LIBSSH2_FREE(session, session->userauth_list_data);
        }

        s = session->userauth_list_data =
            LIBSSH2_ALLOC(session, session->userauth_list_data_len);
        if(!session->userauth_list_data) {
            _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                           "Unable to allocate memory for userauth_list");
            return NULL;
        }

        *(s++) = SSH_MSG_USERAUTH_REQUEST;
        _libssh2_store_str(&s, username, username_len);
        _libssh2_store_str(&s, "ssh-connection", 14);
        _libssh2_store_u32(&s, 4); /* send "none" separately */
        /* ... */
                  const char *username, unsigned int username_len,
                  const unsigned char *password, unsigned int password_len,
                  LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)))
{
    unsigned char *s;
    static const unsigned char reply_codes[4] = {
        SSH_MSG_USERAUTH_SUCCESS,
        SSH_MSG_USERAUTH_FAILURE,
        SSH_MSG_USERAUTH_PASSWD_CHANGEREQ,
        0
    };
    int rc;

    if(session->userauth_pswd_state == libssh2_NB_state_idle) {
        /* Zero the whole thing out */
        memset(&session->userauth_pswd_packet_requirev_state, 0,
               sizeof(session->userauth_pswd_packet_requirev_state));

        /*
         * 40 = packet_type(1) + username_len(4) + service_len(4) +
         * service(14)"ssh-connection" + method_len(4) + method(8)"password" +
         * chgpwdbool(1) + password_len(4) */
        session->userauth_pswd_data_len = username_len + 40;

        session->userauth_pswd_data0 =
            (unsigned char) ~SSH_MSG_USERAUTH_PASSWD_CHANGEREQ;

        /* TODO: remove this alloc with a fixed buffer in the session
           struct */
        s = session->userauth_pswd_data =
            LIBSSH2_ALLOC(session, session->userauth_pswd_data_len);
        if(!session->userauth_pswd_data) {
            return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                                  "Unable to allocate memory for "
                                  "userauth-password request");
        }

        *(s++) = SSH_MSG_USERAUTH_REQUEST;
        _libssh2_store_str(&s, username, username_len);
        _libssh2_store_str(&s, "ssh-connection", sizeof("ssh-connection") - 1);
        /* ... */
                (session->userauth_pswd_state == libssh2_NB_state_sent2)) {
                if(session->userauth_pswd_state == libssh2_NB_state_sent1) {
                    _libssh2_debug((session, LIBSSH2_TRACE_AUTH,
                                   "Password change required"));
                    LIBSSH2_FREE(session, session->userauth_pswd_data);
                    session->userauth_pswd_data = NULL;
                }
                if(passwd_change_cb) {
                    if(session->userauth_pswd_state ==
                       libssh2_NB_state_sent1) {
                        passwd_change_cb(session,
                                         &session->userauth_pswd_newpw,
                                         &session->userauth_pswd_newpw_len,
                                         &session->abstract);
                        if(!session->userauth_pswd_newpw) {
                            return _libssh2_error(session,
                                                LIBSSH2_ERROR_PASSWORD_EXPIRED,
                                                  "Password expired, and "
                                                  "callback failed");
                        }

                        /* basic data_len + newpw_len(4) */
                        if(username_len + password_len + 44 <= UINT_MAX) {
                            session->userauth_pswd_data_len =
                                username_len + password_len + 44;
                            s = session->userauth_pswd_data =
                                LIBSSH2_ALLOC(session,
                                              session->userauth_pswd_data_len);
                        }
                        else {
                            s = session->userauth_pswd_data = NULL;
                            session->userauth_pswd_data_len = 0;
                        }

                        if(!session->userauth_pswd_data) {
                            LIBSSH2_FREE(session,
                                         session->userauth_pswd_newpw);
                            session->userauth_pswd_newpw = NULL;
                            return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                                                  "Unable to allocate memory "
```

[Assistant]
diff --git a/src/userauth.c b/src/userauth.c
--- a/src/userauth.c
+++ b/src/userauth.c
@@ -80,6 +80,12 @@ static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
         memset(&session->userauth_list_packet_requirev_state, 0,
                sizeof(session->userauth_list_packet_requirev_state));

+        if(username_len > UINT32_MAX - 27) {
+            _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+                           "username_len out of bounds");
+            return NULL;
+        }
+
         session->userauth_list_data_len = username_len + 27;

         if(session->userauth_list_data) {
@@ -316,6 +322,11 @@ userauth_password(LIBSSH2_SESSION *session,
          * 40 = packet_type(1) + username_len(4) + service_len(4) +
          * service(14)"ssh-connection" + method_len(4) + method(8)"password" +
          * chgpwdbool(1) + password_len(4) */
+        if(username_len > UINT32_MAX - 40) {
+            return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+                                  "username_len out of bounds");
+        }
+
         session->userauth_pswd_data_len = username_len + 40;

         session->userauth_pswd_data0 =
@@ -456,7 +467,7 @@ userauth_password(LIBSSH2_SESSION *session,
                         }

                         /* basic data_len + newpw_len(4) */
-                        if(username_len + password_len + 44 <= UINT_MAX) {
+                        if(username_len <= UINT32_MAX - password_len - 44) {
                             session->userauth_pswd_data_len =
                                 username_len + password_len + 44;
                             s = session->userauth_pswd_data =


[System]
You are a security engineer fixing a CVE. You are given the vulnerability description (symptom only) and the vulnerable source window. Author the MINIMAL fix as a unified diff. Follow these rules exactly:
1. Target ONLY the file named in the `# Vulnerable source (...)` header — do not invent or substitute file paths.
2. Modify ONLY code visible in the shown source window.
3. Change as few lines as possible; do not rewrite surrounding logic.
4. Output only the unified diff with no other text.
5. Prefer the minimal structural change: if an existing condition is missing a check, add it inline to that condition rather than inserting a new code block. If existing code is redundant or overcomplicated, replace it — do not add more code around it.
6. Edit the most specific method or class that directly handles the vulnerable operation — not a base class, interface, or Protocol definition.

[User]
# CVE
CVE-2026-7598: libssh2 authentication code performs arithmetic on a caller-supplied username or password length without first ensuring the value fits in a 32-bit unsigned integer, allowing an excessively large length to wrap around and produce a truncated allocation that is subsequently overflowed when authentication data is written into it.

# Vulnerable source (src/userauth.c)
```c
 */

#include "libssh2_priv.h"

#include <ctype.h>

/* Needed for struct iovec on some platforms */
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif

#include "transport.h"
#include "session.h"
#include "userauth.h"
#include "userauth_kbd_packet.h"

#include <stdlib.h>  /* strtol() */

/* userauth_list
 *
 * List authentication methods
 * Will yield successful login if "none" happens to be allowable for this user
 * Not a common configuration for any SSH server though
 * username should be NULL, or a null terminated string
 */
static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
                           unsigned int username_len)
{
    unsigned char reply_codes[4] =
        { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE,
          SSH_MSG_USERAUTH_BANNER, 0 };
    /* packet_type(1) + username_len(4) + service_len(4) +
       service(14)"ssh-connection" + method_len(4) = 27 */
    unsigned long methods_len;
    unsigned int banner_len;
    unsigned char *s;
    int rc;

    if(session->userauth_list_state == libssh2_NB_state_idle) {
        /* Zero the whole thing out */
        memset(&session->userauth_list_packet_requirev_state, 0,
               sizeof(session->userauth_list_packet_requirev_state));

        session->userauth_list_data_len = username_len + 27;

        s = session->userauth_list_data =
            LIBSSH2_ALLOC(session, session->userauth_list_data_len);
        if(!session->userauth_list_data) {
            _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                           "Unable to allocate memory for userauth_list");
            return NULL;
        }

        *(s++) = SSH_MSG_USERAUTH_REQUEST;
        _libssh2_store_str(&s, username, username_len);
        _libssh2_store_str(&s, "ssh-connection", 14);
        _libssh2_store_u32(&s, 4); /* send "none" separately */

        session->userauth_list_state = libssh2_NB_state_created;
    }

    if(session->userauth_list_state == libssh2_NB_state_created) {
        rc = _libssh2_transport_send(session, session->userauth_list_data,
                                     session->userauth_list_data_len,
                                     (unsigned char *)"none", 4);
        if(rc == LIBSSH2_ERROR_EAGAIN) {
            _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
                           "Would block requesting userauth list");
            return NULL;
        }
        /* now free the packet that was sent */
        LIBSSH2_FREE(session, session->userauth_list_data);
        session->userauth_list_data = NULL;

        if(rc) {
            _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
                           "Unable to send userauth-none request");
            session->userauth_list_state = libssh2_NB_state_idle;
            return NULL;
        }

        session->userauth_list_state = libssh2_NB_state_sent;
    }

    if(session->userauth_list_state == libssh2_NB_state_sent) {
        rc = _libssh2_packet_requirev(session, reply_codes,
                                      &session->userauth_list_data,
                                      &session->userauth_list_data_len, 0,
                                      NULL, 0,
                               &session->userauth_list_packet_requirev_state);
        if(rc == LIBSSH2_ERROR_EAGAIN) {
            _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
                           "Would block requesting userauth list");
            return NULL;
        }
        else if(rc || (session->userauth_list_data_len < 1)) {
            _libssh2_error(session, rc, "Failed getting response");
            session->userauth_list_state = libssh2_NB_state_idle;
            return NULL;
        }

        if(session->userauth_list_data[0] == SSH_MSG_USERAUTH_BANNER) {
            if(session->userauth_list_data_len < 5) {
                LIBSSH2_FREE(session, session->userauth_list_data);
                session->userauth_list_data = NULL;
                _libssh2_error(session, LIBSSH2_ERROR_PROTO,
                               "Unexpected packet size");
                return NULL;
            }
            banner_len = _libssh2_ntohu32(session->userauth_list_data + 1);
            if(banner_len > session->userauth_list_data_len - 5) {
                LIBSSH2_FREE(session, session->userauth_list_data);
                session->userauth_list_data = NULL;
                _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
                               "Unexpected userauth banner size");
                return NULL;
            }
            session->userauth_banner = LIBSSH2_ALLOC(session, banner_len + 1);
            if(!session->userauth_banner) {
                LIBSSH2_FREE(session, session->userauth_list_data);
                session->userauth_list_data = NULL;
                _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                              "Unable to allocate memory for userauth_banner");
                return NULL;
            }
            memcpy(session->userauth_banner, session->userauth_list_data + 5,
                    banner_len);
            session->userauth_banner[banner_len] = '\0';
            _libssh2_debug((session, LIBSSH2_TRACE_AUTH,
                           "Banner: %s",
                           session->userauth_banner));
            LIBSSH2_FREE(session, session->userauth_list_data);
            session->userauth_list_data = NULL;
            /* SSH_MSG_USERAUTH_BANNER has been handled */
            reply_codes[2] = 0;
            rc = _libssh2_packet_requirev(session, reply_codes,
                                          &session->userauth_list_data,
                                          &session->userauth_list_data_len, 0,
                                          NULL, 0,
                                &session->userauth_list_packet_requirev_state);
            if(rc == LIBSSH2_ERROR_EAGAIN) {
                _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
                               "Would block requesting userauth list");
                return NULL;
            }
            else if(rc || (session->userauth_list_data_len < 1)) {
                _libssh2_error(session, rc, "Failed getting response");
                session->userauth_list_state = libssh2_NB_state_idle;
                return NULL;
            }
        }

        if(session->userauth_list_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
            /* Wow, who'dve thought... */
            _libssh2_error(session, LIBSSH2_ERROR_NONE, "No error");
            LIBSSH2_FREE(session, session->userauth_list_data);
            session->userauth_list_data = NULL;
            session->state |= LIBSSH2_STATE_AUTHENTICATED;
            session->userauth_list_state = libssh2_NB_state_idle;
            return NULL;
        }

        if(session->userauth_list_data_len < 5) {
            LIBSSH2_FREE(session, session->userauth_list_data);
            session->userauth_list_data = NULL;
            _libssh2_error(session, LIBSSH2_ERROR_PROTO,
                           "Unexpected packet size");
            return NULL;
        }

        methods_len = _libssh2_ntohu32(session->userauth_list_data + 1);
        if(methods_len >= session->userauth_list_data_len - 5) {
            _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
                           "Unexpected userauth list size");
            return NULL;
        }

        /* Do note that the memory areas overlap! */
        memmove(session->userauth_list_data, session->userauth_list_data + 5,
                methods_len);
        session->userauth_list_data[methods_len] = '\0';
        _libssh2_debug((session, LIBSSH2_TRACE_AUTH,
                       "Permitted auth methods: %s",
                       session->userauth_list_data));
    }

    session->userauth_list_state = libssh2_NB_state_idle;
    return (char *)session->userauth_list_data;
}

/* libssh2_userauth_list
 *
 * List authentication methods
 * Will yield successful login if "none" happens to be allowable for this user
 * Not a common configuration for any SSH server though
 * username should be NULL, or a null terminated string
 */
LIBSSH2_API char *
libssh2_userauth_list(LIBSSH2_SESSION * session, const char *user,
                      unsigned int user_len)
{
    char *ptr;
    BLOCK_ADJUST_ERRNO(ptr, session,
                       userauth_list(session, user, user_len));
    return ptr;
}

/* libssh2_userauth_banner
 *
 * Retrieve banner message from server, if available.
 * When no such message is sent by server or if no authentication attempt has
 * been made, this function returns LIBSSH2_ERROR_MISSING_AUTH_BANNER.
 */
LIBSSH2_API int
libssh2_userauth_banner(LIBSSH2_SESSION *session, char **banner)
{
    if(!session)
        return LIBSSH2_ERROR_MISSING_USERAUTH_BANNER;

    if(!session->userauth_banner) {
        return _libssh2_error(session,
                              LIBSSH2_ERROR_MISSING_USERAUTH_BANNER,
                              "Missing userauth banner");
    }

    if(banner)
        *banner = session->userauth_banner;

    return LIBSSH2_ERROR_NONE;
}

/*
 * libssh2_userauth_authenticated
 *
 * Returns: 0 if not yet authenticated
 *          1 if already authenticated
 */
LIBSSH2_API int
libssh2_userauth_authenticated(LIBSSH2_SESSION * session)
{
    return (session->state & LIBSSH2_STATE_AUTHENTICATED) ? 1 : 0;
}

/* userauth_password
 * Plain ol' login
 */
static int
userauth_password(LIBSSH2_SESSION *session,
                  const char *username, unsigned int username_len,
                  const unsigned char *password, unsigned int password_len,
                  LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)))
{
    unsigned char *s;
    static const unsigned char reply_codes[4] =
        { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE,
          SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0
        };
    int rc;

    if(session->userauth_pswd_state == libssh2_NB_state_idle) {
        /* Zero the whole thing out */
        memset(&session->userauth_pswd_packet_requirev_state, 0,
               sizeof(session->userauth_pswd_packet_requirev_state));

        /*
         * 40 = packet_type(1) + username_len(4) + service_len(4) +
         * service(14)"ssh-connection" + method_len(4) + method(8)"password" +
         * chgpwdbool(1) + password_len(4) */
        session->userauth_pswd_data_len = username_len + 40;

        session->userauth_pswd_data0 =
            (unsigned char) ~SSH_MSG_USERAUTH_PASSWD_CHANGEREQ;

        /* TODO: remove this alloc with a fixed buffer in the session
           struct */
        s = session->userauth_pswd_data =
            LIBSSH2_ALLOC(session, session->userauth_pswd_data_len);
        if(!session->userauth_pswd_data) {
            return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                                  "Unable to allocate memory for "
                                  "userauth-password request");
        }

        *(s++) = SSH_MSG_USERAUTH_REQUEST;
        _libssh2_store_str(&s, username, username_len);
        _libssh2_store_str(&s, "ssh-connection", sizeof("ssh-connection") - 1);
        _libssh2_store_str(&s, "password", sizeof("password") - 1);
        *s++ = '\0';
        _libssh2_store_u32(&s, password_len);
        /* 'password' is sent separately */

        _libssh2_debug((session, LIBSSH2_TRACE_AUTH,
                       "Attempting to login using password authentication"));

        session->userauth_pswd_state = libssh2_NB_state_created;
    }

    if(session->userauth_pswd_state == libssh2_NB_state_created) {
        rc = _libssh2_transport_send(session, session->userauth_pswd_data,
                                     session->userauth_pswd_data_len,
                                     password, password_len);
        if(rc == LIBSSH2_ERROR_EAGAIN) {
            return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
                                  "Would block writing password request");
        }

        /* now free the sent packet */
        LIBSSH2_FREE(session, session->userauth_pswd_data);
        session->userauth_pswd_data = NULL;

        if(rc) {
            session->userauth_pswd_state = libssh2_NB_state_idle;
            return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
                                  "Unable to send userauth-password request");
        }

        session->userauth_pswd_state = libssh2_NB_state_sent;
    }

password_response:

    if((session->userauth_pswd_state == libssh2_NB_state_sent)
        || (session->userauth_pswd_state == libssh2_NB_state_sent1)
        || (session->userauth_pswd_state == libssh2_NB_state_sent2)) {
        if(session->userauth_pswd_state == libssh2_NB_state_sent) {
            rc = _libssh2_packet_requirev(session, reply_codes,
                                          &session->userauth_pswd_data,
                                          &session->userauth_pswd_data_len,
                                          0, NULL, 0,
                                          &session->
                                          userauth_pswd_packet_requirev_state);

            if(rc) {
                if(rc != LIBSSH2_ERROR_EAGAIN)
                    session->userauth_pswd_state = libssh2_NB_state_idle;

                return _libssh2_error(session, rc,
                                      "Waiting for password response");
            }
            else if(session->userauth_pswd_data_len < 1) {
                session->userauth_pswd_state = libssh2_NB_state_idle;
                return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
                                      "Unexpected packet size");
            }

            if(session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
                _libssh2_debug((session, LIBSSH2_TRACE_AUTH,
                               "Password authentication successful"));
                LIBSSH2_FREE(session, session->userauth_pswd_data);
                session->userauth_pswd_data = NULL;
                session->state |= LIBSSH2_STATE_AUTHENTICATED;
                session->userauth_pswd_state = libssh2_NB_state_idle;
                return 0;
            }
            else if(session->userauth_pswd_data[0] ==
                    SSH_MSG_USERAUTH_FAILURE) {
                _libssh2_debug((session, LIBSSH2_TRACE_AUTH,
                               "Password authentication failed"));
                LIBSSH2_FREE(session, session->userauth_pswd_data);
                session->userauth_pswd_data = NULL;
                session->userauth_pswd_state = libssh2_NB_state_idle;
                return _libssh2_error(session,
                                      LIBSSH2_ERROR_AUTHENTICATION_FAILED,
                                      "Authentication failed "
                                      "(username/password)");
            }

            session->userauth_pswd_newpw = NULL;
            session->userauth_pswd_newpw_len = 0;

            session->userauth_pswd_state = libssh2_NB_state_sent1;
        }

        if(session->userauth_pswd_data_len < 1) {
            session->userauth_pswd_state = libssh2_NB_state_idle;
            return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
                                  "Unexpected packet size");
        }

        if((session->userauth_pswd_data[0] ==
             SSH_MSG_USERAUTH_PASSWD_CHANGEREQ)
            || (session->userauth_pswd_data0 ==
                SSH_MSG_USERAUTH_PASSWD_CHANGEREQ)) {
            session->userauth_pswd_data0 = SSH_MSG_USERAUTH_PASSWD_CHANGEREQ;

            if((session->userauth_pswd_state == libssh2_NB_state_sent1) ||
                (session->userauth_pswd_state == libssh2_NB_state_sent2)) {
                if(session->userauth_pswd_state == libssh2_NB_state_sent1) {
                    _libssh2_debug((session, LIBSSH2_TRACE_AUTH,
                                   "Password change required"));
                    LIBSSH2_FREE(session, session->userauth_pswd_data);
                    session->userauth_pswd_data = NULL;
                }
                if(passwd_change_cb) {
                    if(session->userauth_pswd_state ==
                       libssh2_NB_state_sent1) {
                        passwd_change_cb(session,
                                         &session->userauth_pswd_newpw,
                                         &session->userauth_pswd_newpw_len,
                                         &session->abstract);
                        if(!session->userauth_pswd_newpw) {
                            return _libssh2_error(session,
                                                LIBSSH2_ERROR_PASSWORD_EXPIRED,
                                                  "Password expired, and "
                                                  "callback failed");
                        }

                        /* basic data_len + newpw_len(4) */
                        if(username_len + password_len + 44 <= UINT_MAX) {
                            session->userauth_pswd_data_len =
                                username_len + password_len + 44;
                            s = session->userauth_pswd_data =
                                LIBSSH2_ALLOC(session,
                                              session->userauth_pswd_data_len);
                        }
                        else {
                            s = session->userauth_pswd_data = NULL;
                            session->userauth_pswd_data_len = 0;
                        }

                        if(!session->userauth_pswd_data) {
                            LIBSSH2_FREE(session,
                                         session->userauth_pswd_newpw);
                            session->userauth_pswd_newpw = NULL;
                            return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                                                  "Unable to allocate memory "
                                                  "for userauth password "
                                                  "change request");
                        }

                        *(s++) = SSH_MSG_USERAUTH_REQUEST;
                        _libssh2_store_str(&s, username, username_len);
                        _libssh2_store_str(&s, "ssh-connection",
                                           sizeof("ssh-connection") - 1);
                        _libssh2_store_str(&s, "password",
                                           sizeof("password") - 1);
                        *s++ = 0x01;
                        _libssh2_store_str(&s, (char *)password, password_len);
                        _libssh2_store_u32(&s,
                                           session->userauth_pswd_newpw_len);
                        /* send session->userauth_pswd_newpw separately */

                        session->userauth_pswd_state = libssh2_NB_state_sent2;
                    }

                    if(session->userauth_pswd_state ==
                       libssh2_NB_state_sent2) {
                        rc = _libssh2_transport_send(session,
                                            session->userauth_pswd_data,
                                            session->userauth_pswd_data_len,
                                            (unsigned char *)
                                            session->userauth_pswd_newpw,
                                            session->userauth_pswd_newpw_len);
                        if(rc == LIBSSH2_ERROR_EAGAIN) {
                            return _libssh2_error(session,
                                                  LIBSSH2_ERROR_EAGAIN,
                                                  "Would block waiting");
                        }

                        /* free the allocated packets again */
                        LIBSSH2_FREE(session, session->userauth_pswd_data);
```

[Assistant]
diff --git a/src/userauth.c b/src/userauth.c
index f8e02651c4..43d9ab9b9d 100644
--- a/src/userauth.c
+++ b/src/userauth.c
@@ -80,6 +80,12 @@ static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
         memset(&session->userauth_list_packet_requirev_state, 0,
                sizeof(session->userauth_list_packet_requirev_state));

+        if(username_len > UINT32_MAX - 27) {
+            _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+                           "username_len out of bounds");
+            return NULL;
+        }
+
         session->userauth_list_data_len = username_len + 27;

         if(session->userauth_list_data) {
@@ -316,6 +322,11 @@ userauth_password(LIBSSH2_SESSION *session,
          * 40 = packet_type(1) + username_len(4) + service_len(4) +
          * service(14)"ssh-connection" + method_len(4) + method(8)"password" +
          * chgpwdbool(1) + password_len(4) */
+        if(username_len > UINT32_MAX - 40) {
+            return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+                                  "username_len out of bounds");
+        }
+
         session->userauth_pswd_data_len = username_len + 40;

         session->userauth_pswd_data0 =
@@ -456,7 +467,7 @@ userauth_password(LIBSSH2_SESSION *session,
                         }

                         /* basic data_len + newpw_len(4) */
-                        if(username_len + password_len + 44 <= UINT_MAX) {
+                        if(username_len <= UINT32_MAX - password_len - 44) {
                             session->userauth_pswd_data_len =
                                 username_len + password_len + 44;
                             s = session->userauth_pswd_data =


[System]
You are a security engineer fixing a CVE. You are given the vulnerability description (symptom only) and the vulnerable source window. Author the MINIMAL fix as a unified diff. Follow these rules exactly:
1. Target ONLY the file named in the `# Vulnerable source (...)` header — do not invent or substitute file paths.
2. Modify ONLY code visible in the shown source window.
3. Change as few lines as possible; do not rewrite surrounding logic.
4. Output only the unified diff with no other text.
5. Prefer the minimal structural change: if an existing condition is missing a check, add it inline to that condition rather than inserting a new code block. If existing code is redundant or overcomplicated, replace it — do not add more code around it.
6. Edit the most specific method or class that directly handles the vulnerable operation — not a base class, interface, or Protocol definition.

[User]
# CVE
CVE-2026-7598: libssh2's SSH authentication code failed to validate that the accumulated packet size for the username and password fields remained within the 32-bit unsigned integer limit before arithmetic operations, allowing an attacker to craft an unusually long credential that caused integer overflow in the subsequent length computation. The overflow produced a truncated allocation, and later writes into the undersized buffer caused heap corruption that could be exploited for remote code execution.

# Vulnerable source (src/userauth.c)
```c
 */

#include "libssh2_priv.h"

#include <ctype.h>

/* Needed for struct iovec on some platforms */
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif

#include "transport.h"
#include "session.h"
#include "userauth.h"
#include "userauth_kbd_packet.h"

#include <stdlib.h>  /* strtol() */

/* userauth_list
 *
 * List authentication methods
 * Will yield successful login if "none" happens to be allowable for this user
 * Not a common configuration for any SSH server though
 * username should be NULL, or a null terminated string
 */
static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
                           unsigned int username_len)
{
    unsigned char reply_codes[4] =
        { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE,
          SSH_MSG_USERAUTH_BANNER, 0 };
    /* packet_type(1) + username_len(4) + service_len(4) +
       service(14)"ssh-connection" + method_len(4) = 27 */
    unsigned long methods_len;
    unsigned int banner_len;
    unsigned char *s;
    int rc;

    if(session->userauth_list_state == libssh2_NB_state_idle) {
        /* Zero the whole thing out */
        memset(&session->userauth_list_packet_requirev_state, 0,
               sizeof(session->userauth_list_packet_requirev_state));

        session->userauth_list_data_len = username_len + 27;

        s = session->userauth_list_data =
            LIBSSH2_ALLOC(session, session->userauth_list_data_len);
        if(!session->userauth_list_data) {
            _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                           "Unable to allocate memory for userauth_list");
            return NULL;
        }

        *(s++) = SSH_MSG_USERAUTH_REQUEST;
        _libssh2_store_str(&s, username, username_len);
        _libssh2_store_str(&s, "ssh-connection", 14);
        _libssh2_store_u32(&s, 4); /* send "none" separately */

        session->userauth_list_state = libssh2_NB_state_created;
    }

    if(session->userauth_list_state == libssh2_NB_state_created) {
        rc = _libssh2_transport_send(session, session->userauth_list_data,
                                     session->userauth_list_data_len,
                                     (unsigned char *)"none", 4);
        if(rc == LIBSSH2_ERROR_EAGAIN) {
            _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
                           "Would block requesting userauth list");
            return NULL;
        }
        /* now free the packet that was sent */
        LIBSSH2_FREE(session, session->userauth_list_data);
        session->userauth_list_data = NULL;

        if(rc) {
            _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
                           "Unable to send userauth-none request");
            session->userauth_list_state = libssh2_NB_state_idle;
            return NULL;
        }

        session->userauth_list_state = libssh2_NB_state_sent;
    }

    if(session->userauth_list_state == libssh2_NB_state_sent) {
        rc = _libssh2_packet_requirev(session, reply_codes,
                                      &session->userauth_list_data,
                                      &session->userauth_list_data_len, 0,
                                      NULL, 0,
                               &session->userauth_list_packet_requirev_state);
        if(rc == LIBSSH2_ERROR_EAGAIN) {
            _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
                           "Would block requesting userauth list");
            return NULL;
        }
        else if(rc || (session->userauth_list_data_len < 1)) {
            _libssh2_error(session, rc, "Failed getting response");
            session->userauth_list_state = libssh2_NB_state_idle;
            return NULL;
        }

        if(session->userauth_list_data[0] == SSH_MSG_USERAUTH_BANNER) {
            if(session->userauth_list_data_len < 5) {
                LIBSSH2_FREE(session, session->userauth_list_data);
                session->userauth_list_data = NULL;
                _libssh2_error(session, LIBSSH2_ERROR_PROTO,
                               "Unexpected packet size");
                return NULL;
            }
            banner_len = _libssh2_ntohu32(session->userauth_list_data + 1);
            if(banner_len > session->userauth_list_data_len - 5) {
                LIBSSH2_FREE(session, session->userauth_list_data);
                session->userauth_list_data = NULL;
                _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
                               "Unexpected userauth banner size");
                return NULL;
            }
            session->userauth_banner = LIBSSH2_ALLOC(session, banner_len + 1);
            if(!session->userauth_banner) {
                LIBSSH2_FREE(session, session->userauth_list_data);
                session->userauth_list_data = NULL;
                _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                              "Unable to allocate memory for userauth_banner");
                return NULL;
            }
            memcpy(session->userauth_banner, session->userauth_list_data + 5,
                    banner_len);
            session->userauth_banner[banner_len] = '\0';
            _libssh2_debug((session, LIBSSH2_TRACE_AUTH,
                           "Banner: %s",
                           session->userauth_banner));
            LIBSSH2_FREE(session, session->userauth_list_data);
            session->userauth_list_data = NULL;
            /* SSH_MSG_USERAUTH_BANNER has been handled */
            reply_codes[2] = 0;
            rc = _libssh2_packet_requirev(session, reply_codes,
                                          &session->userauth_list_data,
                                          &session->userauth_list_data_len, 0,
                                          NULL, 0,
                                &session->userauth_list_packet_requirev_state);
            if(rc == LIBSSH2_ERROR_EAGAIN) {
                _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
                               "Would block requesting userauth list");
                return NULL;
            }
            else if(rc || (session->userauth_list_data_len < 1)) {
                _libssh2_error(session, rc, "Failed getting response");
                session->userauth_list_state = libssh2_NB_state_idle;
                return NULL;
            }
        }

        if(session->userauth_list_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
            /* Wow, who'dve thought... */
            _libssh2_error(session, LIBSSH2_ERROR_NONE, "No error");
            LIBSSH2_FREE(session, session->userauth_list_data);
            session->userauth_list_data = NULL;
            session->state |= LIBSSH2_STATE_AUTHENTICATED;
            session->userauth_list_state = libssh2_NB_state_idle;
            return NULL;
        }

        if(session->userauth_list_data_len < 5) {
            LIBSSH2_FREE(session, session->userauth_list_data);
            session->userauth_list_data = NULL;
            _libssh2_error(session, LIBSSH2_ERROR_PROTO,
                           "Unexpected packet size");
            return NULL;
        }

        methods_len = _libssh2_ntohu32(session->userauth_list_data + 1);
        if(methods_len >= session->userauth_list_data_len - 5) {
            _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
                           "Unexpected userauth list size");
            return NULL;
        }

        /* Do note that the memory areas overlap! */
        memmove(session->userauth_list_data, session->userauth_list_data + 5,
                methods_len);
        session->userauth_list_data[methods_len] = '\0';
        _libssh2_debug((session, LIBSSH2_TRACE_AUTH,
                       "Permitted auth methods: %s",
                       session->userauth_list_data));
    }

    session->userauth_list_state = libssh2_NB_state_idle;
    return (char *)session->userauth_list_data;
}

/* libssh2_userauth_list
 *
 * List authentication methods
 * Will yield successful login if "none" happens to be allowable for this user
 * Not a common configuration for any SSH server though
 * username should be NULL, or a null terminated string
 */
LIBSSH2_API char *
libssh2_userauth_list(LIBSSH2_SESSION * session, const char *user,
                      unsigned int user_len)
{
    char *ptr;
    BLOCK_ADJUST_ERRNO(ptr, session,
                       userauth_list(session, user, user_len));
    return ptr;
}

/* libssh2_userauth_banner
 *
 * Retrieve banner message from server, if available.
 * When no such message is sent by server or if no authentication attempt has
 * been made, this function returns LIBSSH2_ERROR_MISSING_AUTH_BANNER.
 */
LIBSSH2_API int
libssh2_userauth_banner(LIBSSH2_SESSION *session, char **banner)
{
    if(!session)
        return LIBSSH2_ERROR_MISSING_USERAUTH_BANNER;

    if(!session->userauth_banner) {
        return _libssh2_error(session,
                              LIBSSH2_ERROR_MISSING_USERAUTH_BANNER,
                              "Missing userauth banner");
    }

    if(banner)
        *banner = session->userauth_banner;

    return LIBSSH2_ERROR_NONE;
}

/*
 * libssh2_userauth_authenticated
 *
 * Returns: 0 if not yet authenticated
 *          1 if already authenticated
 */
LIBSSH2_API int
libssh2_userauth_authenticated(LIBSSH2_SESSION * session)
{
    return (session->state & LIBSSH2_STATE_AUTHENTICATED) ? 1 : 0;
}

/* userauth_password
 * Plain ol' login
 */
static int
userauth_password(LIBSSH2_SESSION *session,
                  const char *username, unsigned int username_len,
                  const unsigned char *password, unsigned int password_len,
                  LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)))
{
    unsigned char *s;
    static const unsigned char reply_codes[4] =
        { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE,
          SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0
        };
    int rc;

    if(session->userauth_pswd_state == libssh2_NB_state_idle) {
        /* Zero the whole thing out */
        memset(&session->userauth_pswd_packet_requirev_state, 0,
               sizeof(session->userauth_pswd_packet_requirev_state));

        /*
         * 40 = packet_type(1) + username_len(4) + service_len(4) +
         * service(14)"ssh-connection" + method_len(4) + method(8)"password" +
         * chgpwdbool(1) + password_len(4) */
        session->userauth_pswd_data_len = username_len + 40;

        session->userauth_pswd_data0 =
            (unsigned char) ~SSH_MSG_USERAUTH_PASSWD_CHANGEREQ;

        /* TODO: remove this alloc with a fixed buffer in the session
           struct */
        s = session->userauth_pswd_data =
            LIBSSH2_ALLOC(session, session->userauth_pswd_data_len);
        if(!session->userauth_pswd_data) {
            return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                                  "Unable to allocate memory for "
                                  "userauth-password request");
        }

        *(s++) = SSH_MSG_USERAUTH_REQUEST;
        _libssh2_store_str(&s, username, username_len);
        _libssh2_store_str(&s, "ssh-connection", sizeof("ssh-connection") - 1);
        _libssh2_store_str(&s, "password", sizeof("password") - 1);
        *s++ = '\0';
        _libssh2_store_u32(&s, password_len);
        /* 'password' is sent separately */

        _libssh2_debug((session, LIBSSH2_TRACE_AUTH,
                       "Attempting to login using password authentication"));

        session->userauth_pswd_state = libssh2_NB_state_created;
    }

    if(session->userauth_pswd_state == libssh2_NB_state_created) {
        rc = _libssh2_transport_send(session, session->userauth_pswd_data,
                                     session->userauth_pswd_data_len,
                                     password, password_len);
        if(rc == LIBSSH2_ERROR_EAGAIN) {
            return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
                                  "Would block writing password request");
        }

        /* now free the sent packet */
        LIBSSH2_FREE(session, session->userauth_pswd_data);
        session->userauth_pswd_data = NULL;

        if(rc) {
            session->userauth_pswd_state = libssh2_NB_state_idle;
            return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
                                  "Unable to send userauth-password request");
        }

        session->userauth_pswd_state = libssh2_NB_state_sent;
    }

password_response:

    if((session->userauth_pswd_state == libssh2_NB_state_sent)
        || (session->userauth_pswd_state == libssh2_NB_state_sent1)
        || (session->userauth_pswd_state == libssh2_NB_state_sent2)) {
        if(session->userauth_pswd_state == libssh2_NB_state_sent) {
            rc = _libssh2_packet_requirev(session, reply_codes,
                                          &session->userauth_pswd_data,
                                          &session->userauth_pswd_data_len,
                                          0, NULL, 0,
                                          &session->
                                          userauth_pswd_packet_requirev_state);

            if(rc) {
                if(rc != LIBSSH2_ERROR_EAGAIN)
                    session->userauth_pswd_state = libssh2_NB_state_idle;

                return _libssh2_error(session, rc,
                                      "Waiting for password response");
            }
            else if(session->userauth_pswd_data_len < 1) {
                session->userauth_pswd_state = libssh2_NB_state_idle;
                return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
                                      "Unexpected packet size");
            }

            if(session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
                _libssh2_debug((session, LIBSSH2_TRACE_AUTH,
                               "Password authentication successful"));
                LIBSSH2_FREE(session, session->userauth_pswd_data);
                session->userauth_pswd_data = NULL;
                session->state |= LIBSSH2_STATE_AUTHENTICATED;
                session->userauth_pswd_state = libssh2_NB_state_idle;
                return 0;
            }
            else if(session->userauth_pswd_data[0] ==
                    SSH_MSG_USERAUTH_FAILURE) {
                _libssh2_debug((session, LIBSSH2_TRACE_AUTH,
                               "Password authentication failed"));
                LIBSSH2_FREE(session, session->userauth_pswd_data);
                session->userauth_pswd_data = NULL;
                session->userauth_pswd_state = libssh2_NB_state_idle;
                return _libssh2_error(session,
                                      LIBSSH2_ERROR_AUTHENTICATION_FAILED,
                                      "Authentication failed "
                                      "(username/password)");
            }

            session->userauth_pswd_newpw = NULL;
            session->userauth_pswd_newpw_len = 0;

            session->userauth_pswd_state = libssh2_NB_state_sent1;
        }

        if(session->userauth_pswd_data_len < 1) {
            session->userauth_pswd_state = libssh2_NB_state_idle;
            return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
                                  "Unexpected packet size");
        }

        if((session->userauth_pswd_data[0] ==
             SSH_MSG_USERAUTH_PASSWD_CHANGEREQ)
            || (session->userauth_pswd_data0 ==
                SSH_MSG_USERAUTH_PASSWD_CHANGEREQ)) {
            session->userauth_pswd_data0 = SSH_MSG_USERAUTH_PASSWD_CHANGEREQ;

            if((session->userauth_pswd_state == libssh2_NB_state_sent1) ||
                (session->userauth_pswd_state == libssh2_NB_state_sent2)) {
                if(session->userauth_pswd_state == libssh2_NB_state_sent1) {
                    _libssh2_debug((session, LIBSSH2_TRACE_AUTH,
                                   "Password change required"));
                    LIBSSH2_FREE(session, session->userauth_pswd_data);
                    session->userauth_pswd_data = NULL;
                }
                if(passwd_change_cb) {
                    if(session->userauth_pswd_state ==
                       libssh2_NB_state_sent1) {
                        passwd_change_cb(session,
                                         &session->userauth_pswd_newpw,
                                         &session->userauth_pswd_newpw_len,
                                         &session->abstract);
                        if(!session->userauth_pswd_newpw) {
                            return _libssh2_error(session,
                                                LIBSSH2_ERROR_PASSWORD_EXPIRED,
                                                  "Password expired, and "
                                                  "callback failed");
                        }

                        /* basic data_len + newpw_len(4) */
                        if(username_len + password_len + 44 <= UINT_MAX) {
                            session->userauth_pswd_data_len =
                                username_len + password_len + 44;
                            s = session->userauth_pswd_data =
                                LIBSSH2_ALLOC(session,
                                              session->userauth_pswd_data_len);
                        }
                        else {
                            s = session->userauth_pswd_data = NULL;
                            session->userauth_pswd_data_len = 0;
                        }

                        if(!session->userauth_pswd_data) {
                            LIBSSH2_FREE(session,
                                         session->userauth_pswd_newpw);
                            session->userauth_pswd_newpw = NULL;
                            return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                                                  "Unable to allocate memory "
                                                  "for userauth password "
                                                  "change request");
                        }

                        *(s++) = SSH_MSG_USERAUTH_REQUEST;
                        _libssh2_store_str(&s, username, username_len);
                        _libssh2_store_str(&s, "ssh-connection",
                                           sizeof("ssh-connection") - 1);
                        _libssh2_store_str(&s, "password",
                                           sizeof("password") - 1);
                        *s++ = 0x01;
                        _libssh2_store_str(&s, (char *)password, password_len);
                        _libssh2_store_u32(&s,
                                           session->userauth_pswd_newpw_len);
                        /* send session->userauth_pswd_newpw separately */

                        session->userauth_pswd_state = libssh2_NB_state_sent2;
                    }

                    if(session->userauth_pswd_state ==
                       libssh2_NB_state_sent2) {
                        rc = _libssh2_transport_send(session,
                                            session->userauth_pswd_data,
                                            session->userauth_pswd_data_len,
                                            (unsigned char *)
                                            session->userauth_pswd_newpw,
                                            session->userauth_pswd_newpw_len);
                        if(rc == LIBSSH2_ERROR_EAGAIN) {
                            return _libssh2_error(session,
                                                  LIBSSH2_ERROR_EAGAIN,
                                                  "Would block waiting");
                        }

                        /* free the allocated packets again */
                        LIBSSH2_FREE(session, session->userauth_pswd_data);
```

[Assistant]
diff --git a/src/userauth.c b/src/userauth.c
index f8e02651c4..43d9ab9b9d 100644
--- a/src/userauth.c
+++ b/src/userauth.c
@@ -80,6 +80,12 @@ static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
         memset(&session->userauth_list_packet_requirev_state, 0,
                sizeof(session->userauth_list_packet_requirev_state));

+        if(username_len > UINT32_MAX - 27) {
+            _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+                           "username_len out of bounds");
+            return NULL;
+        }
+
         session->userauth_list_data_len = username_len + 27;

         if(session->userauth_list_data) {
@@ -316,6 +322,11 @@ userauth_password(LIBSSH2_SESSION *session,
          * 40 = packet_type(1) + username_len(4) + service_len(4) +
          * service(14)"ssh-connection" + method_len(4) + method(8)"password" +
          * chgpwdbool(1) + password_len(4) */
+        if(username_len > UINT32_MAX - 40) {
+            return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+                                  "username_len out of bounds");
+        }
+
         session->userauth_pswd_data_len = username_len + 40;

         session->userauth_pswd_data0 =
@@ -456,7 +467,7 @@ userauth_password(LIBSSH2_SESSION *session,
                         }

                         /* basic data_len + newpw_len(4) */
-                        if(username_len + password_len + 44 <= UINT_MAX) {
+                        if(username_len <= UINT32_MAX - password_len - 44) {
                             session->userauth_pswd_data_len =
                                 username_len + password_len + 44;
                             s = session->userauth_pswd_data =