Incorrect usage of dirname() in sysdep/unix/main.c causes segfault

Henrique de Moraes Holschuh hmh at
Sun Mar 18 14:53:32 CET 2012

According to POSIX, dirname() is allowed to modify the string passed to
it.  In fact, according to dirname(3), glibc's will do just that when
libgen.h is in use.  The manpage even warns you that it will segfault
when passed a constant that cannot be modified...

Well, I hit that bug and it took a while to track it down.
--enable-debug seems to link a different dirname() that is less crappy,
so the bug wouldn't show up in debug builds.

The attached patch explains it better.

  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh
-------------- next part --------------
diff -ru bird-1.3.6/sysdep/unix/main.c bird-1.3.6_fix//sysdep/unix/main.c
--- bird-1.3.6/sysdep/unix/main.c	2011-10-10 04:57:59.000000000 -0300
+++ bird-1.3.6_fix//sysdep/unix/main.c	2012-03-18 10:50:31.397381192 -0300
@@ -167,12 +167,15 @@
   char full_name[BIRD_FNAME_MAX];
   char *cur = filename;
+  char *dir;
   int ret;
   if (*filename != '/') {
-    snprintf(full_name, sizeof(full_name), "%s/%s", dirname(config_name), filename);
+    dir = strdup(config_name);
+    snprintf(full_name, sizeof(full_name), "%s/%s", dirname(dir), filename);
     full_name[sizeof(full_name)-1] = 0;
     cur = full_name;
+    free(dir);
   if ((ret = open(cur, O_RDONLY)) == -1)

More information about the Bird-users mailing list