On Thu, Sep 25, 2014 at 10:37:28PM +0000, Xin LI wrote:
> Author: delphij
> Date: Thu Sep 25 22:37:27 2014
> New Revision: 272144
> URL: http://svnweb.freebsd.org/changeset/base/272144
> 
> Log:
>   The strtol(3) family of functions would set errno when it hits one.
>   Check errno and handle it as invalid input.
>   

But this requires explicitely setting errno to 0 before strto* call,
otherwise you cannot know whether errno is meaningful when you test it.

Also it looks like the code would use some deduplications with macros or
something.


>   Obtained from:      HardenedBSD
>   Submitted by:       David CARLIER <devne...@gmail.com>
>   MFC after:  2 weeks
> 
> Modified:
>   head/sbin/sysctl/sysctl.c
> 
> Modified: head/sbin/sysctl/sysctl.c
> ==============================================================================
> --- head/sbin/sysctl/sysctl.c Thu Sep 25 22:22:57 2014        (r272143)
> +++ head/sbin/sysctl/sysctl.c Thu Sep 25 22:37:27 2014        (r272144)
> @@ -305,7 +305,8 @@ parse(const char *string, int lineno)
>                               } else {
>                                       intval = (int)strtol(newval, &endptr,
>                                           0);
> -                                     if (endptr == newval || *endptr != 
> '\0') {
> +                                     if (errno != 0 || endptr == newval ||
> +                                             *endptr != '\0') {
>                                               warnx("invalid integer '%s'%s",
>                                                   (char *)newval, line);
>                                               return (1);
> @@ -316,7 +317,8 @@ parse(const char *string, int lineno)
>                               break;
>                       case CTLTYPE_UINT:
>                               uintval = (int) strtoul(newval, &endptr, 0);
> -                             if (endptr == newval || *endptr != '\0') {
> +                             if (errno != 0 || endptr == newval ||
> +                                     *endptr != '\0') {
>                                       warnx("invalid unsigned integer '%s'%s",
>                                           (char *)newval, line);
>                                       return (1);
> @@ -326,7 +328,8 @@ parse(const char *string, int lineno)
>                               break;
>                       case CTLTYPE_LONG:
>                               longval = strtol(newval, &endptr, 0);
> -                             if (endptr == newval || *endptr != '\0') {
> +                             if (errno != 0 || endptr == newval ||
> +                                     *endptr != '\0') {
>                                       warnx("invalid long integer '%s'%s",
>                                           (char *)newval, line);
>                                       return (1);
> @@ -336,7 +339,8 @@ parse(const char *string, int lineno)
>                               break;
>                       case CTLTYPE_ULONG:
>                               ulongval = strtoul(newval, &endptr, 0);
> -                             if (endptr == newval || *endptr != '\0') {
> +                             if (errno != 0 || endptr == newval ||
> +                                     *endptr != '\0') {
>                                       warnx("invalid unsigned long integer"
>                                           " '%s'%s", (char *)newval, line);
>                                       return (1);
> @@ -348,7 +352,8 @@ parse(const char *string, int lineno)
>                               break;
>                       case CTLTYPE_S64:
>                               i64val = strtoimax(newval, &endptr, 0);
> -                             if (endptr == newval || *endptr != '\0') {
> +                             if (errno != 0 || endptr == newval ||
> +                                     *endptr != '\0') {
>                                       warnx("invalid int64_t '%s'%s",
>                                           (char *)newval, line);
>                                       return (1);
> @@ -358,7 +363,8 @@ parse(const char *string, int lineno)
>                               break;
>                       case CTLTYPE_U64:
>                               u64val = strtoumax(newval, &endptr, 0);
> -                             if (endptr == newval || *endptr != '\0') {
> +                             if (errno != 0 || endptr == newval ||
> +                                     *endptr != '\0') {
>                                       warnx("invalid uint64_t '%s'%s",
>                                           (char *)newval, line);
>                                       return (1);
> @@ -669,14 +675,16 @@ set_IK(const char *str, int *val)
>       p = &str[len - 1];
>       if (*p == 'C' || *p == 'F') {
>               temp = strtof(str, &endptr);
> -             if (endptr == str || endptr != p)
> +             if (errno != 0 || endptr == str ||
> +                     endptr != p)
>                       return (0);
>               if (*p == 'F')
>                       temp = (temp - 32) * 5 / 9;
>               kelv = temp * 10 + 2732;
>       } else {
>               kelv = (int)strtol(str, &endptr, 10);
> -             if (endptr == str || *endptr != '\0')
> +             if (errno != 0 || endptr == str ||
> +                     *endptr != '\0')
>                       return (0);
>       }
>       *val = kelv;
> 

-- 
Mateusz Guzik <mjguzik gmail.com>
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to