[PATCH v5] libio: Fix CVE-2026-18374 heap buffer overflow in ccs= handling

Florian Weimer fweimer@redhat.com
Thu Sep 3 12:43:13 GMT 2026


* 손동균:

> Thanks for the feedback, Florian!
>
> Changes since v4 (responding to Florian's review):
>  - Unified the two if statements into a single condition since their bodies
>    were identical. The first condition checks for empty charset after strip(),
>    and the second checks for conversion module loading failure. Both result
>    in the same error handling.
>  - Removed the test case from libio/tst-fopenloc.c as suggested. Florian
>    will submit a test separately.
>
> When fopen() is called with a ,ccs= parameter whose value becomes empty
> after strip(), the code must reject it with EINVAL instead of attempting
> to use it.  The original upstr() fallback could read past the ',' delimiter
> and cause a heap buffer overflow.
>
> The fix checks if the charset specification is empty after strip() and
> returns EINVAL immediately, preventing the overflow and following the
> approach described in BZ #34574.
>
> CVE-2026-18374 - CVSS 4.9 (AV:L/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L)
> Reported-by: AISLE in partnership with Red Hat
> Signed-off-by: Dongkyun Son <dongkyun.s@samsung.com>
> ---
>  libio/fileops.c | 10 +++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/libio/fileops.c b/libio/fileops.c
> index 9348d7c3a1..5a249725ee 100644
> --- a/libio/fileops.c
> +++ b/libio/fileops.c
> @@ -355,8 +355,14 @@ _IO_new_file_fopen (FILE *fp, const char *filename, const char *mode,
>  	  *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0';
>  	  strip (ccs, ccs);
>  
> -	  if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0'
> -				   ? upstr (ccs, cs + 5) : ccs) != 0)
> +	  /* After stripping, ccs[2] == '\0' means the charset name is empty.
> +	     This is not a valid charset and would cause problems downstream.
> +	     Reject it with EINVAL (BZ #34574, CVE-2026-18374).  */
> +	  if (ccs[2] == '\0' || __wcsmbs_named_conv (&fcts, ccs) != 0)
>  	    {
> +	      /* Either the charset name is empty after strip(), or conversion
> +		 modules cannot be loaded.  This means we cannot proceed since
> +		 the user explicitly asked for character conversion.  */
>  	      (void) _IO_file_close_it (fp);
>  	      free (ccs);
>  	      __set_errno (EINVAL);

The patch is corrupted, the - lines deleting the old comment are
missing:

-	      /* Something went wrong, we cannot load the conversion modules.
-		 This means we cannot proceed since the user explicitly asked
-		 for these.  */

Not sure how this happened.  I'm going to send a v6.  I'm not sure if I
did the ks_c_5601-1987 to UTF-8 conversion correctly.

Thanks,
Florian



More information about the Libc-alpha mailing list