Re: Interrupted fputc followed by fprintf in _IOLBF mode causes core dump

From: Guy Yur <guyyur_at_gmail.com>
Date: Fri, 25 Mar 2022 17:48:56 UTC
On Fri, Mar 25, 2022 at 5:50 PM Mark Johnston <markj@freebsd.org> wrote:
>
> On Fri, Mar 25, 2022 at 03:18:40PM +0300, Guy Yur wrote:
> > Hi,
> >
> > dhcpcd on head (Mar 24) and 13.1-BETA2 crashes in fprintf/__sfvwrite.
> > It doesn't crash if If I revert the __sflush/__sfvwrite commits:
> > 86a16ada1ea608408cec370171d9f59353e97c77 and
> > bafaa70b6f9098d83d074968c8e6747ecec1e118.
> >
> > ...
>
> Thanks for the reproducer.  The bug is akin to that fixed by
> bafaa70b6f9098d83d074968c8e6747ecec1e118.  Could you please verify that
> the patch below fixes the original bug?
>
> commit 11f817e847b2f06bd543d1bd6cfdff53d69842dc
> Author: Mark Johnston <markj@FreeBSD.org>
> Date:   Fri Mar 25 10:46:24 2022 -0400
>
>     libc: Restore fp state upon flush error in fputc
>
> diff --git a/lib/libc/stdio/wbuf.c b/lib/libc/stdio/wbuf.c
> index e1aa70243e94..6cd75145a271 100644
> --- a/lib/libc/stdio/wbuf.c
> +++ b/lib/libc/stdio/wbuf.c
> @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
>  int
>  __swbuf(int c, FILE *fp)
>  {
> +       unsigned char *old_p;
>         int n;
>
>         /*
> @@ -87,8 +88,15 @@ __swbuf(int c, FILE *fp)
>         }
>         fp->_w--;
>         *fp->_p++ = c;
> -       if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n'))
> -               if (__fflush(fp))
> +       old_p = fp->_p;
> +       if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n')) {
> +               if (__fflush(fp)) {
> +                       if (fp->_p == old_p) {
> +                               fp->_p--;
> +                               fp->_w++;
> +                       }
>                         return (EOF);
> +               }
> +       }
>         return (c);
>  }

Hi,

With this patch applied, dhcpcd doesn't crash.

Thanks,
Guy