bug-glibc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Mail Delivery System <address@hidden>] Mail delivery failed: returning


From: Ralph Schleicher
Subject: [Mail Delivery System <address@hidden>] Mail delivery failed: returning message to sender
Date: 02 Dec 2003 19:44:32 +0100
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

Hmm, the glibcbug script sets the recipient address to
<address@hidden> but this address does
not exist!

Do I have to resubmit the bug report or can you extract
it from the original message?

--- Begin Message --- Subject: Mail delivery failed: returning message to sender Date: Tue, 02 Dec 2003 04:07:39 -0500
This message was created automatically by mail delivery software.

A message that you sent could not be delivered to one or more of its
recipients. This is a permanent error. The following address(es) failed:

  pipe to | /usr/lib/gnats/queue-pr -q
    generated by address@hidden
    (ultimately generated from address@hidden)
    local delivery failed

------ This is a copy of the message, including all the headers. ------

Return-path: <address@hidden>
Received: from monty-python.gnu.org ([199.232.76.173])
        by fencepost.gnu.org with esmtp (Exim 4.24)
        id 1AR6VP-0004lB-55
        for address@hidden; Tue, 02 Dec 2003 04:07:39 -0500
Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.24)
        id 1AR7bf-0006YW-O0
        for address@hidden; Tue, 02 Dec 2003 05:18:42 -0500
Received: from [213.182.8.6] (helo=mail.allgaeu.org)
        by monty-python.gnu.org with esmtp (TLSv1:DES-CBC3-SHA:168)
        (Exim 4.24)
        id 1AR7be-0006XM-Pp
        for address@hidden; Tue, 02 Dec 2003 05:18:11 -0500
Received: from kim.allgaeu.org (localhost [127.0.0.1])
        by mail.allgaeu.org with ESMTP id hB29GdVQ002918
        (version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=NO)
        for <address@hidden>; Tue, 2 Dec 2003 10:16:40 +0100
X-Complaints-To: address@hidden
Received: (from address@hidden)
        by kim.allgaeu.org with UUCP id hB29Gdpn002917
        for address@hidden; Tue, 2 Dec 2003 10:16:39 +0100
Date: 2 Dec 2003 08:47:05 -0000
Message-ID: <address@hidden>
From: Ralph Schleicher <address@hidden>
To: address@hidden
Subject: call to argp_help generates a core dump
X-RCPT-Domain: gnu.org
X-Virus-Check: Yes
X-Spam-Check: Yes
X-Spam-Tests: 
X-Spam-Status: No, hits=-0.2 required=5.0
        tests=PATCH_CONTEXT_DIFF
        version=2.55
X-Spam-Level: 
X-Spam-Checker-Version: SpamAssassin 2.55 (1.174.2.19-2003-05-19-exp)

>Submitter-Id:  net
>Originator:    Ralph Schleicher
>Organization:
>
>Confidential:  no
>Synopsis:      sigsegv due to null-pointer dereferencing in glibc
>Severity:      serious
>Priority:      high
>Category:      libc
>Class:         sw-bug
>Release:       libc-2.3.2
>Environment:
        
Host type: i686-pc-linux-gnu
System: Linux bravo 2.4.19 #1 SMP Fri Oct 18 16:57:39 CEST 2002 i686 unknown
Architecture: i686

Addons: linuxthreads
Build CFLAGS: -pipe -O2
Build CC: gcc
Compiler version: 3.2.2
Kernel headers: 2.4.19
Symbol versioning: yes
Build static: yes
Build shared: yes
Build pic-default: no
Build profile: yes
Build omitfp: no
Build bounded: no
Build static-nss: no

>Description:
A call to argp_help generates a core dump due to null-pointer
dereferencing

>How-To-Repeat:
Compile the following example program and run it with './argp-demo --help'.

#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 2003-12-02 09:35 CET by <address@hidden>.
# Source directory was `/home/rs/src/argp/lib/bug'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#    101 -rw-r--r-- Makefile
#   1144 -rw-r--r-- argp-demo.c
#   4550 -rw-r--r-- prog.c
#    469 -rw-r--r-- prog.h
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
  if test "$gettext_dir" = FAILED && test -f $dir/gettext \
     && ($dir/gettext --version >/dev/null 2>&1)
  then
    set `$dir/gettext --version 2>&1`
    if test "$3" = GNU
    then
      gettext_dir=$dir
    fi
  fi
  if test "$locale_dir" = FAILED && test -f $dir/shar \
     && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
  then
    locale_dir=`$dir/shar --print-text-domain-dir`
  fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
  echo=echo
else
  TEXTDOMAINDIR=$locale_dir
  export TEXTDOMAINDIR
  TEXTDOMAIN=sharutils
  export TEXTDOMAIN
  echo="$gettext_dir/gettext -s"
fi
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  $echo 'WARNING: not restoring timestamps.  Consider getting and'
  $echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
if mkdir _sh31221; then
  $echo 'x -' 'creating lock directory'
else
  $echo 'failed to create lock directory'
  exit 1
fi
# ============= Makefile ==============
if test -f 'Makefile' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'Makefile' '(file already exists)'
else
  $echo 'x -' extracting 'Makefile' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
CC = gcc -g -Wall -W
CFLAGS = -D_GNU_SOURCE
X
argp-demo: argp-demo.c prog.c
X       $(CC) $(CFLAGS) -o $@ $^
SHAR_EOF
  $shar_touch -am 11292242103 'Makefile' &&
  chmod 0644 'Makefile' ||
  $echo 'restore of' 'Makefile' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'Makefile:' 'MD5 check failed'
96ec561384a6a486d1853a5df748c4eb  Makefile
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'Makefile'`"
    test 101 -eq "$shar_count" ||
    $echo 'Makefile:' 'original size' '101,' 'current size' "$shar_count!"
  fi
fi
# ============= argp-demo.c ==============
if test -f 'argp-demo.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'argp-demo.c' '(file already exists)'
else
  $echo 'x -' extracting 'argp-demo.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'argp-demo.c' &&
#include <stdlib.h>
#include <string.h>
#include <argp.h>
#include "prog.h"
X
#define PACKAGE "argp-demo"
#define VERSION "1.0"
X
static char *log_file = PACKAGE ".log";
static char *run_file = PACKAGE ".pid";
X
static struct argp_option options[] =
X  {
X    {"log-file", 'l', "FILE", 0, "Write status messages to file FILE", 0},
X    {"run-file", 'p', "FILE", 0, "Save runtime information in file FILE", 0},
X    {NULL, 0, NULL, 0, NULL, 0},
X  };
X
X
static error_t
parser (int key, char *arg, struct argp_state *state __attribute__ ((unused)))
{
X  switch (key)
X    {
X    case 'l':
X      log_file = arg;
X      return 0;
X
X    case 'r':
X      run_file = arg;
X      return 0;
X    }
X
X  return ARGP_ERR_UNKNOWN;
}
X
X
int
main (int argc, char *argv[])
{
X  struct argp argp = {options, parser};
X  int i;
X
X  package_name = PACKAGE;
X  package_version = VERSION;
X  package_string = PACKAGE " " VERSION;
X  package_address = "address@hidden";
X
X  i = setup_program (argc, argv, &argp);
X
X  printf ("log-file = %s\n", log_file);
X  printf ("run-file = %s\n", run_file);
X
X  for (; i < argc; ++i)
X    printf ("%d: %s\n", i, argv[i]);
X
X  exit (EXIT_SUCCESS);
}
SHAR_EOF
  $shar_touch -am 11292239103 'argp-demo.c' &&
  chmod 0644 'argp-demo.c' ||
  $echo 'restore of' 'argp-demo.c' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'argp-demo.c:' 'MD5 check failed'
eb716876eda57a054a1d9cab43aa2118  argp-demo.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'argp-demo.c'`"
    test 1144 -eq "$shar_count" ||
    $echo 'argp-demo.c:' 'original size' '1144,' 'current size' "$shar_count!"
  fi
fi
# ============= prog.c ==============
if test -f 'prog.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'prog.c' '(file already exists)'
else
  $echo 'x -' extracting 'prog.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'prog.c' &&
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <argp.h>
#include "prog.h"
X
/* Package variables.  */
char *package_name;
char *package_version;
char *package_string;
char *package_copying;
char *package_address;
X
/* Program invocation name.  */
char *invocation_name;
X
/* Program name sans directory.  */
char *program_name;
X
/* Standard options.  */
struct opt
X  {
X    /* Non-zero means display help text.  */
X    int help;
X
X    /* Non-zero means display usage message.  */
X    int usage;
X
X    /* Non-zero means display version information.  */
X    int version;
X  };
X
enum
X  {
X    OPT_HELP = 256,
X    OPT_USAGE,
X    OPT_VERSION
X  };
X
static struct argp_option opt_options[] =
X  {
X    {"help", OPT_HELP, NULL, 0, "Display this help and exit", -1},
X    {"usage", OPT_USAGE, NULL, 0, "Display usage message and exit", -1},
X    {"version", OPT_VERSION, NULL, 0, "Display version information and exit", 
-1},
X    {NULL, 0, NULL, 0, NULL, 0},
X  };
X
/* Forward declarations.  */
static char *base_name (const char *name);
X
X
/* Parser for standard options.  */
static error_t
opt_parser (int key, char *arg __attribute__ ((unused)), struct argp_state 
*state)
{
X  struct opt *opt = state->input;
X
X  switch (key)
X    {
X    case OPT_HELP:
X      opt->help = 1;
X      return 0;
X
X    case OPT_USAGE:
X      opt->usage = 1;
X      return 0;
X
X    case OPT_VERSION:
X      opt->version = 1;
X      return 0;
X    }
X
X  return ARGP_ERR_UNKNOWN;
}
X
X
/* Initialize program.  */
int
setup_program (int argc, char **argv, void *argp)
{
X  struct argp common, parent;
X  struct argp_child child[3];
X  struct opt opt;
X  int err, ind;
X  int outp;
X
X  invocation_name = argv[0];
X  if (*invocation_name == 0)
X    abort ();
X
X  program_name = base_name (invocation_name);
X  if (*program_name == 0)
X    abort ();
X
X  common.options = opt_options;
X  common.parser = opt_parser;
X  common.args_doc = NULL;
X  common.doc = NULL;
X  common.children = NULL;
X  common.help_filter = NULL;
X  common.argp_domain = NULL;
X
X  parent.options = NULL;
X  parent.parser = NULL;
X  parent.args_doc = NULL;
X  parent.doc = NULL;
X  parent.children = child;
X  parent.help_filter = NULL;
X  parent.argp_domain = NULL;
X
X  child[0].argp = &common;
X  child[0].flags = 0;
X  child[0].header = NULL;
X  child[0].group = -1;
X
X  child[1].argp = argp;
X  child[1].flags = 0;
X  child[1].header = NULL;
X  child[1].group = 0;
X
X  child[2].argp = NULL;
X  child[2].flags = 0;
X  child[2].header = NULL;
X  child[2].group = 0;
X
X  argp = &parent;
X
X  /* Default values.  */
X  opt.help = 0;
X  opt.usage = 0;
X  opt.version = 0;
X
X  err = argp_parse (argp, argc, argv, ARGP_SILENT, &ind, &opt);
X  switch (err)
X    {
X    case 0:
X
X      if (opt.version)
X       {
X         if (package_name != NULL)
X           {
X             fputs (package_name, stdout);
X
X             if (package_version != NULL)
X               {
X                 fputc (' ', stdout);
X                 fputs (package_version, stdout);
X               }
X
X             if (package_string != NULL)
X               {
X                 fputc (' ', stdout);
X                 fputc ('(', stdout);
X                 fputs (package_string, stdout);
X                 fputc (')', stdout);
X               }
X
X             if (package_copying != NULL)
X               {
X                 fputc ('\n', stdout);
X                 fputc ('\n', stdout);
X                 fputs (package_copying, stdout);
X               }
X
X             fputc ('\n', stdout);
X             outp = 1;
X           }
X         else
X           {
X             fprintf (stderr, "%s: %s\n", program_name,
X                      "No version information available");
X           }
X       }
X
X      if (opt.usage)
X       {
X         if (outp)
X           fputc ('\n', stdout);
X
X         argp_help (argp, stdout, ARGP_HELP_USAGE, program_name);
X         outp = 1;
X       }
X
X      if (opt.help)
X       {
X         unsigned int flags;
X
X         flags = opt.usage ? 0 : ARGP_HELP_SHORT_USAGE;
X         flags |= (ARGP_HELP_LONG | ARGP_HELP_DOC);
X
X         if (outp)
X           fputc ('\n', stdout);
X
X         argp_help (argp, stdout, flags, program_name);
X         outp = 1;
X
X         if (package_address != NULL)
X           {
X             fputc ('\n', stdout);
X             fputs ("Report bugs to <", stdout);
X             fputs (package_address, stdout);
X             fputs (">.\n", stdout);
X           }
X       }
X
X      if (opt.version || opt.usage || opt.help)
X       exit (EXIT_SUCCESS);
X
X      return ind;
X
X    case EINVAL:
X
X      fprintf (stderr, "%s: Unrecognized option '%s'\n",
X              program_name, argv[optind]);
X
X      fprintf (stderr, "Try '%s --help' for more information\n",
X              invocation_name);
X
X      exit (EXIT_FAILURE);
X
X    default:
X
X      fprintf (stderr, "%s: %s\n",
X              program_name, strerror (err));
X
X      exit (EXIT_FAILURE);
X    }
}
X
X
/* Return base name.  */
static char *
base_name (const char *name)
{
X  char *tem;
X
X  tem = strrchr (name, '/');
X  if (tem == NULL)
X    return (char *) name;
X  else
X    return tem + 1;
}
SHAR_EOF
  $shar_touch -am 11292242103 'prog.c' &&
  chmod 0644 'prog.c' ||
  $echo 'restore of' 'prog.c' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'prog.c:' 'MD5 check failed'
9b09ed7e84339ff55479cb961ed6ecce  prog.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'prog.c'`"
    test 4550 -eq "$shar_count" ||
    $echo 'prog.c:' 'original size' '4550,' 'current size' "$shar_count!"
  fi
fi
# ============= prog.h ==============
if test -f 'prog.h' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'prog.h' '(file already exists)'
else
  $echo 'x -' extracting 'prog.h' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'prog.h' &&
#ifndef LOGGER_PROG_H
#define LOGGER_PROG_H
X
/* User variables.  */
extern char *package_name;
extern char *package_version;
extern char *package_string;
extern char *package_address;
extern char *package_copying;
X
/* Program invocation name.  */
extern char *invocation_name;
X
/* Program name sans directory.  */
extern char *program_name;
X
/* Initialize program.  */
extern int setup_program (int __argc, char **__argv, void *__argp);
X
#endif /* not LOGGER_PROG_H */
SHAR_EOF
  $shar_touch -am 11272001103 'prog.h' &&
  chmod 0644 'prog.h' ||
  $echo 'restore of' 'prog.h' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'prog.h:' 'MD5 check failed'
2afe0e271f4f062c98a4b99ac7538d90  prog.h
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'prog.h'`"
    test 469 -eq "$shar_count" ||
    $echo 'prog.h:' 'original size' '469,' 'current size' "$shar_count!"
  fi
fi
rm -fr _sh31221
exit 0

>Fix:
Apply the following patch.  Here is the associated ChangeLog entry:

2003-11-29  Ralph Schleicher  <address@hidden>

        * argp/argp-help.c (hol_entry_help, hol_help, fill_in_uparams):
        Check if state is non-null before accessing a structure member.

        * argp/argp-help.c (filter_doc): Check if argp is non-null before
        accessing a structure member.

diff -c2d glibc-2.3.2/argp/argp-help.c.orig glibc-2.3.2/argp/argp-help.c
*** glibc-2.3.2/argp/argp-help.c.orig   Thu Nov 27 21:17:02 2003
--- glibc-2.3.2/argp/argp-help.c        Thu Nov 27 22:23:35 2003
***************
*** 156,159 ****
--- 156,160 ----
  {
    const char *var = getenv ("ARGP_HELP_FMT");
+   const char *domain = state ? state->root_argp->argp_domain : NULL;
  
  #define SKIPWS(p) do { while (isspace (*p)) p++; } while (0);
***************
*** 211,215 ****
                  if (unspec && !un->is_bool)
                    __argp_failure (state, 0, 0,
!                                   dgettext (state->root_argp->argp_domain, "\
  %.*s: ARGP_HELP_FMT parameter requires a value"),
                                    (int) var_len, var);
--- 212,216 ----
                  if (unspec && !un->is_bool)
                    __argp_failure (state, 0, 0,
!                                   dgettext (domain, "\
  %.*s: ARGP_HELP_FMT parameter requires a value"),
                                    (int) var_len, var);
***************
*** 220,224 ****
            if (! un->name)
              __argp_failure (state, 0, 0,
!                             dgettext (state->root_argp->argp_domain, "\
  %.*s: Unknown ARGP_HELP_FMT parameter"),
                              (int) var_len, var);
--- 221,225 ----
            if (! un->name)
              __argp_failure (state, 0, 0,
!                             dgettext (domain, "\
  %.*s: Unknown ARGP_HELP_FMT parameter"),
                              (int) var_len, var);
***************
*** 231,235 ****
          {
            __argp_failure (state, 0, 0,
!                           dgettext (state->root_argp->argp_domain,
                                      "Garbage in ARGP_HELP_FMT: %s"), var);
            break;
--- 232,236 ----
          {
            __argp_failure (state, 0, 0,
!                           dgettext (domain,
                                      "Garbage in ARGP_HELP_FMT: %s"), var);
            break;
***************
*** 963,967 ****
            const struct argp_state *state)
  {
!   if (argp->help_filter)
      /* We must apply a user filter to this output.  */
      {
--- 964,968 ----
            const struct argp_state *state)
  {
!   if (argp && argp->help_filter)
      /* We must apply a user filter to this output.  */
      {
***************
*** 1060,1063 ****
--- 1061,1065 ----
       share with helper functions.  */
    struct pentry_state pest = { entry, stream, hhstate, 1, state };
+   const char *domain = state ? state->root_argp->argp_domain : NULL;
  
    if (! odoc (real))
***************
*** 1081,1085 ****
            __argp_fmtstream_putc (stream, *so);
            if (!have_long_opt || uparams.dup_args)
!             arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream);
            else if (real->arg)
              hhstate->suppressed_dup_arg = 1;
--- 1083,1087 ----
            __argp_fmtstream_putc (stream, *so);
            if (!have_long_opt || uparams.dup_args)
!             arg (real, " %s", "[%s]", domain, stream);
            else if (real->arg)
              hhstate->suppressed_dup_arg = 1;
***************
*** 1100,1106 ****
               have been done on the original; but documentation options
               should be pretty rare anyway...  */
!           __argp_fmtstream_puts (stream,
!                                  dgettext (state->root_argp->argp_domain,
!                                            opt->name));
          }
      }
--- 1102,1106 ----
               have been done on the original; but documentation options
               should be pretty rare anyway...  */
!           __argp_fmtstream_puts (stream, dgettext (domain, opt->name));
          }
      }
***************
*** 1117,1122 ****
            __argp_fmtstream_printf (stream, "--%s", opt->name);
            if (first_long_opt || uparams.dup_args)
!             arg (real, "=%s", "[=%s]", state->root_argp->argp_domain,
!                  stream);
            else if (real->arg)
              hhstate->suppressed_dup_arg = 1;
--- 1117,1121 ----
            __argp_fmtstream_printf (stream, "--%s", opt->name);
            if (first_long_opt || uparams.dup_args)
!             arg (real, "=%s", "[=%s]", domain, stream);
            else if (real->arg)
              hhstate->suppressed_dup_arg = 1;
***************
*** 1139,1144 ****
    else
      {
!       const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain,
!                                              real->doc) : 0;
        const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
        if (fstr && *fstr)
--- 1138,1142 ----
    else
      {
!       const char *tstr = real->doc ? dgettext (domain, real->doc) : 0;
        const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
        if (fstr && *fstr)
***************
*** 1181,1184 ****
--- 1179,1183 ----
    struct hol_entry *entry;
    struct hol_help_state hhstate = { 0, 0, 0 };
+   const char *domain = state ? state->root_argp->argp_domain : NULL;
  
    for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
***************
*** 1187,1191 ****
    if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
      {
!       const char *tstr = dgettext (state->root_argp->argp_domain, "\
  Mandatory or optional arguments to long options are also mandatory or \
  optional for any corresponding short options.");
--- 1186,1190 ----
    if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
      {
!       const char *tstr = dgettext (domain, "\
  Mandatory or optional arguments to long options are also mandatory or \
  optional for any corresponding short options.");


--- End Message ---

-- 
Ralph

reply via email to

[Prev in Thread] Current Thread [Next in Thread]