Printf inconsistency when handed null string

Bug #193795 reported by Robert Escriva
12
This bug affects 1 person
Affects Status Importance Assigned to Milestone
gcc-4.3 (Ubuntu)
Confirmed
Low
Unassigned

Bug Description

Binary package hint: libc6

This happens both on AMD 64 and i386 of Ubuntu 7.10.
The following c code will segfault:
  printf("%s\n", NULL);

The following code will just output "(null)":
  printf("%s \n", NULL);

The distinction is the space between the %s and the \n.

I believe the error is in libc6 2.6.1-1ubuntu1. I haven't tested earlier version. A quick peek at the original source package shows that glibc-2.6.1/stdio-common/vprintf.c will write the string "(null)" if there is space. The check for this is on lines 1010-1011 and line 1141. I don't have the skills/resources to compile libc and test if making line 1141 follow lines 1010-1011 would fix it, but I suspect this would fix the issue as line 1141 assumes the size of a char is 1 byte, and it was necessary to check the size of a char on lines 1010-1011.

I'm willing to provide more information to help solve this issue.

Revision history for this message
Robert Escriva (no-spam-robescriva) wrote :

Small correction: vfprintf.c not vprintf.c. Sorry for the typo.

Revision history for this message
Philipp Kohlbecher (xt28) wrote :

I can confirm this behaviour.

I am not sure that you've correctly identified the cause, though. Looking at the disassembled machine code for both function calls, I found that 'printf("%s\n")' isn't handled by printf() at all -- the compiler inserts a call to puts() instead. puts(), in turn, calls strlen(), passing it a null pointer, which strlen() tries to dereference. Hence, the segmentation fault.

One more thing: Is this actually a bug? I mean, the inconsistency is due to gcc's substituting puts() for printf(). Calling puts() with a null pointer results in a segfault. But isn't it the programmer's job to make sure that he doesn't accidentally pass a null pointer to puts() -- or to printf("%s\n") for that matter?

Anyway, since I can reproduce this, I am marking this as confirmed.

Revision history for this message
Robert Escriva (no-spam-robescriva) wrote :

I agree 100% that it is the programmer's responsibility to check for null pointers and found this bug through testing of my own code.

I also played around with it last night and confirm as well that my original guess at the cause of this behavior was incorrect.

The only reason I reported this behavior was because in the latter of the two cases above it doesn't segfault, but in the former does. I think that the behavior should be consistent whether it has the space or not.

Matthias Klose (doko)
Changed in glibc:
importance: Undecided → Low
status: New → Triaged
Revision history for this message
Malcolm Parsons (malcolm-parsons) wrote :

gcc optimises printf to puts.
They behave differently, so the optimisation is invalid.

Andrey M (andrey.mrt.)
Changed in gcc-4.3 (Ubuntu):
status: Triaged → Confirmed
Revision history for this message
Andrey M (andrey.mrt.) wrote :

I've been digging through the gcc-4.3 source, looking for where the compiler swaps
printf("%s\n",str);
with
puts(str);

but the source is huge and I have no idea where or how to find the code responsible for this.

I would happily patch this, provided I can get some direction on where I can find the optimization code

Revision history for this message
Andrey M (andrey.mrt.) wrote :

I've traced the file that does the optimization to
/usr/src/gcc-4.3/gcc-4.3.3/gcc/builtins.c

The functions are

fold_builtin_printf()
fold_builtin_sprintf()

the functions return a tree that seems to point straight to some puts() or putchar() construct

that return tree should be modified to include a null check

I'm posting this preliminary research in case anyone already knows the gcc tree struct and can easily patch it

Revision history for this message
Malcolm Parsons (malcolm-parsons) wrote :

I think you need to try to convince the gcc developers that this is a bug.

Revision history for this message
Andrey M (andrey.mrt.) wrote : Re: [Bug 193795] Re: Printf inconsistency when handed null string

How can I do that?

On Sun, May 10, 2009 at 3:29 AM, Malcolm Parsons
<email address hidden>wrote:

> I think you need to try to convince the gcc developers that this is a
> bug.
>
> --
> Printf inconsistency when handed null string
> https://bugs.launchpad.net/bugs/193795
> You received this bug notification because you are a direct subscriber
> of the bug.
>

Revision history for this message
Malcolm Parsons (malcolm-parsons) wrote :

> How can I do that?

You could try posting to their mailing list.

http://gcc.gnu.org/lists.html

Revision history for this message
Andrey M (andrey.mrt.) wrote :

the gcc developers responded somewhat prick-like stating that it's the programmer's fault

anyways the interim solution is to pass the "-fno-builtin-printf" to the compiler

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

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.