dd segfaults which it doesn't with the breezy package (on dapper)

Bug #36036 reported by Karel Demeyer on 2006-03-22
16
Affects Status Importance Assigned to Milestone
coreutils (Ubuntu)
Medium
Unassigned

Bug Description

Segfault when I write an image to my /dev/sde1 partition on my ipod. When I downgrade coreutils to breezy it has no problems whatsoever

Matt Zimmerman (mdz) wrote :

Please be more specific about how you triggered the segfault. Give us enough detail so that we can experience the problem ourselves in order to debug it.

If you're unsure about what information we may need, this document may help: http://www.chiark.greenend.org.uk/~sgtatham/bugs.html

Changed in coreutils:
status: Unconfirmed → Needs Info
Karel Demeyer (kmdemeye) wrote :

backtrace:

scapor@kryptonix:~/Desktop/linux$ gdb -args dd if=my_sw.bin of=/dev/sde1
GNU gdb 6.4-debian
Copyright 2005 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...(no debugging symbols found)
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".

(gdb) run
Starting program: /bin/dd if=my_sw.bin of=/dev/sde1
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
[Thread debugging using libthread_db enabled]
[New Thread -1209534784 (LWP 23252)]
(no debugging symbols found)
10035+1 records in
10035+1 records out

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1209534784 (LWP 23252)]
0xb7efc2a3 in strlen () from /lib/tls/i686/cmov/libc.so.6
(gdb) bt full
#0 0xb7efc2a3 in strlen () from /lib/tls/i686/cmov/libc.so.6
No symbol table info available.
#1 0xb7ed02e4 in vfprintf () from /lib/tls/i686/cmov/libc.so.6
No symbol table info available.
#2 0xb7eccd7c in cuserid () from /lib/tls/i686/cmov/libc.so.6
No symbol table info available.
#3 0xb7eccfbb in vfprintf () from /lib/tls/i686/cmov/libc.so.6
No symbol table info available.
#4 0xb7ed56af in fprintf () from /lib/tls/i686/cmov/libc.so.6
No symbol table info available.
#5 0x080497b2 in ?? ()
No symbol table info available.
#6 0xb7fbcf80 in _IO_list_all () from /lib/tls/i686/cmov/libc.so.6
No symbol table info available.
#7 0xb7d69d5d in ?? ()
No symbol table info available.
#8 0x004e66a4 in ?? ()
No symbol table info available.
#9 0x00000000 in ?? ()
No symbol table info available.

libc6-i686 2.3.6-0ubuntu16
Linux kryptonix.homelinux.org 2.6.15-20-686 #1 SMP PREEMPT Tue Apr 4 18:37:00 UTC 2006 i686 GNU/Linux

Björn Lindqvist (bjourne) wrote :

I can confirm this. This command consistently segfaults:

$ dd if=boot.img of=/dev/fd0
2880+0 records in
2880+0 records out
Segmenteringsfel

I'll attach the boot.img file so that you can repeat it.

"dd if=boot.img of=/dev/fd0" consistently segfaults in Dapper.

Rodrigo Belem (rbelem) wrote :

I can confirm this too.

With current dapper coreutils package dd segfaults

rodrigo@ubuntustrong:~/downloads/h2200/backup$ sudo dd if=2ndstage.rescue of=/dev/hde bs=1K
1280+0 records in
1280+0 records out
Falha de segmentação

but when I downgrade to the first breezy coreutils release it works well.

rodrigo@ubuntustrong:~/downloads/h2200/backup$ dpkg -i --force-all coreutils_5.2.1-2ubuntu2_amd64.deb
dpkg: operação requer acesso de leitura/gravação à área de status do dpkg
rodrigo@ubuntustrong:~/downloads/h2200/backup$ sudo dpkg -i --force-all coreutils_5.2.1-2ubuntu2_amd64.deb
dpkg - aviso: rebaixando coreutils de 5.93-5ubuntu3 para 5.2.1-2ubuntu2.
(Lendo banco de dados ... 101579 arquivos e diretórios atualmente instalados.)
Preparando para substituir coreutils 5.93-5ubuntu3 (usando coreutils_5.2.1-2ubuntu2_amd64.deb) ...
Descompactando substituto coreutils ...
Instalando coreutils (5.2.1-2ubuntu2) ...

rodrigo@ubuntustrong:~/downloads/h2200/backup$ sudo dd if=2ndstage.rescue of=/dev/hde bs=1K count=1280 1280+0 records in
1280+0 records out
1310720 bytes transferred in 5,040860 seconds (260019 bytes/sec)

I've seen another dd bug which said this is locale related..

Xavier Claessens (zdra) wrote :

I can confirme this too:

dd if=/dev/zero of=test.img count=2
2+0 records in
2+0 records out
Erreur de segmentation

Backtrace

Jérémie Corbier (jcorbier) wrote :

I forgot to say that I used "(gdb) run if=/dev/zero of=test.img count=2".

Jérémie Corbier (jcorbier) wrote :

Wierd... I can't reproduce this bug a few hours later with the same version of coreutils...

everybody on this page seems to have a locale different than english so I really think it's a dup of #42264 (switching)

Vitaly (v-mayatskih) wrote :

$ dd if=/dev/zero of=123 bs=512 count=1
1+0 records in
1+0 records out
Segmentation fault

$ LANG=C dd if=/dev/zero of=123 bs=512 count=1
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.00011 seconds, 4.7 MB/s

$ locale
LANG=ru_RU.UTF-8
LANGUAGE=ru_RU:ru:en_GB:en
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=

PascalC (p92) wrote :

Same here with french locale, it seems to bug on the statistics message, works OK with LC_ALL=C.

$ locale
LANG=fr_FR.UTF-8
LANGUAGE=fr_FR:fr:en_GB:en
LC_CTYPE="fr_FR.UTF-8"
LC_NUMERIC="fr_FR.UTF-8"
LC_TIME="fr_FR.UTF-8"
LC_COLLATE="fr_FR.UTF-8"
LC_MONETARY="fr_FR.UTF-8"
LC_MESSAGES="fr_FR.UTF-8"
LC_PAPER="fr_FR.UTF-8"
LC_NAME="fr_FR.UTF-8"
LC_ADDRESS="fr_FR.UTF-8"
LC_TELEPHONE="fr_FR.UTF-8"
LC_MEASUREMENT="fr_FR.UTF-8"
LC_IDENTIFICATION="fr_FR.UTF-8"
LC_ALL=

with strace you can see that dd breaks when reading this
very file (missing though) :

        /usr/share/locale-langpack/<your locale>/LC_MESSAGES/coreutils.mo

The bug can be fixed while waiting for a correcting package by creating an empty file for your locale.
Example with locale fr :
         touch /usr/share/locale-langpack/fr/LC_MESSAGES/coreutils.mo

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....

Xavier Claessens (zdra) wrote :

I think the problem isn't the w_bytes. gettext should remove the %PRIuMAX and replace it by something like %llu. So w_bytes goes for the %llu and human_readable() is for %s in the string. The segfault comes because gettext doesn't replace %<PRIuMAX> by %llu so fprintf doesn't reconize %<PRIuMAX> and so he gives w_bytes to the %s, w_bytes isn't a string so it segfault. I you remove the w_bytes of course it doesn't segfault, but it doesn't realy solve the problem which is the %<PRIuMAX>.

grep PRIuMAX *
Binary file coreutils.mo matches

So coreutils is the only program which has PRIuMAX in translations. If you look at the fr.po (or what ever is your local) there is some %<PRIuMAX> is the translation strings.

I don't know how gettext works but I think the %<PRIuMAX> shouldn't appear in the .mo file. coreutils is the only package which has it... Does someone knows a package which has %PRIuMAX in the C code but not in the .mo file (or maybe it is removed by gettext in .pot or .po don't know) ? All I know by googling is that it seems that "PRIuMAX" is a special string that gettext should handle in some way. If you add "#, c-format" in the .po file and compile it the problem goes away because gettext does more tests and replace %<PRIuMAX> by something like %llu, that's the proof that %<PRIuMAX> shouldn't appear in .mo files.

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....

Oops, sorry for this double post.

Yep it seems you're right Xavier I made a mistake about the ngettext process.
But that's strange: PRIuMAX is defined in system.h (on the same folder than dd.c) and this file is included in dd.c

Matthias Hilbig (hilbig) wrote :

On my system dd segfaults if I send a USR1 signal to make it print statistics:

start in first terminal:
dd if=/dev/zero of=/dev/null

start in second terminal:
kill -USR1 [pid_of_dd]

Output from dd:
17373419+0 records in
17373418+0 records out
Segmentation fault

Launchpad Janitor (janitor) wrote :

[Expired for coreutils (Ubuntu) because there has been no activity for 60 days.]

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers