diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | PACKAGING | 1 | ||||
-rw-r--r-- | gettext-runtime/intl/ChangeLog | 8 | ||||
-rw-r--r-- | gettext-runtime/intl/localcharset.c | 156 | ||||
-rw-r--r-- | gettext-runtime/m4/ChangeLog | 6 | ||||
-rw-r--r-- | gettext-runtime/m4/Makefile.am | 1 | ||||
-rw-r--r-- | gettext-runtime/m4/fcntl_h.m4 | 108 | ||||
-rw-r--r-- | gettext-runtime/m4/intl.m4 | 3 | ||||
-rw-r--r-- | gettext-tools/doc/ChangeLog | 4 | ||||
-rw-r--r-- | gettext-tools/doc/gettext.texi | 2 | ||||
-rw-r--r-- | gettext-tools/m4/ChangeLog | 4 | ||||
-rw-r--r-- | gettext-tools/m4/Makefile.am | 1 | ||||
-rw-r--r-- | gettext-tools/misc/ChangeLog | 5 | ||||
-rw-r--r-- | gettext-tools/misc/gettextize.in | 8 |
15 files changed, 246 insertions, 67 deletions
@@ -1,3 +1,8 @@ +2009-10-18 Bruno Haible <bruno@clisp.org> + + * Makefile.am (distcheck-hook): Compare fcntl_h.m4. + * PACKAGING: Mention also fcntl_h.m4. + 2009-09-27 Bruno Haible <bruno@clisp.org> * NEWS: Mention configure options --without-cvs and --with-git. diff --git a/Makefile.am b/Makefile.am index 03ef081..6b5449b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -43,6 +43,7 @@ distcheck-hook: cmp -s gettext-runtime/po/remove-potcdate.sin gettext-tools/po/remove-potcdate.sin cmp -s gettext-runtime/po/remove-potcdate.sin gettext-tools/examples/po/remove-potcdate.sin cmp -s gettext-runtime/m4/codeset.m4 gettext-tools/gnulib-m4/codeset.m4 + cmp -s gettext-runtime/m4/fcntl_h.m4 gettext-tools/gnulib-m4/fcntl_h.m4 cmp -s gettext-runtime/m4/gettext.m4 gettext-tools/gnulib-m4/gettext.m4 cmp -s gettext-runtime/m4/glibc2.m4 gettext-tools/gnulib-m4/glibc2.m4 cmp -s gettext-runtime/m4/glibc21.m4 gettext-tools/gnulib-m4/glibc21.m4 @@ -117,6 +117,7 @@ following file list. $prefix/share/gettext/archive.git.tar.gz (only installed if --with-git specified) $prefix/share/gettext/archive.dir.tar.gz (only installed if --without-cvs specified) $prefix/share/aclocal/codeset.m4 + $prefix/share/aclocal/fcntl_h.m4 $prefix/share/aclocal/gettext.m4 $prefix/share/aclocal/glibc2.m4 $prefix/share/aclocal/glibc21.m4 diff --git a/gettext-runtime/intl/ChangeLog b/gettext-runtime/intl/ChangeLog index 0fefa04..6dd1b7f 100644 --- a/gettext-runtime/intl/ChangeLog +++ b/gettext-runtime/intl/ChangeLog @@ -1,3 +1,11 @@ +2009-10-18 Bruno Haible <bruno@clisp.org> + + Avoid symlink attack in localcharset module. + * localcharset.c: Include <fcntl.h>, <unistd.h>. + (O_NOFOLLOW): Define fallback. + (get_charset_aliases): Don't open the file if it is a symbolic link. + Reported by Fergal Glynn <fglynn@veracode.com>. + 2009-08-20 Eric Blake <ebb9@byu.net> * vasnprintf.c (decimal_point_char): Avoid warning on old-style diff --git a/gettext-runtime/intl/localcharset.c b/gettext-runtime/intl/localcharset.c index 434fc7c..e808967 100644 --- a/gettext-runtime/intl/localcharset.c +++ b/gettext-runtime/intl/localcharset.c @@ -24,6 +24,7 @@ /* Specification. */ #include "localcharset.h" +#include <fcntl.h> #include <stddef.h> #include <stdio.h> #include <string.h> @@ -45,6 +46,7 @@ #endif #if !defined WIN32_NATIVE +# include <unistd.h> # if HAVE_LANGINFO_CODESET # include <langinfo.h> # else @@ -76,6 +78,11 @@ # include "configmake.h" #endif +/* Define O_NOFOLLOW to 0 on platforms where it does not exist. */ +#ifndef O_NOFOLLOW +# define O_NOFOLLOW 0 +#endif + #if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ /* Win32, Cygwin, OS/2, DOS */ # define ISSLASH(C) ((C) == '/' || (C) == '\\') @@ -118,7 +125,6 @@ get_charset_aliases (void) if (cp == NULL) { #if !(defined DARWIN7 || defined VMS || defined WIN32_NATIVE || defined __CYGWIN__) - FILE *fp; const char *dir; const char *base = "charset.alias"; char *file_name; @@ -144,77 +150,105 @@ get_charset_aliases (void) } } - if (file_name == NULL || (fp = fopen (file_name, "r")) == NULL) - /* Out of memory or file not found, treat it as empty. */ + if (file_name == NULL) + /* Out of memory. Treat the file as empty. */ cp = ""; else { - /* Parse the file's contents. */ - char *res_ptr = NULL; - size_t res_size = 0; - - for (;;) + int fd; + + /* Open the file. Reject symbolic links on platforms that support + O_NOFOLLOW. This is a security feature. Without it, an attacker + could retrieve parts of the contents (namely, the tail of the + first line that starts with "* ") of an arbitrary file by placing + a symbolic link to that file under the name "charset.alias" in + some writable directory and defining the environment variable + CHARSETALIASDIR to point to that directory. */ + fd = open (file_name, + O_RDONLY | (HAVE_WORKING_O_NOFOLLOW ? O_NOFOLLOW : 0)); + if (fd < 0) + /* File not found. Treat it as empty. */ + cp = ""; + else { - int c; - char buf1[50+1]; - char buf2[50+1]; - size_t l1, l2; - char *old_res_ptr; - - c = getc (fp); - if (c == EOF) - break; - if (c == '\n' || c == ' ' || c == '\t') - continue; - if (c == '#') - { - /* Skip comment, to end of line. */ - do - c = getc (fp); - while (!(c == EOF || c == '\n')); - if (c == EOF) - break; - continue; - } - ungetc (c, fp); - if (fscanf (fp, "%50s %50s", buf1, buf2) < 2) - break; - l1 = strlen (buf1); - l2 = strlen (buf2); - old_res_ptr = res_ptr; - if (res_size == 0) + FILE *fp; + + fp = fdopen (fd, "r"); + if (fp == NULL) { - res_size = l1 + 1 + l2 + 1; - res_ptr = (char *) malloc (res_size + 1); + /* Out of memory. Treat the file as empty. */ + close (fd); + cp = ""; } else { - res_size += l1 + 1 + l2 + 1; - res_ptr = (char *) realloc (res_ptr, res_size + 1); + /* Parse the file's contents. */ + char *res_ptr = NULL; + size_t res_size = 0; + + for (;;) + { + int c; + char buf1[50+1]; + char buf2[50+1]; + size_t l1, l2; + char *old_res_ptr; + + c = getc (fp); + if (c == EOF) + break; + if (c == '\n' || c == ' ' || c == '\t') + continue; + if (c == '#') + { + /* Skip comment, to end of line. */ + do + c = getc (fp); + while (!(c == EOF || c == '\n')); + if (c == EOF) + break; + continue; + } + ungetc (c, fp); + if (fscanf (fp, "%50s %50s", buf1, buf2) < 2) + break; + l1 = strlen (buf1); + l2 = strlen (buf2); + old_res_ptr = res_ptr; + if (res_size == 0) + { + res_size = l1 + 1 + l2 + 1; + res_ptr = (char *) malloc (res_size + 1); + } + else + { + res_size += l1 + 1 + l2 + 1; + res_ptr = (char *) realloc (res_ptr, res_size + 1); + } + if (res_ptr == NULL) + { + /* Out of memory. */ + res_size = 0; + if (old_res_ptr != NULL) + free (old_res_ptr); + break; + } + strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); + strcpy (res_ptr + res_size - (l2 + 1), buf2); + } + fclose (fp); + if (res_size == 0) + cp = ""; + else + { + *(res_ptr + res_size) = '\0'; + cp = res_ptr; + } } - if (res_ptr == NULL) - { - /* Out of memory. */ - res_size = 0; - if (old_res_ptr != NULL) - free (old_res_ptr); - break; - } - strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); - strcpy (res_ptr + res_size - (l2 + 1), buf2); - } - fclose (fp); - if (res_size == 0) - cp = ""; - else - { - *(res_ptr + res_size) = '\0'; - cp = res_ptr; } - } - if (file_name != NULL) - free (file_name); + free (file_name); + } #else diff --git a/gettext-runtime/m4/ChangeLog b/gettext-runtime/m4/ChangeLog index 8d699b9..f854b70 100644 --- a/gettext-runtime/m4/ChangeLog +++ b/gettext-runtime/m4/ChangeLog @@ -1,3 +1,9 @@ +2009-10-18 Bruno Haible <bruno@clisp.org> + + * fcntl_h.m4: New file, from gnulib. + * intl.m4 (AM_INTL_SUBDIR): Require gl_FCNTL_O_FLAGS. + * Makefile.am (EXTRA_DIST): Add fcntl_h.m4. + 2009-08-14 Bruno Haible <bruno@clisp.org> * eoverflow.m4: Remove file. Obsoleted by gnulib's 'errno' module. diff --git a/gettext-runtime/m4/Makefile.am b/gettext-runtime/m4/Makefile.am index 5dcfc68..ccf0f2e 100644 --- a/gettext-runtime/m4/Makefile.am +++ b/gettext-runtime/m4/Makefile.am @@ -5,6 +5,7 @@ EXTRA_DIST = README \ ansi-c++.m4 \ codeset.m4 \ +fcntl_h.m4 \ gettext.m4 \ glibc2.m4 \ glibc21.m4 \ diff --git a/gettext-runtime/m4/fcntl_h.m4 b/gettext-runtime/m4/fcntl_h.m4 new file mode 100644 index 0000000..223fa48 --- /dev/null +++ b/gettext-runtime/m4/fcntl_h.m4 @@ -0,0 +1,108 @@ +# serial 6 +# Configure fcntl.h. +dnl Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Written by Paul Eggert. + +AC_DEFUN([gl_FCNTL_H], +[ + AC_REQUIRE([gl_FCNTL_H_DEFAULTS]) + AC_REQUIRE([gl_FCNTL_O_FLAGS]) + gl_CHECK_NEXT_HEADERS([fcntl.h]) + FCNTL_H='fcntl.h' + AC_SUBST([FCNTL_H]) +]) + +# Test whether the flags O_NOATIME and O_NOFOLLOW actually work. +# Define HAVE_WORKING_O_NOATIME to 1 if O_NOATIME works, or to 0 otherwise. +# Define HAVE_WORKING_O_NOFOLLOW to 1 if O_NOFOLLOW works, or to 0 otherwise. +AC_DEFUN([gl_FCNTL_O_FLAGS], +[ + dnl Persuade glibc <fcntl.h> to define O_NOATIME and O_NOFOLLOW. + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + AC_CACHE_CHECK([for working fcntl.h], [gl_cv_header_working_fcntl_h], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include <sys/types.h> + #include <sys/stat.h> + #include <unistd.h> + #include <fcntl.h> + #ifndef O_NOATIME + #define O_NOATIME 0 + #endif + #ifndef O_NOFOLLOW + #define O_NOFOLLOW 0 + #endif + static int const constants[] = + { + O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND, + O_NONBLOCK, O_SYNC, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY + }; + ]], + [[ + int status = !constants; + { + static char const sym[] = "conftest.sym"; + if (symlink (".", sym) != 0 + || close (open (sym, O_RDONLY | O_NOFOLLOW)) == 0) + status |= 32; + unlink (sym); + } + { + static char const file[] = "confdefs.h"; + int fd = open (file, O_RDONLY | O_NOATIME); + char c; + struct stat st0, st1; + if (fd < 0 + || fstat (fd, &st0) != 0 + || sleep (1) != 0 + || read (fd, &c, 1) != 1 + || close (fd) != 0 + || stat (file, &st1) != 0 + || st0.st_atime != st1.st_atime) + status |= 64; + } + return status;]])], + [gl_cv_header_working_fcntl_h=yes], + [case $? in #( + 32) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #( + 64) gl_cv_header_working_fcntl_h='no (bad O_NOATIME)';; #( + 96) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #( + *) gl_cv_header_working_fcntl_h='no';; + esac], + [gl_cv_header_working_fcntl_h=cross-compiling])]) + + case $gl_cv_header_working_fcntl_h in #( + *O_NOATIME* | no | cross-compiling) ac_val=0;; #( + *) ac_val=1;; + esac + AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOATIME], [$ac_val], + [Define to 1 if O_NOATIME works.]) + + case $gl_cv_header_working_fcntl_h in #( + *O_NOFOLLOW* | no | cross-compiling) ac_val=0;; #( + *) ac_val=1;; + esac + AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOFOLLOW], [$ac_val], + [Define to 1 if O_NOFOLLOW works.]) +]) + +AC_DEFUN([gl_FCNTL_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_FCNTL_H_DEFAULTS]) + GNULIB_[]m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./-],[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=1 +]) + +AC_DEFUN([gl_FCNTL_H_DEFAULTS], +[ + GNULIB_OPEN=0; AC_SUBST([GNULIB_OPEN]) + GNULIB_OPENAT=0; AC_SUBST([GNULIB_OPENAT]) + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_OPENAT=1; AC_SUBST([HAVE_OPENAT]) + REPLACE_OPEN=0; AC_SUBST([REPLACE_OPEN]) + REPLACE_OPENAT=0; AC_SUBST([REPLACE_OPENAT]) +]) diff --git a/gettext-runtime/m4/intl.m4 b/gettext-runtime/m4/intl.m4 index 2b446d2..a0325c3 100644 --- a/gettext-runtime/m4/intl.m4 +++ b/gettext-runtime/m4/intl.m4 @@ -1,4 +1,4 @@ -# intl.m4 serial 13 (gettext-0.18) +# intl.m4 serial 14 (gettext-0.18) dnl Copyright (C) 1995-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -40,6 +40,7 @@ AC_DEFUN([AM_INTL_SUBDIR], AC_REQUIRE([gt_PRINTF_POSIX]) AC_REQUIRE([gl_GLIBC21])dnl AC_REQUIRE([gl_XSIZE])dnl + AC_REQUIRE([gl_FCNTL_O_FLAGS])dnl AC_REQUIRE([gt_INTL_MACOSX])dnl dnl Support for automake's --enable-silent-rules. diff --git a/gettext-tools/doc/ChangeLog b/gettext-tools/doc/ChangeLog index 0176229..fa0e163 100644 --- a/gettext-tools/doc/ChangeLog +++ b/gettext-tools/doc/ChangeLog @@ -1,3 +1,7 @@ +2009-10-18 Bruno Haible <bruno@clisp.org> + + * gettext.texi (aclocal): Add fcntl_h.m4 to the file list. + 2009-09-20 Bruno Haible <bruno@clisp.org> * gettext.texi (src/Makefile): Update recommendations for autoconf diff --git a/gettext-tools/doc/gettext.texi b/gettext-tools/doc/gettext.texi index b09bcba..68ac5ca 100644 --- a/gettext-tools/doc/gettext.texi +++ b/gettext-tools/doc/gettext.texi @@ -7934,7 +7934,7 @@ automake 1.9. @cindex @file{aclocal.m4} file If you do not have an @file{aclocal.m4} file in your distribution, -the simplest is to concatenate the files @file{codeset.m4}, +the simplest is to concatenate the files @file{codeset.m4}, @file{fcntl_h.m4}, @file{gettext.m4}, @file{glibc2.m4}, @file{glibc21.m4}, @file{iconv.m4}, @file{intdiv0.m4}, @file{intl.m4}, @file{intldir.m4}, @file{intlmacosx.m4}, @file{intmax.m4}, @file{inttypes_h.m4}, @file{inttypes-pri.m4}, diff --git a/gettext-tools/m4/ChangeLog b/gettext-tools/m4/ChangeLog index dfbf8f5..0923c53 100644 --- a/gettext-tools/m4/ChangeLog +++ b/gettext-tools/m4/ChangeLog @@ -1,3 +1,7 @@ +2009-10-18 Bruno Haible <bruno@clisp.org> + + * Makefile.am (aclocal_DATA): Add fcntl_h.m4. + 2009-08-15 Bruno Haible <bruno@clisp.org> Stop using gnulib module 'strdup'. diff --git a/gettext-tools/m4/Makefile.am b/gettext-tools/m4/Makefile.am index 99a11e9..fe6795a 100644 --- a/gettext-tools/m4/Makefile.am +++ b/gettext-tools/m4/Makefile.am @@ -8,6 +8,7 @@ aclocal_DATA = \ ../../autoconf-lib-link/m4/lib-link.m4 \ ../../autoconf-lib-link/m4/lib-prefix.m4 \ ../../gettext-runtime/m4/codeset.m4 \ + ../../gettext-runtime/m4/fcntl_h.m4 \ ../../gettext-runtime/m4/gettext.m4 \ ../../gettext-runtime/m4/glibc2.m4 \ ../../gettext-runtime/m4/glibc21.m4 \ diff --git a/gettext-tools/misc/ChangeLog b/gettext-tools/misc/ChangeLog index 0d05081..5f0aa94 100644 --- a/gettext-tools/misc/ChangeLog +++ b/gettext-tools/misc/ChangeLog @@ -1,3 +1,8 @@ +2009-10-18 Bruno Haible <bruno@clisp.org> + + * gettextize.in (m4filelist): Add fcntl_h.m4 to the list. + (func_version): Bump copyright year. + 2009-09-27 Bruno Haible <bruno@clisp.org> * add-to-archive: Pass option -fPIC to gcc. Clean up cvsuser.so. diff --git a/gettext-tools/misc/gettextize.in b/gettext-tools/misc/gettextize.in index bdccb55..8c30f74 100644 --- a/gettext-tools/misc/gettextize.in +++ b/gettext-tools/misc/gettextize.in @@ -1,6 +1,6 @@ #! /bin/sh # -# Copyright (C) 1995-1998, 2000-2008 Free Software Foundation, Inc. +# Copyright (C) 1995-1998, 2000-2009 Free Software Foundation, Inc. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -174,7 +174,7 @@ Report bugs to <bug-gnu-gettext@gnu.org>." func_version () { echo "$progname (GNU $package) $version" - echo "Copyright (C) 1995-1998, 2000-2008 Free Software Foundation, Inc. + echo "Copyright (C) 1995-1998, 2000-2009 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law." @@ -768,8 +768,8 @@ m4filelist='gettext.m4 iconv.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 nls.m4 min_automake_version=1.9 if test -n "$intldir" || test -z "$have_automake19"; then # Add intldir.m4, intl.m4 and its dependencies. - m4filelist=$m4filelist' codeset.m4 glibc2.m4 glibc21.m4 intdiv0.m4 intl.m4 - intldir.m4 intlmacosx.m4 intmax.m4 inttypes_h.m4 inttypes-pri.m4 + m4filelist=$m4filelist' codeset.m4 fcntl_h.m4 glibc2.m4 glibc21.m4 intdiv0.m4 + intl.m4 intldir.m4 intlmacosx.m4 intmax.m4 inttypes_h.m4 inttypes-pri.m4 lcmessage.m4 lock.m4 longlong.m4 printf-posix.m4 size_max.m4 stdint_h.m4 threadlib.m4 uintmax_t.m4 visibility.m4 wchar_t.m4 wint_t.m4 xsize.m4' min_automake_version=1.8 |