Hi,

Bulat Musin wrote on Tue, Jan 02, 2018 at 09:47:39PM +0300:

> /bin/dd/args.c r1.28
> get_off(char *val)
> 
>       num = strtoll(val, &expr, 0);
>       if (num == LLONG_MAX)                   /* Overflow. */
>               err(1, "%s", oper);
> 
> Incorrect checking of overflow.
> Firstly, set errno to 0 before calling strtoll.
> Secondly: check of errno == ERANGE. =>

Clearly an edge case, but i think you are right that it ought to
be fixed, if only to avoid the bad example.  I also checked that
clobbering the previous value of errno is not a problem here.

OK for the patch at the end?

Testing - before:

 $ /obin/dd if=/dev/zero of=/dev/null bs=1 count=2 skip=0x7ffffffffffffffe
2+0 records in
2+0 records out
2 bytes transferred in 0.000 secs (116877 bytes/sec)
 $ echo $?
0
 $ /obin/dd if=/dev/zero of=/dev/null bs=1 count=2 skip=0x7fffffffffffffff
dd: skip: Undefined error: 0    /* wrong */
 $ echo $?
1                               /* wrong */
 $ /obin/dd if=/dev/zero of=/dev/null bs=1 count=2 skip=0x8000000000000000
dd: skip: Result too large
 $ echo $?
1

Testing - after:

 $ dd if=/dev/zero of=/dev/null bs=1 count=2 skip=0x7ffffffffffffffe
2+0 records in
2+0 records out
2 bytes transferred in 0.000 secs (230920 bytes/sec)
 $ echo $?
0
 $ dd if=/dev/zero of=/dev/null bs=1 count=2 skip=0x7fffffffffffffff
2+0 records in
2+0 records out
2 bytes transferred in 0.000 secs (78453 bytes/sec)
 $ echo $?
0
 $ dd if=/dev/zero of=/dev/null bs=1 count=2 skip=0x8000000000000000
dd: skip: Result too large
 $ echo $?
1

Yours,
  Ingo


Index: args.c
===================================================================
RCS file: /cvs/src/bin/dd/args.c,v
retrieving revision 1.28
diff -u -p -r1.28 args.c
--- args.c      16 Aug 2016 16:44:55 -0000      1.28
+++ args.c      2 Jan 2018 22:47:19 -0000
@@ -406,8 +406,9 @@ get_off(char *val)
        off_t num, t;
        char *expr;
 
+       errno = 0;
        num = strtoll(val, &expr, 0);
-       if (num == LLONG_MAX)                   /* Overflow. */
+       if (num == LLONG_MAX && errno == ERANGE)        /* Overflow. */
                err(1, "%s", oper);
        if (expr == val)                        /* No digits. */
                errx(1, "%s: illegal numeric value", oper);

Reply via email to