Comment 17 for bug 36036

Revision history for this message
Frederic Weisbecker (chantecode) wrote :

Hi all.

I'm using dd with french locale and have this segfault.
I use dapper with a dd included in coreutils (5.93-5ubuntu4).

Here is a backtrace with gdb (remade from the source from packages.ubuntu.com):

#0 0xb7ead2a3 in strlen () from /lib/tls/i686/cmov/libc.so.6
#1 0xb7e812e4 in vfprintf () from /lib/tls/i686/cmov/libc.so.6
#2 0xb7e7dd7c in cuserid () from /lib/tls/i686/cmov/libc.so.6
#3 0xb7e7dfbb in vfprintf () from /lib/tls/i686/cmov/libc.so.6
#4 0xb7e866af in fprintf () from /lib/tls/i686/cmov/libc.so.6
#5 0x080497b2 in print_stats () at dd.c:553
#6 0x0804b3fa in main (argc=5, argv=0xbfea0c24) at dd.c:600

If you take a look at dd.c on line 553 you have that:

fprintf (stderr,
    ngettext ("1 byte (1 B) copied",
       "%"PRIuMAX" bytes (%s) copied",
       MIN (w_bytes, ULONG_MAX)),
    w_bytes,
    human_readable (w_bytes, hbuf, human_opts, 1, 1));

If more than one byte is transferred, the second line in ngettext is used (the plural one) and the first format ("%"PRIuMax which give something like %ul) will load MIN (w_bytes, ULONG_MAX). After that, fprintf will load the next arg for the symbol %s and this arg is w_bytes which is an unsigned long I guess. It is not a string, so it will crash the strlen inside fprintf. Here is the segfault. I guess w_bytes as a third argument has no reason to exist. The third argument has to be the actual fourth: human_readable(....)

If only a byte is transferred, you not have the segfault because there is no format chars wich load next arguments, this because the singular line will be used.

Here is a small patch to correct this:

--- dd (copie).c 2005-11-02 14:18:47.000000000 +0100
+++ dd.c 2006-06-21 06:35:56.000000000 +0200
@@ -554,7 +554,6 @@
     ngettext ("1 byte (1 B) copied",
        "%"PRIuMAX" bytes (%s) copied",
        MIN (w_bytes, ULONG_MAX)),
- w_bytes,
     human_readable (w_bytes, hbuf, human_opts, 1, 1));

   if (start_time < now)

Note that I have a new bug now with this patch: "%"PRIuMAX" should give "%llu" by me. But on output it gives (as an example):

%<PRIuMAX> octets (3 B) copiés, 0,000179 seconde, 16,8 kB/s

That's strange, I can't understand that....