Little did I expect to see true segfault! But that's exactly what happens when you invoke it via an invalid use of execve.
With the patch below, I've exempted true and false from this sort of abuse, but every program that calls set_program_name (argv[0]) will suffer the same fate. I haven't yet decided if/how to accommodate. Maybe like this: set_program_name (argv[0] ? argv[0] : PROGRAM_NAME); >From 4c9082a39618b5ef17f6cbb490d47a648c634da7 Mon Sep 17 00:00:00 2001 From: Jim Meyering <[email protected]> Date: Sun, 15 Nov 2009 22:23:01 +0100 Subject: [PATCH] true, false: perform initialization only when argc == 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * src/true.c (main): There is no reason to examine argv[0], call atexit, etc., in the usual case in which we're about to exit. This has the side effect of making it so that these programs no longer segfault when subjected to execve abuse. Before this change, this would segfault: printf '%s\n' '#include <unistd.h>' 'int main(int c, char**v)' \ '{ execve (v[1], 0, 0); }' > k.c && gcc k.c && ./a.out $PWD/true Now it succeeds. Reported by Tetsuo Handa and Bart Van Assche via Ondřej Vašík in http://bugzilla.redhat.com/537684. --- src/true.c | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/true.c b/src/true.c index f3e937f..d9d0118 100644 --- a/src/true.c +++ b/src/true.c @@ -54,18 +54,18 @@ Usage: %s [ignored command line arguments]\n\ int main (int argc, char **argv) { - initialize_main (&argc, &argv); - set_program_name (argv[0]); - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - atexit (close_stdout); - /* Recognize --help or --version only if it's the only command-line argument. */ if (argc == 2) { + initialize_main (&argc, &argv); + set_program_name (argv[0]); + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + atexit (close_stdout); + if (STREQ (argv[1], "--help")) usage (EXIT_STATUS); -- 1.6.5.2.386.g2a326
