diff --git a/config/cfgroot/general-functions.pl b/config/cfgroot/general-functions.pl index 8ed87fc80..35ae7c093 100644 --- a/config/cfgroot/general-functions.pl +++ b/config/cfgroot/general-functions.pl @@ -286,7 +286,7 @@ sub validip sub validmask { my $mask = shift; - return &Network::check_netmask($mask) or &Network::check_prefix($mask); + return &Network::check_netmask($mask) || &Network::check_prefix($mask); } sub validipormask @@ -388,7 +388,9 @@ sub iporsubtocidr } sub getnetworkip { - return &Network::get_netaddress(shift); + my $arg = join("/", @_); + + return &Network::get_netaddress($arg); } sub getccdbc diff --git a/config/findutils/updatedb b/config/findutils/updatedb new file mode 100644 index 000000000..6cc188672 --- /dev/null +++ b/config/findutils/updatedb @@ -0,0 +1,16 @@ +#!/bin/bash + +[ -x "/usr/bin/updatedb" ] || exit 0 + +LOCKFILE="/var/lib/locate/updatedb.lock" + +trap "rm -f $LOCKFILE" EXIT + +if [ -e "$LOCKFILE" ]; then + echo >&2 "Warning: $LOCKFILE present, not running updatedb." + exit 1 +else + touch "$LOCKFILE" +fi + +/usr/bin/updatedb diff --git a/config/rootfiles/common/fcron b/config/rootfiles/common/fcron index b3a1c4960..89f68a76c 100644 --- a/config/rootfiles/common/fcron +++ b/config/rootfiles/common/fcron @@ -11,7 +11,6 @@ etc/fcron.hourly/info.txt etc/fcron.minutely/info.txt #etc/fcron.monthly etc/fcron.monthly/info.txt -#etc/fcron.weekly etc/fcron.weekly/info.txt usr/bin/fcronsighup usr/bin/fcrontab diff --git a/config/rootfiles/common/findutils b/config/rootfiles/common/findutils index 13cae26eb..ac4fffe95 100644 --- a/config/rootfiles/common/findutils +++ b/config/rootfiles/common/findutils @@ -1,3 +1,5 @@ +#etc/fcron.weekly +etc/fcron.weekly/updatedb bin/find usr/bin/locate #usr/bin/oldfind diff --git a/config/rootfiles/core/82/filelists/openssl-compat b/config/rootfiles/core/82/filelists/openssl-compat new file mode 120000 index 000000000..c9fa42132 --- /dev/null +++ b/config/rootfiles/core/82/filelists/openssl-compat @@ -0,0 +1 @@ +../../../common/openssl-compat \ No newline at end of file diff --git a/config/rootfiles/core/82/exclude b/config/rootfiles/core/83/exclude similarity index 100% rename from config/rootfiles/core/82/exclude rename to config/rootfiles/core/83/exclude diff --git a/config/rootfiles/core/83/filelists/bash b/config/rootfiles/core/83/filelists/bash new file mode 120000 index 000000000..de970cb1d --- /dev/null +++ b/config/rootfiles/core/83/filelists/bash @@ -0,0 +1 @@ +../../../common/bash \ No newline at end of file diff --git a/config/rootfiles/core/83/filelists/files b/config/rootfiles/core/83/filelists/files new file mode 100644 index 000000000..5c0b6fefb --- /dev/null +++ b/config/rootfiles/core/83/filelists/files @@ -0,0 +1,6 @@ +etc/system-release +etc/issue +srv/web/ipfire/cgi-bin/logs.cgi/ids.dat +srv/web/ipfire/cgi-bin/proxy.cgi +srv/web/ipfire/cgi-bin/urlfilter.cgi +var/ipfire/general-functions.pl diff --git a/config/rootfiles/core/83/filelists/findutils b/config/rootfiles/core/83/filelists/findutils new file mode 120000 index 000000000..545280ac5 --- /dev/null +++ b/config/rootfiles/core/83/filelists/findutils @@ -0,0 +1 @@ +../../../common/findutils \ No newline at end of file diff --git a/config/rootfiles/core/83/filelists/squid b/config/rootfiles/core/83/filelists/squid new file mode 120000 index 000000000..2dc8372a0 --- /dev/null +++ b/config/rootfiles/core/83/filelists/squid @@ -0,0 +1 @@ +../../../common/squid \ No newline at end of file diff --git a/config/rootfiles/core/82/meta b/config/rootfiles/core/83/meta similarity index 100% rename from config/rootfiles/core/82/meta rename to config/rootfiles/core/83/meta diff --git a/config/rootfiles/core/83/update.sh b/config/rootfiles/core/83/update.sh new file mode 100644 index 000000000..c766b42a4 --- /dev/null +++ b/config/rootfiles/core/83/update.sh @@ -0,0 +1,59 @@ +#!/bin/bash +############################################################################ +# # +# This file is part of the IPFire Firewall. # +# # +# IPFire is free software; you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 3 of the License, or # +# (at your option) any later version. # +# # +# IPFire is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with IPFire; if not, write to the Free Software # +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +# # +# Copyright (C) 2014 IPFire-Team . # +# # +############################################################################ +# +. /opt/pakfire/lib/functions.sh +/usr/local/bin/backupctrl exclude >/dev/null 2>&1 + +# Remove old core updates from pakfire cache to save space... +core=83 +for (( i=1; i<=$core; i++ )) +do + rm -f /var/cache/pakfire/core-upgrade-*-$i.ipfire +done + +# Stop services + +# Remove old files + +# Extract files +extract_files + +# reload init because glibc/linker changed +telinit -u + +# Start services + +# Update Language cache +perl -e "require '/var/ipfire/lang.pl'; &Lang::BuildCacheLang" + +sync + +# This update need a reboot... +touch /var/run/need_reboot + +# Finish +/etc/init.d/fireinfo start +sendprofile + +# Don't report the exitcode last command +exit 0 diff --git a/config/rootfiles/oldcore/82/exclude b/config/rootfiles/oldcore/82/exclude new file mode 100644 index 000000000..18e9b4d24 --- /dev/null +++ b/config/rootfiles/oldcore/82/exclude @@ -0,0 +1,20 @@ +boot/config.txt +etc/collectd.custom +etc/ipsec.conf +etc/ipsec.secrets +etc/ipsec.user.conf +etc/ipsec.user.secrets +etc/localtime +etc/shadow +etc/ssh/ssh_config +etc/ssh/sshd_config +etc/ssl/openssl.cnf +etc/sudoers +etc/sysconfig/firewall.local +etc/sysconfig/rc.local +etc/udev/rules.d/30-persistent-network.rules +srv/web/ipfire/html/proxy.pac +var/ipfire/ovpn +var/log/cache +var/state/dhcp/dhcpd.leases +var/updatecache diff --git a/config/rootfiles/core/82/filelists/armv5tel/gmp b/config/rootfiles/oldcore/82/filelists/armv5tel/gmp similarity index 100% rename from config/rootfiles/core/82/filelists/armv5tel/gmp rename to config/rootfiles/oldcore/82/filelists/armv5tel/gmp diff --git a/config/rootfiles/core/82/filelists/batctl b/config/rootfiles/oldcore/82/filelists/batctl similarity index 100% rename from config/rootfiles/core/82/filelists/batctl rename to config/rootfiles/oldcore/82/filelists/batctl diff --git a/config/rootfiles/core/82/filelists/boost b/config/rootfiles/oldcore/82/filelists/boost similarity index 100% rename from config/rootfiles/core/82/filelists/boost rename to config/rootfiles/oldcore/82/filelists/boost diff --git a/config/rootfiles/core/82/filelists/files b/config/rootfiles/oldcore/82/filelists/files similarity index 100% rename from config/rootfiles/core/82/filelists/files rename to config/rootfiles/oldcore/82/filelists/files diff --git a/config/rootfiles/core/82/filelists/i586/gmp b/config/rootfiles/oldcore/82/filelists/i586/gmp similarity index 100% rename from config/rootfiles/core/82/filelists/i586/gmp rename to config/rootfiles/oldcore/82/filelists/i586/gmp diff --git a/config/rootfiles/core/82/filelists/libnl-3 b/config/rootfiles/oldcore/82/filelists/libnl-3 similarity index 100% rename from config/rootfiles/core/82/filelists/libnl-3 rename to config/rootfiles/oldcore/82/filelists/libnl-3 diff --git a/config/rootfiles/core/82/filelists/mpfr b/config/rootfiles/oldcore/82/filelists/mpfr similarity index 100% rename from config/rootfiles/core/82/filelists/mpfr rename to config/rootfiles/oldcore/82/filelists/mpfr diff --git a/config/rootfiles/core/82/filelists/ppp b/config/rootfiles/oldcore/82/filelists/ppp similarity index 100% rename from config/rootfiles/core/82/filelists/ppp rename to config/rootfiles/oldcore/82/filelists/ppp diff --git a/config/rootfiles/oldcore/82/meta b/config/rootfiles/oldcore/82/meta new file mode 100644 index 000000000..d547fa86f --- /dev/null +++ b/config/rootfiles/oldcore/82/meta @@ -0,0 +1 @@ +DEPS="" diff --git a/config/rootfiles/core/82/update.sh b/config/rootfiles/oldcore/82/update.sh similarity index 100% rename from config/rootfiles/core/82/update.sh rename to config/rootfiles/oldcore/82/update.sh diff --git a/config/rootfiles/packages/minidlna b/config/rootfiles/packages/minidlna index c30e30b40..f0b953653 100644 --- a/config/rootfiles/packages/minidlna +++ b/config/rootfiles/packages/minidlna @@ -1,3 +1,15 @@ etc/rc.d/init.d/minidlna etc/minidlna.conf -usr/sbin/minidlna +usr/sbin/minidlnad +#usr/share/locale/da/LC_MESSAGES/minidlna.mo +#usr/share/locale/de/LC_MESSAGES/minidlna.mo +#usr/share/locale/es/LC_MESSAGES/minidlna.mo +#usr/share/locale/fr/LC_MESSAGES/minidlna.mo +#usr/share/locale/it/LC_MESSAGES/minidlna.mo +#usr/share/locale/ja/LC_MESSAGES/minidlna.mo +#usr/share/locale/nb/LC_MESSAGES/minidlna.mo +#usr/share/locale/nl/LC_MESSAGES/minidlna.mo +#usr/share/locale/pl/LC_MESSAGES/minidlna.mo +#usr/share/locale/ru/LC_MESSAGES/minidlna.mo +#usr/share/locale/sl/LC_MESSAGES/minidlna.mo +#usr/share/locale/sv/LC_MESSAGES/minidlna.mo diff --git a/config/rootfiles/packages/perl-PDF-API2 b/config/rootfiles/packages/perl-PDF-API2 index c594d8242..642579a6e 100644 --- a/config/rootfiles/packages/perl-PDF-API2 +++ b/config/rootfiles/packages/perl-PDF-API2 @@ -129,9 +129,9 @@ usr/lib/perl5/site_perl/5.12.3/PDF/API2/Resource/uniglyph.txt usr/lib/perl5/site_perl/5.12.3/PDF/API2/UniWrap.pm usr/lib/perl5/site_perl/5.12.3/PDF/API2/Util.pm usr/lib/perl5/site_perl/5.12.3/PDF/API2/Win32.pm -#usr/lib/perl5/site_perl/5.12.3/i586-linux-thread-multi/auto/PDF -#usr/lib/perl5/site_perl/5.12.3/i586-linux-thread-multi/auto/PDF/API2 -#usr/lib/perl5/site_perl/5.12.3/i586-linux-thread-multi/auto/PDF/API2/.packlist +#usr/lib/perl5/site_perl/5.12.3/MACHINE-linux-thread-multi/auto/PDF +#usr/lib/perl5/site_perl/5.12.3/MACHINE-linux-thread-multi/auto/PDF/API2 +#usr/lib/perl5/site_perl/5.12.3/MACHINE-linux-thread-multi/auto/PDF/API2/.packlist #usr/share/man/man3/PDF::API2.3 #usr/share/man/man3/PDF::API2::Annotation.3 #usr/share/man/man3/PDF::API2::Basic::PDF::Array.3 diff --git a/config/xen-image/README b/config/xen-image/README index 574812166..531867311 100644 --- a/config/xen-image/README +++ b/config/xen-image/README @@ -19,6 +19,7 @@ other usefull commands from the Dom0: - reset the fire: "xm destroy ipfire-xen" - look what is going on: "xm top" or "xm list" -This script can also build a Citrix XenCenter xva image. +This script can also build a Citrix XenCenter xva image. (Need xz-aware +xen version. Tested with Citrix Xen Server 6.2.5 beta) - run "XEN_IMG_TYPE=xva sh xen-image-maker.sh" to build an xva image. - import the vm with "xe vm-import file=ipfire.xfa" diff --git a/html/cgi-bin/logs.cgi/ids.dat b/html/cgi-bin/logs.cgi/ids.dat index 86207c2aa..44b3abdac 100644 --- a/html/cgi-bin/logs.cgi/ids.dat +++ b/html/cgi-bin/logs.cgi/ids.dat @@ -336,7 +336,7 @@ print <$sid\n"; } else { print $sid; diff --git a/html/cgi-bin/proxy.cgi b/html/cgi-bin/proxy.cgi index 772852bb8..ba2455a96 100644 --- a/html/cgi-bin/proxy.cgi +++ b/html/cgi-bin/proxy.cgi @@ -3221,6 +3221,48 @@ END print FILE "\n"; } + open (PORTS,"$acl_ports_ssl"); + my @ssl_ports = ; + close PORTS; + + if (@ssl_ports) { + foreach (@ssl_ports) { + print FILE "acl SSL_ports port $_"; + } + } + + open (PORTS,"$acl_ports_safe"); + my @safe_ports = ; + close PORTS; + + if (@safe_ports) { + foreach (@safe_ports) { + print FILE "acl Safe_ports port $_"; + } + } + + print FILE < 0) { print FILE <; -close PORTS; - -if (@ssl_ports) { - foreach (@ssl_ports) { - print FILE "acl SSL_ports port $_"; - } -} - -open (PORTS,"$acl_ports_safe"); -my @safe_ports = ; -close PORTS; - -if (@safe_ports) { - foreach (@safe_ports) { - print FILE "acl Safe_ports port $_"; - } -} - - print FILE </' metadata.c + cd $(DIR_APP) && ./configure --prefix=/usr cd $(DIR_APP) && make $(MAKETUNING) $(EXTRA_MAKE) cd $(DIR_APP) && make install diff --git a/lfs/openssl-compat b/lfs/openssl-compat index d2ae6a0e9..604ac1324 100644 --- a/lfs/openssl-compat +++ b/lfs/openssl-compat @@ -1,7 +1,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007-2013 IPFire Team # +# Copyright (C) 2007-2014 IPFire Team # # # # 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 # @@ -24,7 +24,7 @@ include Config -VER = 0.9.8y +VER = 0.9.8zb THISAPP = openssl-$(VER) DL_FILE = $(THISAPP).tar.gz @@ -40,7 +40,7 @@ objects = $(DL_FILE) $(DL_FILE) = $(DL_FROM)/$(DL_FILE) -$(DL_FILE)_MD5 = 47c7fb37f78c970f1d30aa2f9e9e26d8 +$(DL_FILE)_MD5 = 65c5f42734f8ecd58990b12a9afa6453 install : $(TARGET) diff --git a/lfs/samba b/lfs/samba index 4bd42cbb2..3772ad302 100644 --- a/lfs/samba +++ b/lfs/samba @@ -32,7 +32,7 @@ DL_FROM = $(URL_IPFIRE) DIR_APP = $(DIR_SRC)/$(THISAPP) TARGET = $(DIR_INFO)/$(THISAPP) PROG = samba -PAK_VER = 58 +PAK_VER = 59 DEPS = "cups krb5" diff --git a/lfs/sane b/lfs/sane index 842b54846..39b9603b5 100644 --- a/lfs/sane +++ b/lfs/sane @@ -33,9 +33,9 @@ DIR_APP = $(DIR_SRC)/sane-backends-$(VER) TARGET = $(DIR_INFO)/$(THISAPP) PROG = sane -PAK_VER = 3 +PAK_VER = 4 -DEPS = "libtiff" +DEPS = "cups libtiff" ############################################################################### # Top-level Rules diff --git a/lfs/squid b/lfs/squid index e050b17c5..921feebf2 100644 --- a/lfs/squid +++ b/lfs/squid @@ -24,7 +24,7 @@ include Config -VER = 3.4.5 +VER = 3.4.7 THISAPP = squid-$(VER) DL_FILE = $(THISAPP).tar.xz @@ -40,7 +40,7 @@ objects = $(DL_FILE) $(DL_FILE) = $(DL_FROM)/$(DL_FILE) -$(DL_FILE)_MD5 = a831efb36cfbaa419f8dc7a43cba72c9 +$(DL_FILE)_MD5 = 74677634121649ccb87a5655fcd4298d install : $(TARGET) diff --git a/make.sh b/make.sh index f1c39dbec..536ed6fcd 100755 --- a/make.sh +++ b/make.sh @@ -25,8 +25,8 @@ NAME="IPFire" # Software name SNAME="ipfire" # Short name VERSION="2.15" # Version number -CORE="82" # Core Level (Filename) -PAKFIRE_CORE="82" # Core Level (PAKFIRE) +CORE="83" # Core Level (Filename) +PAKFIRE_CORE="83" # Core Level (PAKFIRE) GIT_BRANCH=`git rev-parse --abbrev-ref HEAD` # Git Branch SLOGAN="www.ipfire.org" # Software slogan CONFIG_ROOT=/var/ipfire # Configuration rootdir diff --git a/src/initscripts/init.d/minidlna b/src/initscripts/init.d/minidlna index 682306760..74ad8f880 100644 --- a/src/initscripts/init.d/minidlna +++ b/src/initscripts/init.d/minidlna @@ -16,17 +16,17 @@ case "${1}" in start) boot_mesg "Starting minidlna..." - loadproc /usr/sbin/minidlna + loadproc /usr/sbin/minidlnad ;; stop) boot_mesg "Stopping minidlna..." - killproc /usr/sbin/minidlna + killproc /usr/sbin/minidlnad ;; reload) boot_mesg "Reloading minidlna..." - reloadproc /usr/sbin/minidlna + reloadproc /usr/sbin/minidlnad ;; restart) @@ -36,7 +36,7 @@ case "${1}" in ;; status) - statusproc /usr/sbin/minidlna + statusproc /usr/sbin/minidlnad ;; *) diff --git a/src/patches/bash-3.2-CVE-2014-6271.patch b/src/patches/bash-3.2-CVE-2014-6271.patch new file mode 100644 index 000000000..396491603 --- /dev/null +++ b/src/patches/bash-3.2-CVE-2014-6271.patch @@ -0,0 +1,72 @@ +*** ../bash-3.2.51/builtins/common.h 2006-03-06 09:38:44.000000000 -0500 +--- builtins/common.h 2014-09-16 19:08:02.000000000 -0400 +*************** +*** 34,37 **** +--- 34,39 ---- + + /* Flags for describe_command, shared between type.def and command.def */ ++ #define SEVAL_FUNCDEF 0x080 /* only allow function definitions */ ++ #define SEVAL_ONECMD 0x100 /* only allow a single command */ + #define CDESC_ALL 0x001 /* type -a */ + #define CDESC_SHORTDESC 0x002 /* command -V */ +*** ../bash-3.2.51/builtins/evalstring.c 2008-11-15 17:47:04.000000000 -0500 +--- builtins/evalstring.c 2014-09-16 19:08:02.000000000 -0400 +*************** +*** 235,238 **** +--- 235,246 ---- + struct fd_bitmap *bitmap; + ++ if ((flags & SEVAL_FUNCDEF) && command->type != cm_function_def) ++ { ++ internal_warning ("%s: ignoring function definition attempt", from_file); ++ should_jump_to_top_level = 0; ++ last_result = last_command_exit_value = EX_BADUSAGE; ++ break; ++ } ++ + bitmap = new_fd_bitmap (FD_BITMAP_SIZE); + begin_unwind_frame ("pe_dispose"); +*************** +*** 292,295 **** +--- 300,306 ---- + dispose_fd_bitmap (bitmap); + discard_unwind_frame ("pe_dispose"); ++ ++ if (flags & SEVAL_ONECMD) ++ break; + } + } +*** ../bash-3.2.51/variables.c 2008-11-15 17:15:06.000000000 -0500 +--- variables.c 2014-09-16 19:10:39.000000000 -0400 +*************** +*** 319,328 **** + strcpy (temp_string + char_index + 1, string); + +! parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST); +! +! /* Ancient backwards compatibility. Old versions of bash exported +! functions like name()=() {...} */ +! if (name[char_index - 1] == ')' && name[char_index - 2] == '(') +! name[char_index - 2] = '\0'; + + if (temp_var = find_function (name)) +--- 319,326 ---- + strcpy (temp_string + char_index + 1, string); + +! /* Don't import function names that are invalid identifiers from the +! environment. */ +! if (legal_identifier (name)) +! parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD); + + if (temp_var = find_function (name)) +*************** +*** 333,340 **** + else + report_error (_("error importing function definition for `%s'"), name); +- +- /* ( */ +- if (name[char_index - 1] == ')' && name[char_index - 2] == '\0') +- name[char_index - 2] = '('; /* ) */ + } + #if defined (ARRAY_VARS) +--- 331,334 ---- diff --git a/src/patches/bash-3.2-CVE-2014-7169.patch b/src/patches/bash-3.2-CVE-2014-7169.patch new file mode 100644 index 000000000..964b91f51 --- /dev/null +++ b/src/patches/bash-3.2-CVE-2014-7169.patch @@ -0,0 +1,11 @@ +*** ../bash-20140912/parse.y 2014-08-26 15:09:42.000000000 -0400 +--- parse.y 2014-09-24 22:47:28.000000000 -0400 +*************** +*** 2959,2962 **** +--- 2959,2964 ---- + word_desc_to_read = (WORD_DESC *)NULL; + ++ eol_ungetc_lookahead = 0; ++ + current_token = '\n'; /* XXX */ + last_read_token = '\n'; diff --git a/src/patches/glibc/glibc-rh1008310.patch b/src/patches/glibc/glibc-rh1008310.patch new file mode 100644 index 000000000..3658a9f31 --- /dev/null +++ b/src/patches/glibc/glibc-rh1008310.patch @@ -0,0 +1,45 @@ +diff -Nrup a/malloc/malloc.c b/malloc/malloc.c +--- a/malloc/malloc.c 2013-09-23 17:08:33.698331221 -0400 ++++ b/malloc/malloc.c 2013-09-23 21:04:25.901270645 -0400 +@@ -3879,6 +3879,13 @@ public_mEMALIGn(size_t alignment, size_t + /* Otherwise, ensure that it is at least a minimum chunk size */ + if (alignment < MINSIZE) alignment = MINSIZE; + ++ /* Check for overflow. */ ++ if (bytes > SIZE_MAX - alignment - MINSIZE) ++ { ++ __set_errno (ENOMEM); ++ return 0; ++ } ++ + arena_get(ar_ptr, bytes + alignment + MINSIZE); + if(!ar_ptr) + return 0; +@@ -3924,6 +3931,13 @@ public_vALLOc(size_t bytes) + + size_t pagesz = mp_.pagesize; + ++ /* Check for overflow. */ ++ if (bytes > SIZE_MAX - pagesz - MINSIZE) ++ { ++ __set_errno (ENOMEM); ++ return 0; ++ } ++ + __malloc_ptr_t (*hook) __MALLOC_PMT ((size_t, size_t, + __const __malloc_ptr_t)) = + force_reg (__memalign_hook); +@@ -3975,6 +3989,13 @@ public_pVALLOc(size_t bytes) + size_t page_mask = mp_.pagesize - 1; + size_t rounded_bytes = (bytes + page_mask) & ~(page_mask); + ++ /* Check for overflow. */ ++ if (bytes > SIZE_MAX - 2*pagesz - MINSIZE) ++ { ++ __set_errno (ENOMEM); ++ return 0; ++ } ++ + __malloc_ptr_t (*hook) __MALLOC_PMT ((size_t, size_t, + __const __malloc_ptr_t)) = + force_reg (__memalign_hook); diff --git a/src/patches/glibc/glibc-rh1022022.patch b/src/patches/glibc/glibc-rh1022022.patch new file mode 100644 index 000000000..6d23bb1e1 --- /dev/null +++ b/src/patches/glibc/glibc-rh1022022.patch @@ -0,0 +1,20 @@ +diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c +index 81e928a..05883bd 100644 +--- a/sysdeps/posix/getaddrinfo.c ++++ b/sysdeps/posix/getaddrinfo.c +@@ -832,8 +832,13 @@ gaih_inet (const char *name, const struct gaih_service *service, + while (!no_more) + { + no_data = 0; +- nss_gethostbyname4_r fct4 +- = __nss_lookup_function (nip, "gethostbyname4_r"); ++ nss_gethostbyname4_r fct4 = NULL; ++ ++ /* gethostbyname4_r sends out parallel A and AAAA queries and ++ is thus only suitable for PF_UNSPEC. */ ++ if (req->ai_family == PF_UNSPEC) ++ fct4 = __nss_lookup_function (nip, "gethostbyname4_r"); ++ + if (fct4 != NULL) + { + int herrno; diff --git a/src/patches/glibc/glibc-rh1091162.patch b/src/patches/glibc/glibc-rh1091162.patch new file mode 100644 index 000000000..782568282 --- /dev/null +++ b/src/patches/glibc/glibc-rh1091162.patch @@ -0,0 +1,58 @@ +commit 362b47fe09ca9a928d444c7e2f7992f7f61bfc3e +Author: Maxim Kuvyrkov +Date: Tue Dec 24 09:44:50 2013 +1300 + + Fix race in free() of fastbin chunk: BZ #15073 + + Perform sanity check only if we have_lock. Due to lockless nature of fastbins + we need to be careful derefencing pointers to fastbin entries (chunksize(old) + in this case) in multithreaded environments. + + The fix is to add have_lock to the if-condition checks. The rest of the patch + only makes code more readable. + + * malloc/malloc.c (_int_free): Perform sanity check only if we + have_lock. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index b1668b5..5e419ad 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -3783,25 +3783,29 @@ _int_free(mstate av, mchunkptr p, int have_lock) + fb = &fastbin (av, idx); + + #ifdef ATOMIC_FASTBINS +- mchunkptr fd; +- mchunkptr old = *fb; ++ /* Atomically link P to its fastbin: P->FD = *FB; *FB = P; */ ++ mchunkptr old = *fb, old2; + unsigned int old_idx = ~0u; + do + { +- /* Another simple check: make sure the top of the bin is not the +- record we are going to add (i.e., double free). */ ++ /* Check that the top of the bin is not the record we are going to add ++ (i.e., double free). */ + if (__builtin_expect (old == p, 0)) + { + errstr = "double free or corruption (fasttop)"; + goto errout; + } +- if (old != NULL) ++ /* Check that size of fastbin chunk at the top is the same as ++ size of the chunk that we are adding. We can dereference OLD ++ only if we have the lock, otherwise it might have already been ++ deallocated. See use of OLD_IDX below for the actual check. */ ++ if (have_lock && old != NULL) + old_idx = fastbin_index(chunksize(old)); +- p->fd = fd = old; ++ p->fd = old2 = old; + } +- while ((old = catomic_compare_and_exchange_val_rel (fb, p, fd)) != fd); ++ while ((old = catomic_compare_and_exchange_val_rel (fb, p, old2)) != old2); + +- if (fd != NULL && __builtin_expect (old_idx != idx, 0)) ++ if (have_lock && old != NULL && __builtin_expect (old_idx != idx, 0)) + { + errstr = "invalid fastbin entry (free)"; + goto errout; diff --git a/src/patches/glibc/glibc-rh1098050.patch b/src/patches/glibc/glibc-rh1098050.patch new file mode 100644 index 000000000..e5ff3ca1b --- /dev/null +++ b/src/patches/glibc/glibc-rh1098050.patch @@ -0,0 +1,28 @@ +commit cf26a0cb6a0bbaca46a01ddad6662e5e5159a32a +Author: Siddhesh Poyarekar +Date: Thu May 15 12:33:11 2014 +0530 + + Return EAI_AGAIN for AF_UNSPEC when herrno is TRY_AGAIN (BZ #16849) + + getaddrinfo correctly returns EAI_AGAIN for AF_INET and AF_INET6 + queries. For AF_UNSPEC however, an older change + (a682a1bf553b1efe4dbb03207fece5b719cec482) broke the check and due to + that the returned error was EAI_NONAME. + + This patch fixes the check so that a non-authoritative not-found is + returned as EAI_AGAIN to the user instead of EAI_NONAME. + +diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c +index 6258330..8f392b9 100644 +--- a/sysdeps/posix/getaddrinfo.c ++++ b/sysdeps/posix/getaddrinfo.c +@@ -867,8 +867,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + if (status != NSS_STATUS_TRYAGAIN + || rc != ERANGE || herrno != NETDB_INTERNAL) + { +- if (status == NSS_STATUS_TRYAGAIN +- && herrno == TRY_AGAIN) ++ if (herrno == TRY_AGAIN) + no_data = EAI_AGAIN; + else + no_data = herrno == NO_DATA; diff --git a/src/patches/glibc/glibc-rh1133809-1.patch b/src/patches/glibc/glibc-rh1133809-1.patch new file mode 100644 index 000000000..12b99499f --- /dev/null +++ b/src/patches/glibc/glibc-rh1133809-1.patch @@ -0,0 +1,199 @@ +2014-08-21 Florian Weimer + + [BZ #17187] + * iconv/gconv_trans.c (struct known_trans, search_tree, lock, + trans_compare, open_translit, __gconv_translit_find): + Remove module loading code. + +diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c +index 1e25854..d71c029 100644 +--- a/iconv/gconv_trans.c ++++ b/iconv/gconv_trans.c +@@ -238,181 +238,11 @@ __gconv_transliterate (struct __gconv_step *step, + return __GCONV_ILLEGAL_INPUT; + } + +- +-/* Structure to represent results of found (or not) transliteration +- modules. */ +-struct known_trans +-{ +- /* This structure must remain the first member. */ +- struct trans_struct info; +- +- char *fname; +- void *handle; +- int open_count; +-}; +- +- +-/* Tree with results of previous calls to __gconv_translit_find. */ +-static void *search_tree; +- +-/* We modify global data. */ +-__libc_lock_define_initialized (static, lock); +- +- +-/* Compare two transliteration entries. */ +-static int +-trans_compare (const void *p1, const void *p2) +-{ +- const struct known_trans *s1 = (const struct known_trans *) p1; +- const struct known_trans *s2 = (const struct known_trans *) p2; +- +- return strcmp (s1->info.name, s2->info.name); +-} +- +- +-/* Open (maybe reopen) the module named in the struct. Get the function +- and data structure pointers we need. */ +-static int +-open_translit (struct known_trans *trans) +-{ +- __gconv_trans_query_fct queryfct; +- +- trans->handle = __libc_dlopen (trans->fname); +- if (trans->handle == NULL) +- /* Not available. */ +- return 1; +- +- /* Find the required symbol. */ +- queryfct = __libc_dlsym (trans->handle, "gconv_trans_context"); +- if (queryfct == NULL) +- { +- /* We cannot live with that. */ +- close_and_out: +- __libc_dlclose (trans->handle); +- trans->handle = NULL; +- return 1; +- } +- +- /* Get the context. */ +- if (queryfct (trans->info.name, &trans->info.csnames, &trans->info.ncsnames) +- != 0) +- goto close_and_out; +- +- /* Of course we also have to have the actual function. */ +- trans->info.trans_fct = __libc_dlsym (trans->handle, "gconv_trans"); +- if (trans->info.trans_fct == NULL) +- goto close_and_out; +- +- /* Now the optional functions. */ +- trans->info.trans_init_fct = +- __libc_dlsym (trans->handle, "gconv_trans_init"); +- trans->info.trans_context_fct = +- __libc_dlsym (trans->handle, "gconv_trans_context"); +- trans->info.trans_end_fct = +- __libc_dlsym (trans->handle, "gconv_trans_end"); +- +- trans->open_count = 1; +- +- return 0; +-} +- +- + int + internal_function + __gconv_translit_find (struct trans_struct *trans) + { +- struct known_trans **found; +- const struct path_elem *runp; +- int res = 1; +- +- /* We have to have a name. */ +- assert (trans->name != NULL); +- +- /* Acquire the lock. */ +- __libc_lock_lock (lock); +- +- /* See whether we know this module already. */ +- found = __tfind (trans, &search_tree, trans_compare); +- if (found != NULL) +- { +- /* Is this module available? */ +- if ((*found)->handle != NULL) +- { +- /* Maybe we have to reopen the file. */ +- if ((*found)->handle != (void *) -1) +- /* The object is not unloaded. */ +- res = 0; +- else if (open_translit (*found) == 0) +- { +- /* Copy the data. */ +- *trans = (*found)->info; +- (*found)->open_count++; +- res = 0; +- } +- } +- } +- else +- { +- size_t name_len = strlen (trans->name) + 1; +- int need_so = 0; +- struct known_trans *newp; +- +- /* We have to continue looking for the module. */ +- if (__gconv_path_elem == NULL) +- __gconv_get_path (); +- +- /* See whether we have to append .so. */ +- if (name_len <= 4 || memcmp (&trans->name[name_len - 4], ".so", 3) != 0) +- need_so = 1; +- +- /* Create a new entry. */ +- newp = (struct known_trans *) malloc (sizeof (struct known_trans) +- + (__gconv_max_path_elem_len +- + name_len + 3) +- + name_len); +- if (newp != NULL) +- { +- char *cp; +- +- /* Clear the struct. */ +- memset (newp, '\0', sizeof (struct known_trans)); +- +- /* Store a copy of the module name. */ +- newp->info.name = cp = (char *) (newp + 1); +- cp = __mempcpy (cp, trans->name, name_len); +- +- newp->fname = cp; +- +- /* Search in all the directories. */ +- for (runp = __gconv_path_elem; runp->name != NULL; ++runp) +- { +- cp = __mempcpy (__stpcpy ((char *) newp->fname, runp->name), +- trans->name, name_len); +- if (need_so) +- memcpy (cp, ".so", sizeof (".so")); +- +- if (open_translit (newp) == 0) +- { +- /* We found a module. */ +- res = 0; +- break; +- } +- } +- +- if (res) +- newp->fname = NULL; +- +- /* In any case we'll add the entry to our search tree. */ +- if (__tsearch (newp, &search_tree, trans_compare) == NULL) +- { +- /* Yickes, this should not happen. Unload the object. */ +- res = 1; +- /* XXX unload here. */ +- } +- } +- } +- +- __libc_lock_unlock (lock); +- +- return res; ++ /* This function always fails. Transliteration module loading is ++ not implemented. */ ++ return 1; + } +-- +1.9.3 + diff --git a/src/patches/glibc/glibc-rh1133809-2.patch b/src/patches/glibc/glibc-rh1133809-2.patch new file mode 100644 index 000000000..8148abbbc --- /dev/null +++ b/src/patches/glibc/glibc-rh1133809-2.patch @@ -0,0 +1,625 @@ +commit 585367266923156ac6fb789939a923641ba5aaf4 +Author: Florian Weimer +Date: Wed May 28 14:05:03 2014 +0200 + + manual: Update the locale documentation + +commit 4e8f95a0df7c2300b830ec12c0ae1e161bc8a8a3 +Author: Florian Weimer +Date: Mon May 12 15:24:12 2014 +0200 + + _nl_find_locale: Improve handling of crafted locale names [BZ #17137] + + Prevent directory traversal in locale-related environment variables + (CVE-2014-0475). + +commit d183645616b0533b3acee28f1a95570bffbdf50f +Author: Florian Weimer +Date: Wed May 28 14:41:52 2014 +0200 + + setlocale: Use the heap for the copy of the locale argument + + This avoids alloca calls with potentially large arguments. + +diff -pruN glibc-2.18/locale/findlocale.c glibc-2.18.patched/locale/findlocale.c +--- glibc-2.18/locale/findlocale.c 2013-08-11 04:22:55.000000000 +0530 ++++ glibc-2.18.patched/locale/findlocale.c 2014-08-26 16:14:50.403253778 +0530 +@@ -17,6 +17,7 @@ + 02111-1307 USA. */ + + #include ++#include + #include + #include + #include +@@ -57,6 +58,45 @@ struct loaded_l10nfile *_nl_locale_file_ + + const char _nl_default_locale_path[] attribute_hidden = LOCALEDIR; + ++/* Checks if the name is actually present, that is, not NULL and not ++ empty. */ ++static inline int ++name_present (const char *name) ++{ ++ return name != NULL && name[0] != '\0'; ++} ++ ++/* Checks that the locale name neither extremely long, nor contains a ++ ".." path component (to prevent directory traversal). */ ++static inline int ++valid_locale_name (const char *name) ++{ ++ /* Not set. */ ++ size_t namelen = strlen (name); ++ /* Name too long. The limit is arbitrary and prevents stack overflow ++ issues later. */ ++ if (__builtin_expect (namelen > 255, 0)) ++ return 0; ++ /* Directory traversal attempt. */ ++ static const char slashdot[4] = {'/', '.', '.', '/'}; ++ if (__builtin_expect (memmem (name, namelen, ++ slashdot, sizeof (slashdot)) != NULL, 0)) ++ return 0; ++ if (namelen == 2 && __builtin_expect (name[0] == '.' && name [1] == '.', 0)) ++ return 0; ++ if (namelen >= 3 ++ && __builtin_expect (((name[0] == '.' ++ && name[1] == '.' ++ && name[2] == '/') ++ || (name[namelen - 3] == '/' ++ && name[namelen - 2] == '.' ++ && name[namelen - 1] == '.')), 0)) ++ return 0; ++ /* If there is a slash in the name, it must start with one. */ ++ if (__builtin_expect (memchr (name, '/', namelen) != NULL, 0) && name[0] != '/') ++ return 0; ++ return 1; ++} + + struct __locale_data * + internal_function +@@ -65,7 +105,7 @@ _nl_find_locale (const char *locale_path + { + int mask; + /* Name of the locale for this category. */ +- char *loc_name; ++ char *loc_name = (char *) *name; + const char *language; + const char *modifier; + const char *territory; +@@ -73,31 +113,39 @@ _nl_find_locale (const char *locale_path + const char *normalized_codeset; + struct loaded_l10nfile *locale_file; + +- if ((*name)[0] == '\0') ++ if (loc_name[0] == '\0') + { + /* The user decides which locale to use by setting environment + variables. */ +- *name = getenv ("LC_ALL"); +- if (*name == NULL || (*name)[0] == '\0') +- *name = getenv (_nl_category_names.str ++ loc_name = getenv ("LC_ALL"); ++ if (!name_present (loc_name)) ++ loc_name = getenv (_nl_category_names.str + + _nl_category_name_idxs[category]); +- if (*name == NULL || (*name)[0] == '\0') +- *name = getenv ("LANG"); ++ if (!name_present (loc_name)) ++ loc_name = getenv ("LANG"); ++ if (!name_present (loc_name)) ++ loc_name = (char *) _nl_C_name; + } + +- if (*name == NULL || (*name)[0] == '\0' +- || (__builtin_expect (__libc_enable_secure, 0) +- && strchr (*name, '/') != NULL)) +- *name = (char *) _nl_C_name; ++ /* We used to fall back to the C locale if the name contains a slash ++ character '/', but we now check for directory traversal in ++ valid_locale_name, so this is no longer necessary. */ + +- if (__builtin_expect (strcmp (*name, _nl_C_name), 1) == 0 +- || __builtin_expect (strcmp (*name, _nl_POSIX_name), 1) == 0) ++ if (__builtin_expect (strcmp (loc_name, _nl_C_name), 1) == 0 ++ || __builtin_expect (strcmp (loc_name, _nl_POSIX_name), 1) == 0) + { + /* We need not load anything. The needed data is contained in + the library itself. */ + *name = (char *) _nl_C_name; + return _nl_C[category]; + } ++ else if (!valid_locale_name (loc_name)) ++ { ++ __set_errno (EINVAL); ++ return NULL; ++ } ++ ++ *name = loc_name; + + /* We really have to load some data. First we try the archive, + but only if there was no LOCPATH environment variable specified. */ +diff -pruN glibc-2.18/locale/setlocale.c glibc-2.18.patched/locale/setlocale.c +--- glibc-2.18/locale/setlocale.c 2013-08-11 04:22:55.000000000 +0530 ++++ glibc-2.18.patched/locale/setlocale.c 2014-08-26 16:14:50.401253764 +0530 +@@ -272,6 +272,8 @@ setlocale (int category, const char *loc + of entries of the form `CATEGORY=VALUE'. */ + const char *newnames[__LC_LAST]; + struct __locale_data *newdata[__LC_LAST]; ++ /* Copy of the locale argument, for in-place splitting. */ ++ char *locale_copy = NULL; + + /* Set all name pointers to the argument name. */ + for (category = 0; category < __LC_LAST; ++category) +@@ -281,7 +283,13 @@ setlocale (int category, const char *loc + if (__builtin_expect (strchr (locale, ';') != NULL, 0)) + { + /* This is a composite name. Make a copy and split it up. */ +- char *np = strdupa (locale); ++ locale_copy = strdup (locale); ++ if (__builtin_expect (locale_copy == NULL, 0)) ++ { ++ __libc_rwlock_unlock (__libc_setlocale_lock); ++ return NULL; ++ } ++ char *np = locale_copy; + char *cp; + int cnt; + +@@ -299,6 +307,7 @@ setlocale (int category, const char *loc + { + error_return: + __libc_rwlock_unlock (__libc_setlocale_lock); ++ free (locale_copy); + + /* Bogus category name. */ + ERROR_RETURN; +@@ -391,8 +400,9 @@ setlocale (int category, const char *loc + /* Critical section left. */ + __libc_rwlock_unlock (__libc_setlocale_lock); + +- /* Free the resources (the locale path variable). */ ++ /* Free the resources. */ + free (locale_path); ++ free (locale_copy); + + return composite; + } +diff -pruN glibc-2.18/localedata/Makefile glibc-2.18.patched/localedata/Makefile +--- glibc-2.18/localedata/Makefile 2014-08-26 16:15:22.656474571 +0530 ++++ glibc-2.18.patched/localedata/Makefile 2014-08-26 16:14:50.403253778 +0530 +@@ -77,7 +77,7 @@ locale_test_suite := tst_iswalnum tst_is + + tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \ + tst-leaks tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \ +- tst-strfmon1 tst-sscanf tst-strptime ++ tst-strfmon1 tst-sscanf tst-strptime tst-setlocale3 + ifeq (yes,$(build-shared)) + ifneq (no,$(PERL)) + tests: $(objpfx)mtrace-tst-leaks +@@ -288,6 +288,7 @@ tst-strfmon1-ENV = $(TEST_MBWC_ENV) + tst-strptime-ENV = $(TEST_MBWC_ENV) + + tst-setlocale-ENV = LOCPATH=$(common-objpfx)localedata LC_ALL=ja_JP.EUC-JP ++tst-setlocale3-ENV = LOCPATH=$(common-objpfx)localedata + + bug-iconv-trans-ENV = LOCPATH=$(common-objpfx)localedata + +diff -pruN glibc-2.18/localedata/tst-setlocale3.c glibc-2.18.patched/localedata/tst-setlocale3.c +--- glibc-2.18/localedata/tst-setlocale3.c 1970-01-01 05:30:00.000000000 +0530 ++++ glibc-2.18.patched/localedata/tst-setlocale3.c 2014-08-26 16:14:50.403253778 +0530 +@@ -0,0 +1,203 @@ ++/* Regression test for setlocale invalid environment variable handling. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++/* The result of setlocale may be overwritten by subsequent calls, so ++ this wrapper makes a copy. */ ++static char * ++setlocale_copy (int category, const char *locale) ++{ ++ const char *result = setlocale (category, locale); ++ if (result == NULL) ++ return NULL; ++ return strdup (result); ++} ++ ++static char *de_locale; ++ ++static void ++setlocale_fail (const char *envstring) ++{ ++ setenv ("LC_CTYPE", envstring, 1); ++ if (setlocale (LC_CTYPE, "") != NULL) ++ { ++ printf ("unexpected setlocale success for \"%s\" locale\n", envstring); ++ exit (1); ++ } ++ const char *newloc = setlocale (LC_CTYPE, NULL); ++ if (strcmp (newloc, de_locale) != 0) ++ { ++ printf ("failed setlocale call \"%s\" changed locale to \"%s\"\n", ++ envstring, newloc); ++ exit (1); ++ } ++} ++ ++static void ++setlocale_success (const char *envstring) ++{ ++ setenv ("LC_CTYPE", envstring, 1); ++ char *newloc = setlocale_copy (LC_CTYPE, ""); ++ if (newloc == NULL) ++ { ++ printf ("setlocale for \"%s\": %m\n", envstring); ++ exit (1); ++ } ++ if (strcmp (newloc, de_locale) == 0) ++ { ++ printf ("setlocale with LC_CTYPE=\"%s\" left locale at \"%s\"\n", ++ envstring, de_locale); ++ exit (1); ++ } ++ if (setlocale (LC_CTYPE, de_locale) == NULL) ++ { ++ printf ("restoring locale \"%s\" with LC_CTYPE=\"%s\": %m\n", ++ de_locale, envstring); ++ exit (1); ++ } ++ char *newloc2 = setlocale_copy (LC_CTYPE, newloc); ++ if (newloc2 == NULL) ++ { ++ printf ("restoring locale \"%s\" following \"%s\": %m\n", ++ newloc, envstring); ++ exit (1); ++ } ++ if (strcmp (newloc, newloc2) != 0) ++ { ++ printf ("representation of locale \"%s\" changed from \"%s\" to \"%s\"", ++ envstring, newloc, newloc2); ++ exit (1); ++ } ++ free (newloc); ++ free (newloc2); ++ ++ if (setlocale (LC_CTYPE, de_locale) == NULL) ++ { ++ printf ("restoring locale \"%s\" with LC_CTYPE=\"%s\": %m\n", ++ de_locale, envstring); ++ exit (1); ++ } ++} ++ ++/* Checks that a known-good locale still works if LC_ALL contains a ++ value which should be ignored. */ ++static void ++setlocale_ignore (const char *to_ignore) ++{ ++ const char *fr_locale = "fr_FR.UTF-8"; ++ setenv ("LC_CTYPE", fr_locale, 1); ++ char *expected_locale = setlocale_copy (LC_CTYPE, ""); ++ if (expected_locale == NULL) ++ { ++ printf ("setlocale with LC_CTYPE=\"%s\" failed: %m\n", fr_locale); ++ exit (1); ++ } ++ if (setlocale (LC_CTYPE, de_locale) == NULL) ++ { ++ printf ("failed to restore locale: %m\n"); ++ exit (1); ++ } ++ unsetenv ("LC_CTYPE"); ++ ++ setenv ("LC_ALL", to_ignore, 1); ++ setenv ("LC_CTYPE", fr_locale, 1); ++ const char *actual_locale = setlocale (LC_CTYPE, ""); ++ if (actual_locale == NULL) ++ { ++ printf ("setlocale with LC_ALL, LC_CTYPE=\"%s\" failed: %m\n", ++ fr_locale); ++ exit (1); ++ } ++ if (strcmp (actual_locale, expected_locale) != 0) ++ { ++ printf ("setlocale under LC_ALL failed: got \"%s\", expected \"%s\"\n", ++ actual_locale, expected_locale); ++ exit (1); ++ } ++ unsetenv ("LC_CTYPE"); ++ setlocale_success (fr_locale); ++ unsetenv ("LC_ALL"); ++ free (expected_locale); ++} ++ ++static int ++do_test (void) ++{ ++ /* The glibc test harness sets this environment variable ++ uncondionally. */ ++ unsetenv ("LC_ALL"); ++ ++ de_locale = setlocale_copy (LC_CTYPE, "de_DE.UTF-8"); ++ if (de_locale == NULL) ++ { ++ printf ("setlocale (LC_CTYPE, \"de_DE.UTF-8\"): %m\n"); ++ return 1; ++ } ++ setlocale_success ("C"); ++ setlocale_success ("en_US.UTF-8"); ++ setlocale_success ("/en_US.UTF-8"); ++ setlocale_success ("//en_US.UTF-8"); ++ setlocale_ignore (""); ++ ++ setlocale_fail ("does-not-exist"); ++ setlocale_fail ("/"); ++ setlocale_fail ("/../localedata/en_US.UTF-8"); ++ setlocale_fail ("en_US.UTF-8/"); ++ setlocale_fail ("en_US.UTF-8/.."); ++ setlocale_fail ("en_US.UTF-8/../en_US.UTF-8"); ++ setlocale_fail ("../localedata/en_US.UTF-8"); ++ { ++ size_t large_length = 1024; ++ char *large_name = malloc (large_length + 1); ++ if (large_name == NULL) ++ { ++ puts ("malloc failure"); ++ return 1; ++ } ++ memset (large_name, '/', large_length); ++ const char *suffix = "en_US.UTF-8"; ++ strcpy (large_name + large_length - strlen (suffix), suffix); ++ setlocale_fail (large_name); ++ free (large_name); ++ } ++ { ++ size_t huge_length = 64 * 1024 * 1024; ++ char *huge_name = malloc (huge_length + 1); ++ if (huge_name == NULL) ++ { ++ puts ("malloc failure"); ++ return 1; ++ } ++ memset (huge_name, 'X', huge_length); ++ huge_name[huge_length] = '\0'; ++ /* Construct a composite locale specification. */ ++ const char *prefix = "LC_CTYPE=de_DE.UTF-8;LC_TIME="; ++ memcpy (huge_name, prefix, strlen (prefix)); ++ setlocale_fail (huge_name); ++ free (huge_name); ++ } ++ ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff -pruN glibc-2.18/manual/locale.texi glibc-2.18.patched/manual/locale.texi +--- glibc-2.18/manual/locale.texi 2013-08-11 04:22:55.000000000 +0530 ++++ glibc-2.18.patched/manual/locale.texi 2014-08-26 16:14:50.404253785 +0530 +@@ -29,6 +29,7 @@ will follow the conventions preferred by + * Setting the Locale:: How a program specifies the locale + with library functions. + * Standard Locales:: Locale names available on all systems. ++* Locale Names:: Format of system-specific locale names. + * Locale Information:: How to access the information for the locale. + * Formatting Numbers:: A dedicated function to format numbers. + * Yes-or-No Questions:: Check a Response against the locale. +@@ -99,14 +100,16 @@ locale named @samp{espana-castellano} to + most of Spain. + + The set of locales supported depends on the operating system you are +-using, and so do their names. We can't make any promises about what +-locales will exist, except for one standard locale called @samp{C} or +-@samp{POSIX}. Later we will describe how to construct locales. +-@comment (@pxref{Building Locale Files}). ++using, and so do their names, except that the standard locale called ++@samp{C} or @samp{POSIX} always exist. @xref{Locale Names}. ++ ++In order to force the system to always use the default locale, the ++user can set the @code{LC_ALL} environment variable to @samp{C}. + + @cindex combining locales +-A user also has the option of specifying different locales for different +-purposes---in effect, choosing a mixture of multiple locales. ++A user also has the option of specifying different locales for ++different purposes---in effect, choosing a mixture of multiple ++locales. @xref{Locale Categories}. + + For example, the user might specify the locale @samp{espana-castellano} + for most purposes, but specify the locale @samp{usa-english} for +@@ -120,7 +123,7 @@ which locales apply. However, the user + for a particular subset of those purposes. + + @node Locale Categories, Setting the Locale, Choosing Locale, Locales +-@section Categories of Activities that Locales Affect ++@section Locale Categories + @cindex categories for locales + @cindex locale categories + +@@ -128,7 +131,11 @@ The purposes that locales serve are grou + that a user or a program can choose the locale for each category + independently. Here is a table of categories; each name is both an + environment variable that a user can set, and a macro name that you can +-use as an argument to @code{setlocale}. ++use as the first argument to @code{setlocale}. ++ ++The contents of the environment variable (or the string in the second ++argument to @code{setlocale}) has to be a valid locale name. ++@xref{Locale Names}. + + @vtable @code + @comment locale.h +@@ -172,7 +179,7 @@ for affirmative and negative responses. + @comment locale.h + @comment ISO + @item LC_ALL +-This is not an environment variable; it is only a macro that you can use ++This is not a category; it is only a macro that you can use + with @code{setlocale} to set a single locale for all purposes. Setting + this environment variable overwrites all selections by the other + @code{LC_*} variables or @code{LANG}. +@@ -225,13 +232,7 @@ The symbols in this section are defined + @comment ISO + @deftypefun {char *} setlocale (int @var{category}, const char *@var{locale}) + The function @code{setlocale} sets the current locale for category +-@var{category} to @var{locale}. A list of all the locales the system +-provides can be created by running +- +-@pindex locale +-@smallexample +- locale -a +-@end smallexample ++@var{category} to @var{locale}. + + If @var{category} is @code{LC_ALL}, this specifies the locale for all + purposes. The other possible values of @var{category} specify an +@@ -256,10 +257,9 @@ is passed in as @var{locale} parameter. + + When you read the current locale for category @code{LC_ALL}, the value + encodes the entire combination of selected locales for all categories. +-In this case, the value is not just a single locale name. In fact, we +-don't make any promises about what it looks like. But if you specify +-the same ``locale name'' with @code{LC_ALL} in a subsequent call to +-@code{setlocale}, it restores the same combination of locale selections. ++If you specify the same ``locale name'' with @code{LC_ALL} in a ++subsequent call to @code{setlocale}, it restores the same combination ++of locale selections. + + To be sure you can use the returned string encoding the currently selected + locale at a later time, you must make a copy of the string. It is not +@@ -275,6 +275,11 @@ for @var{category}. + If a nonempty string is given for @var{locale}, then the locale of that + name is used if possible. + ++The effective locale name (either the second argument to ++@code{setlocale}, or if the argument is an empty string, the name ++obtained from the process environment) must be valid locale name. ++@xref{Locale Names}. ++ + If you specify an invalid locale name, @code{setlocale} returns a null + pointer and leaves the current locale unchanged. + @end deftypefun +@@ -328,7 +323,7 @@ locale categories, and future versions o + portability, assume that any symbol beginning with @samp{LC_} might be + defined in @file{locale.h}. + +-@node Standard Locales, Locale Information, Setting the Locale, Locales ++@node Standard Locales, Locale Names, Setting the Locale, Locales + @section Standard Locales + + The only locale names you can count on finding on all operating systems +@@ -362,7 +357,94 @@ with the environment, rather than trying + locale explicitly by name. Remember, different machines might have + different sets of locales installed. + +-@node Locale Information, Formatting Numbers, Standard Locales, Locales ++@node Locale Names, Locale Information, Standard Locales, Locales ++@section Locale Names ++ ++The following command prints a list of locales supported by the ++system: ++ ++@pindex locale ++@smallexample ++ locale -a ++@end smallexample ++ ++@strong{Portability Note:} With the notable exception of the standard ++locale names @samp{C} and @samp{POSIX}, locale names are ++system-specific. ++ ++Most locale names follow XPG syntax and consist of up to four parts: ++ ++@smallexample ++@var{language}[_@var{territory}[.@var{codeset}]][@@@var{modifier}] ++@end smallexample ++ ++Beside the first part, all of them are allowed to be missing. If the ++full specified locale is not found, less specific ones are looked for. ++The various parts will be stripped off, in the following order: ++ ++@enumerate ++@item ++codeset ++@item ++normalized codeset ++@item ++territory ++@item ++modifier ++@end enumerate ++ ++For example, the locale name @samp{de_AT.iso885915@@euro} denotes a ++German-language locale for use in Austria, using the ISO-8859-15 ++(Latin-9) character set, and with the Euro as the currency symbol. ++ ++In addition to locale names which follow XPG syntax, systems may ++provide aliases such as @samp{german}. Both categories of names must ++not contain the slash character @samp{/}. ++ ++If the locale name starts with a slash @samp{/}, it is treated as a ++path relative to the configured locale directories; see @code{LOCPATH} ++below. The specified path must not contain a component @samp{..}, or ++the name is invalid, and @code{setlocale} will fail. ++ ++@strong{Portability Note:} POSIX suggests that if a locale name starts ++with a slash @samp{/}, it is resolved as an absolute path. However, ++the GNU C Library treats it as a relative path under the directories listed ++in @code{LOCPATH} (or the default locale directory if @code{LOCPATH} ++is unset). ++ ++Locale names which are longer than an implementation-defined limit are ++invalid and cause @code{setlocale} to fail. ++ ++As a special case, locale names used with @code{LC_ALL} can combine ++several locales, reflecting different locale settings for different ++categories. For example, you might want to use a U.S. locale with ISO ++A4 paper format, so you set @code{LANG} to @samp{en_US.UTF-8}, and ++@code{LC_PAPER} to @samp{de_DE.UTF-8}. In this case, the ++@code{LC_ALL}-style combined locale name is ++ ++@smallexample ++LC_CTYPE=en_US.UTF-8;LC_TIME=en_US.UTF-8;LC_PAPER=de_DE.UTF-8;@dots{} ++@end smallexample ++ ++followed by other category settings not shown here. ++ ++@vindex LOCPATH ++The path used for finding locale data can be set using the ++@code{LOCPATH} environment variable. This variable lists the ++directories in which to search for locale definitions, separated by a ++colon @samp{:}. ++ ++The default path for finding locale data is system specific. A typical ++value for the @code{LOCPATH} default is: ++ ++@smallexample ++/usr/share/locale ++@end smallexample ++ ++The value of @code{LOCPATH} is ignored by privileged programs for ++security reasons, and only the default directory is used. ++ ++@node Locale Information, Formatting Numbers, Locale Names, Locales + @section Accessing Locale Information + + There are several ways to access locale information. The simplest