Fix overflow handling in dd(1)

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Fix overflow handling in dd(1)

William Orr-2
This diff fixes the overflow handling in dd(1).

Before, if provided an argument of SIZE_T_MAX, dd(1) would exit with

dd: count: Undefined error: 0

since strtoul(3) doesn't set errno when its argument is equal to ULONG_MAX.
Now, dd(1) handles SIZE_T_MAX gracefully.

Index: args.c
===================================================================
RCS file: /cvs/src/bin/dd/args.c,v
retrieving revision 1.25
diff -u -b -w -p -r1.25 args.c
--- args.c 21 May 2014 06:23:02 -0000 1.25
+++ args.c 14 Jun 2014 04:02:51 -0000
@@ -196,8 +196,7 @@ static void
 f_count(char *arg)
 {
 
- if ((cpy_cnt = get_bsz(arg)) == 0)
- cpy_cnt = (size_t)-1;
+ cpy_cnt = get_bsz(arg);
 }
 
 static void
@@ -323,8 +322,9 @@ get_bsz(char *val)
  size_t num, t;
  char *expr;
 
+ errno = 0;
  num = strtoul(val, &expr, 0);
- if (num == SIZE_T_MAX) /* Overflow. */
+ if (num == SIZE_T_MAX && errno == ERANGE) /* Overflow. */
  err(1, "%s", oper);
  if (expr == val) /* No digits. */
  errx(1, "%s: illegal numeric value", oper);
Index: dd.c
===================================================================
RCS file: /cvs/src/bin/dd/dd.c,v
retrieving revision 1.18
diff -u -b -w -p -r1.18 dd.c
--- dd.c 1 Jun 2013 16:46:49 -0000 1.18
+++ dd.c 14 Jun 2014 04:02:51 -0000
@@ -77,7 +77,7 @@ main(int argc, char *argv[])
 
  atexit(summary);
 
- if (cpy_cnt != (size_t)-1) {
+ if (cpy_cnt != 0) {
  while (files_cnt--)
  dd_in();
  }

Reply | Threaded
Open this post in threaded view
|

Re: diff: Fix overflow handling in dd(1)

William Orr-2
Any interest in this?

I’ve made a slight addition, to check for negative numbers in get_bsz.

Index: args.c
===================================================================
RCS file: /cvs/src/bin/dd/args.c,v
retrieving revision 1.25
diff -u -b -w -p -r1.25 args.c
--- args.c 21 May 2014 06:23:02 -0000 1.25
+++ args.c 22 Jun 2014 06:33:29 -0000
@@ -196,8 +196,7 @@ static void
f_count(char *arg)
{

- if ((cpy_cnt = get_bsz(arg)) == 0)
- cpy_cnt = (size_t)-1;
+ cpy_cnt = get_bsz(arg);
}

static void
@@ -323,8 +322,12 @@ get_bsz(char *val)
        size_t num, t;
        char *expr;

+ if (val[0] == '-')
+ errx(1, "%s: cannot be negative", oper);
+
+ errno = 0;
        num = strtoul(val, &expr, 0);
- if (num == SIZE_T_MAX) /* Overflow. */
+ if (num == SIZE_T_MAX && errno == ERANGE) /* Overflow. */
                err(1, "%s", oper);
        if (expr == val) /* No digits. */
                errx(1, "%s: illegal numeric value", oper);
Index: dd.c
===================================================================
RCS file: /cvs/src/bin/dd/dd.c,v
retrieving revision 1.18
diff -u -b -w -p -r1.18 dd.c
--- dd.c 1 Jun 2013 16:46:49 -0000 1.18
+++ dd.c 22 Jun 2014 06:33:29 -0000
@@ -77,7 +77,7 @@ main(int argc, char *argv[])

        atexit(summary);

- if (cpy_cnt != (size_t)-1) {
+ if (cpy_cnt != 0) {
                while (files_cnt--)
                        dd_in();
        }
On Jun 13, 2014, at 9:26 PM, William Orr <[hidden email]> wrote:

> This diff fixes the overflow handling in dd(1).
>
> Before, if provided an argument of SIZE_T_MAX, dd(1) would exit with
>
> dd: count: Undefined error: 0
>
> since strtoul(3) doesn't set errno when its argument is equal to ULONG_MAX.
> Now, dd(1) handles SIZE_T_MAX gracefully.
>
> Index: args.c
> ===================================================================
> RCS file: /cvs/src/bin/dd/args.c,v
> retrieving revision 1.25
> diff -u -b -w -p -r1.25 args.c
> --- args.c 21 May 2014 06:23:02 -0000 1.25
> +++ args.c 14 Jun 2014 04:02:51 -0000
> @@ -196,8 +196,7 @@ static void
> f_count(char *arg)
> {
>
> - if ((cpy_cnt = get_bsz(arg)) == 0)
> - cpy_cnt = (size_t)-1;
> + cpy_cnt = get_bsz(arg);
> }
>
> static void
> @@ -323,8 +322,9 @@ get_bsz(char *val)
>   size_t num, t;
>   char *expr;
>
> + errno = 0;
>   num = strtoul(val, &expr, 0);
> - if (num == SIZE_T_MAX) /* Overflow. */
> + if (num == SIZE_T_MAX && errno == ERANGE) /* Overflow. */
>   err(1, "%s", oper);
>   if (expr == val) /* No digits. */
>   errx(1, "%s: illegal numeric value", oper);
> Index: dd.c
> ===================================================================
> RCS file: /cvs/src/bin/dd/dd.c,v
> retrieving revision 1.18
> diff -u -b -w -p -r1.18 dd.c
> --- dd.c 1 Jun 2013 16:46:49 -0000 1.18
> +++ dd.c 14 Jun 2014 04:02:51 -0000
> @@ -77,7 +77,7 @@ main(int argc, char *argv[])
>
>   atexit(summary);
>
> - if (cpy_cnt != (size_t)-1) {
> + if (cpy_cnt != 0) {
>   while (files_cnt--)
>   dd_in();
>   }
>


signature.asc (817 bytes) Download Attachment