This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] vfprint: add missing errnos
On Fri, Mar 02, 2012 at 11:53:20AM -0800, Kees Cook wrote:
> On Fri, Mar 02, 2012 at 11:10:13AM -0800, Paul Eggert wrote:
> > On 03/02/2012 10:53 AM, Kees Cook wrote:
> > > + if (nargs > SIZE_MAX / bytes_per_arg)
> > > + {
> > > + done = -1;
> > > + goto all_done;
> > > + }
> >
> > I just noticed: isn't vfprintf supposed to set errno on failure?
> > The above code neglects to do that.
> > Presumably it should set errno to ENOMEM,
> > using __set_errno.
>
> Good point. However, this needs fixing in more places than just the
> vfprintf-nargs patch.
>
> Out of about 20 failure conditions, only 3 seem to set errno:
I'm wrong -- most of these are just errno-fall-through from various
other functions called from vfprintf. There were, however, a few that
seemed missing, including the one from the vfprintf-nargs patch.
2012-03-02 Kees Cook <keescook@chromium.org>
* stdio-common/vfprintf.c (vfprintf): add missing errno settings.
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index 31a7c98..a496c3c 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -822,7 +822,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
\
if (function_done < 0) \
{ \
- /* Error in print handler. */ \
+ /* Error in print handler; up to handler to set errno. */ \
done = -1; \
goto all_done; \
} \
@@ -876,7 +876,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
\
if (function_done < 0) \
{ \
- /* Error in print handler. */ \
+ /* Error in print handler; up to handler to set errno. */ \
done = -1; \
goto all_done; \
} \
@@ -1117,7 +1117,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
&mbstate); \
if (len == (size_t) -1) \
{ \
- /* Something went wron gduring the conversion. Bail out. */ \
+ /* Something went wrong during the conversion. Bail out. */ \
done = -1; \
goto all_done; \
} \
@@ -1188,6 +1188,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
if (__mbsnrtowcs (ignore, &str2, strend - str2, \
ignore_size, &ps) == (size_t) -1) \
{ \
+ /* Conversion function has set errno. */ \
done = -1; \
goto all_done; \
} \
@@ -1605,6 +1606,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
if (spec == L_('\0'))
{
/* The format string ended before the specifier is complete. */
+ __set_errno (EINVAL);
done = -1;
goto all_done;
}
@@ -1710,6 +1712,7 @@ do_positional:
/* Check for potential integer overflow. */
if (nargs > SIZE_MAX / bytes_per_arg)
{
+ __set_errno (ERANGE);
done = -1;
goto all_done;
}
@@ -1947,6 +1950,7 @@ do_positional:
about # of chars. */
if (function_done < 0)
{
+ __set_errno (EINVAL);
done = -1;
goto all_done;
}
@@ -1981,6 +1985,7 @@ do_positional:
of chars. */
if (function_done < 0)
{
+ __set_errno (EINVAL);
done = -1;
goto all_done;
}
--
1.7.5.4
--
Kees Cook @outflux.net