backport multiple fixes from 2.18

- Preserve errno across _PC_CHOWN_RESTRICTED call on XFS (#977870).
  - Remove PIPE_BUF Linux-specific code (#977872).
  - Fix FPE in memusagestat when malloc utilization is zero (#977874).
  - Accept leading and trailing spaces in getdate input string (#977875).
This commit is contained in:
Siddhesh Poyarekar 2013-06-25 19:51:23 +05:30
parent e84cca1529
commit 901d798946
5 changed files with 594 additions and 1 deletions

67
glibc-rh977870.patch Normal file
View File

@ -0,0 +1,67 @@
commit d755bba40f880c01ced8740a26fecc85534454b9
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Wed Apr 3 10:56:45 2013 +0530
Preserve errno across _PC_CHOWN_RESTRICTED call on XFS
Fix BZ #15305.
On kernel versions earlier than 2.6.29, the Linux kernel exported a
sysctl called restrict_chown for xfs, which could be used to allow
chown to users other than the owner. 2.6.29 removed this support,
causing the open_not_cancel_2 to fail and thus modify errno. The fix
is to save and restore errno so that the caller sees it as unmodified.
Additionally, since the code to check the sysctl is not useful on
newer kernels, we add an ifdef so that in future the code block gets
rmeoved completely.
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index 8fdff7e..ccd4c59 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -221,3 +221,9 @@
#if defined __x86_64__ && __LINUX_KERNEL_VERSION >= 0x030100
# define __ASSUME_GETCPU_SYSCALL 1
#endif
+
+/* 2.6.29 removed the XFS restricted_chown sysctl, so it is pointless looking
+ for it in newer kernels. */
+#if __LINUX_KERNEL_VERSION >= 0x02061d
+# define __ASSUME_XFS_RESTRICTED_CHOWN 1
+#endif
diff --git a/sysdeps/unix/sysv/linux/pathconf.c b/sysdeps/unix/sysv/linux/pathconf.c
index de91a45..723d234 100644
--- a/sysdeps/unix/sysv/linux/pathconf.c
+++ b/sysdeps/unix/sysv/linux/pathconf.c
@@ -289,11 +289,16 @@ __statfs_chown_restricted (int result, const struct statfs *fsbuf)
return -1;
}
+#if __ASSUME_XFS_RESTRICTED_CHOWN
+ return 1;
+#else
int fd;
+ int save_errno;
long int retval = 1;
switch (fsbuf->f_type)
{
case XFS_SUPER_MAGIC:
+ save_errno = errno;
/* Read the value from /proc/sys/fs/xfs/restrict_chown. If we cannot
read it default to assume the restriction is in place. */
fd = open_not_cancel_2 ("/proc/sys/fs/xfs/restrict_chown", O_RDONLY);
@@ -306,6 +311,7 @@ __statfs_chown_restricted (int result, const struct statfs *fsbuf)
close_not_cancel_no_status (fd);
}
+ __set_errno (save_errno);
break;
default:
@@ -313,4 +319,5 @@ __statfs_chown_restricted (int result, const struct statfs *fsbuf)
}
return retval;
+#endif
}

268
glibc-rh977872.patch Normal file
View File

@ -0,0 +1,268 @@
commit adbb8027be47b3295367019b2f45863ea3d6c727
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Thu Mar 7 12:15:08 2013 +0530
Remove PIPE_BUF Linux-specific code
Fixes BZ #12723
The variable pipe buffer size does nothing to the value of PIPE_BUF,
since the number of bytes that are atomically written is still
PIPE_BUF on Linux.
diff --git a/posix/Makefile b/posix/Makefile
index 2cacd21..658c47e 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -86,7 +86,8 @@ tests := tstgetopt testfnm runtests runptests \
tst-rfc3484-3 \
tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \
bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
- bug-getopt5 tst-getopt_long1 bug-regex34
+ bug-getopt5 tst-getopt_long1 bug-regex34 \
+ tst-pathconf
xtests := bug-ga2
ifeq (yes,$(build-shared))
test-srcs := globtest
diff --git a/posix/tst-pathconf.c b/posix/tst-pathconf.c
new file mode 100644
index 0000000..7627a24
--- /dev/null
+++ b/posix/tst-pathconf.c
@@ -0,0 +1,176 @@
+/* Test that values of pathconf and fpathconf are consistent for a file.
+ Copyright (C) 2013 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static void prepare (void);
+#define PREPARE(argc, argv) prepare ()
+
+static int do_test (void);
+#define TEST_FUNCTION do_test ()
+
+#include "../test-skeleton.c"
+
+static int dir_fd;
+static char *dirbuf;
+
+static void
+prepare (void)
+{
+ size_t test_dir_len = strlen (test_dir);
+ static const char dir_name[] = "/tst-pathconf.XXXXXX";
+
+ size_t dirbuflen = test_dir_len + sizeof (dir_name);
+ dirbuf = malloc (dirbuflen);
+ if (dirbuf == NULL)
+ {
+ puts ("Out of memory");
+ exit (1);
+ }
+
+ snprintf (dirbuf, dirbuflen, "%s%s", test_dir, dir_name);
+ if (mkdtemp (dirbuf) == NULL)
+ {
+ printf ("Cannot create temporary directory: %s\n", strerror (errno));
+ exit (1);
+ }
+
+ add_temp_file (dirbuf);
+
+ dir_fd = open (dirbuf, O_RDONLY);
+ if (dir_fd == -1)
+ {
+ printf ("Cannot open directory: %s\n", strerror (errno));
+ exit (1);
+ }
+}
+
+
+static int
+do_test (void)
+{
+ int ret = 0;
+ static const char *fifo_name = "some-fifo";
+
+ size_t filenamelen = strlen (dirbuf) + strlen (fifo_name) + 2;
+ char *filename = malloc (filenamelen);
+
+ snprintf (filename, filenamelen, "%s/%s", dirbuf, fifo_name);
+
+ /* Create a fifo in the directory. */
+ int e = mkfifo (filename, 0777);
+ if (e == -1)
+ {
+ printf ("fifo creation failed (%s)\n", strerror (errno));
+ ret = 1;
+ goto out_nofifo;
+ }
+
+ long dir_pathconf = pathconf (dirbuf, _PC_PIPE_BUF);
+
+ if (dir_pathconf < 0)
+ {
+ printf ("pathconf on directory failed: %s\n", strerror (errno));
+ ret = 1;
+ goto out_nofifo;
+ }
+
+ long fifo_pathconf = pathconf (filename, _PC_PIPE_BUF);
+
+ if (fifo_pathconf < 0)
+ {
+ printf ("pathconf on file failed: %s\n", strerror (errno));
+ ret = 1;
+ goto out_nofifo;
+ }
+
+ int fifo = open (filename, O_RDONLY | O_NONBLOCK);
+
+ if (fifo < 0)
+ {
+ printf ("fifo open failed (%s)\n", strerror (errno));
+ ret = 1;
+ goto out_nofifo;
+ }
+
+ long dir_fpathconf = fpathconf (dir_fd, _PC_PIPE_BUF);
+
+ if (dir_fpathconf < 0)
+ {
+ printf ("fpathconf on directory failed: %s\n", strerror (errno));
+ ret = 1;
+ goto out;
+ }
+
+ long fifo_fpathconf = fpathconf (fifo, _PC_PIPE_BUF);
+
+ if (fifo_fpathconf < 0)
+ {
+ printf ("fpathconf on file failed: %s\n", strerror (errno));
+ ret = 1;
+ goto out;
+ }
+
+ if (fifo_pathconf != fifo_fpathconf)
+ {
+ printf ("fifo pathconf (%ld) != fifo fpathconf (%ld)\n", fifo_pathconf,
+ fifo_fpathconf);
+ ret = 1;
+ goto out;
+ }
+
+ if (dir_pathconf != fifo_pathconf)
+ {
+ printf ("directory pathconf (%ld) != fifo pathconf (%ld)\n",
+ dir_pathconf, fifo_pathconf);
+ ret = 1;
+ goto out;
+ }
+
+ if (dir_fpathconf != fifo_fpathconf)
+ {
+ printf ("directory fpathconf (%ld) != fifo fpathconf (%ld)\n",
+ dir_fpathconf, fifo_fpathconf);
+ ret = 1;
+ goto out;
+ }
+
+out:
+ close (fifo);
+out_nofifo:
+ close (dir_fd);
+
+ if (unlink (filename) != 0)
+ {
+ printf ("Could not remove fifo (%s)\n", strerror (errno));
+ ret = 1;
+ }
+
+ if (rmdir (dirbuf) != 0)
+ {
+ printf ("Could not remove directory (%s)\n", strerror (errno));
+ ret = 1;
+ }
+
+ return ret;
+}
diff --git a/sysdeps/unix/sysv/linux/fpathconf.c b/sysdeps/unix/sysv/linux/fpathconf.c
index c971644..e8c4dc9 100644
--- a/sysdeps/unix/sysv/linux/fpathconf.c
+++ b/sysdeps/unix/sysv/linux/fpathconf.c
@@ -33,7 +33,6 @@ __fpathconf (fd, name)
int name;
{
struct statfs fsbuf;
- int r;
switch (name)
{
@@ -49,12 +48,6 @@ __fpathconf (fd, name)
case _PC_CHOWN_RESTRICTED:
return __statfs_chown_restricted (__fstatfs (fd, &fsbuf), &fsbuf);
- case _PC_PIPE_BUF:
- r = __fcntl (fd, F_GETPIPE_SZ);
- if (r > 0)
- return r;
- /* FALLTHROUGH */
-
default:
return posix_fpathconf (fd, name);
}
diff --git a/sysdeps/unix/sysv/linux/pathconf.c b/sysdeps/unix/sysv/linux/pathconf.c
index edc691e..de91a45 100644
--- a/sysdeps/unix/sysv/linux/pathconf.c
+++ b/sysdeps/unix/sysv/linux/pathconf.c
@@ -39,8 +39,6 @@ long int
__pathconf (const char *file, int name)
{
struct statfs fsbuf;
- int fd;
- int flags;
switch (name)
{
@@ -56,21 +54,6 @@ __pathconf (const char *file, int name)
case _PC_CHOWN_RESTRICTED:
return __statfs_chown_restricted (__statfs (file, &fsbuf), &fsbuf);
- case _PC_PIPE_BUF:
- flags = O_RDONLY|O_NONBLOCK|O_NOCTTY;
-#ifdef O_CLOEXEC
- flags |= O_CLOEXEC;
-#endif
- fd = open_not_cancel_2 (file, flags);
- if (fd >= 0)
- {
- long int r = __fcntl (fd, F_GETPIPE_SZ);
- close_not_cancel_no_status (fd);
- if (r > 0)
- return r;
- }
- /* FALLTHROUGH */
-
default:
return posix_pathconf (file, name);
}

148
glibc-rh977874.patch Normal file
View File

@ -0,0 +1,148 @@
commit 7da6d9ed266105e0ebefd01a4b6bf08bf56257c3
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Tue Feb 26 14:24:40 2013 +0530
Fix FPE in memusagestat when malloc utilization is zero
[BZ #15160]
Draw graphs for heap and stack only if MAXSIZE_HEAP and MAXSIZE_STACK
are non-zero.
diff --git a/malloc/memusagestat.c b/malloc/memusagestat.c
index f561e0d..7bbd009 100644
--- a/malloc/memusagestat.c
+++ b/malloc/memusagestat.c
@@ -319,17 +319,26 @@ main (int argc, char *argv[])
for (line = 1; line <= 3; ++line)
{
- cnt = ((ysize - 40) * (maxsize_heap / 4 * line / heap_scale)) /
- (maxsize_heap / heap_scale);
- gdImageDashedLine (im_out, 40, ysize - 20 - cnt, xsize - 40,
- ysize - 20 - cnt, red);
- snprintf (buf, sizeof (buf), heap_format, maxsize_heap / 4 * line /
- heap_scale);
- gdImageString (im_out, gdFontSmall, 39 - strlen (buf) * 6,
- ysize - 26 - cnt, (unsigned char *) buf, red);
-
- cnt2 = ((ysize - 40) * (maxsize_stack / 4 * line / stack_scale)) /
- (maxsize_stack / stack_scale);
+ if (maxsize_heap > 0)
+ {
+ cnt = (((ysize - 40) * (maxsize_heap / 4 * line / heap_scale))
+ / (maxsize_heap / heap_scale));
+ gdImageDashedLine (im_out, 40, ysize - 20 - cnt, xsize - 40,
+ ysize - 20 - cnt, red);
+ snprintf (buf, sizeof (buf), heap_format,
+ maxsize_heap / 4 * line / heap_scale);
+ gdImageString (im_out, gdFontSmall, 39 - strlen (buf) * 6,
+ ysize - 26 - cnt, (unsigned char *) buf, red);
+ }
+ else
+ cnt = 0;
+
+ if (maxsize_stack > 0)
+ cnt2 = (((ysize - 40) * (maxsize_stack / 4 * line / stack_scale))
+ / (maxsize_stack / stack_scale));
+ else
+ cnt2 = 0;
+
if (cnt != cnt2)
gdImageDashedLine (im_out, 40, ysize - 20 - cnt2, xsize - 40,
ysize - 20 - cnt2, green);
@@ -372,7 +381,7 @@ main (int argc, char *argv[])
ysize - 14, yellow);
previously = now;
- if (also_total)
+ if (also_total && maxsize_heap > 0)
{
size_t new3;
@@ -386,21 +395,27 @@ main (int argc, char *argv[])
last_total = new3;
}
- // assert (entry.heap <= maxsize_heap);
- new[0] = (ysize - 20) - ((((unsigned long long int) (ysize - 40))
- * entry.heap) / maxsize_heap);
- gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
- last_heap, 40 + ((xsize - 80) * cnt) / total, new[0],
- red);
- last_heap = new[0];
-
- // assert (entry.stack <= maxsize_stack);
- new[1] = (ysize - 20) - ((((unsigned long long int) (ysize - 40))
- * entry.stack) / maxsize_stack);
- gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
- last_stack, 40 + ((xsize - 80) * cnt) / total, new[1],
- green);
- last_stack = new[1];
+ if (maxsize_heap > 0)
+ {
+ new[0] = ((ysize - 20)
+ - ((((unsigned long long int) (ysize - 40))
+ * entry.heap) / maxsize_heap));
+ gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
+ last_heap, 40 + ((xsize - 80) * cnt) / total,
+ new[0], red);
+ last_heap = new[0];
+ }
+
+ if (maxsize_stack > 0)
+ {
+ new[1] = ((ysize - 20)
+ - ((((unsigned long long int) (ysize - 40))
+ * entry.stack) / maxsize_stack));
+ gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
+ last_stack, 40 + ((xsize - 80) * cnt) / total,
+ new[1], green);
+ last_stack = new[1];
+ }
}
cnt = 0;
@@ -448,7 +463,7 @@ main (int argc, char *argv[])
next_tick += MAX (1, total / 20);
}
- if (also_total)
+ if (also_total && maxsize_heap > 0)
{
size_t new3;
@@ -459,16 +474,24 @@ main (int argc, char *argv[])
last_total = new3;
}
- new[0] = (ysize - 20) - ((((unsigned long long int) (ysize - 40))
- * entry.heap) / maxsize_heap);
- gdImageLine (im_out, last_xpos, last_heap, xpos, new[0], red);
- last_heap = new[0];
+ if (maxsize_heap > 0)
+ {
+ new[0] = ((ysize - 20)
+ - ((((unsigned long long int) (ysize - 40))
+ * entry.heap) / maxsize_heap));
+ gdImageLine (im_out, last_xpos, last_heap, xpos, new[0], red);
+ last_heap = new[0];
+ }
- // assert (entry.stack <= maxsize_stack);
- new[1] = (ysize - 20) - ((((unsigned long long int) (ysize - 40))
- * entry.stack) / maxsize_stack);
- gdImageLine (im_out, last_xpos, last_stack, xpos, new[1], green);
- last_stack = new[1];
+ if (maxsize_stack > 0)
+ {
+ new[1] = ((ysize - 20)
+ - ((((unsigned long long int) (ysize - 40))
+ * entry.stack) / maxsize_stack));
+ gdImageLine (im_out, last_xpos, last_stack, xpos, new[1],
+ green);
+ last_stack = new[1];
+ }
last_xpos = xpos;
}

96
glibc-rh977875.patch Normal file
View File

@ -0,0 +1,96 @@
commit abe7f530bf5c741fe6f0658da7be59d8db168f7f
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Wed Apr 10 11:31:46 2013 +0530
Accept leading and trailing spaces in getdate input string
Fixes #15346.
The POSIX description of getdate allows for extra spaces in the
getdate input string. __getdate_r uses strptime internally, which
works fine with extra spaces between format strings (and hence within
an input string) but not with leading and trailing spaces. So we trim
off the leading and trailing spaces before we pass it on to strptime.
diff --git a/time/getdate.c b/time/getdate.c
index 637dd18..eadebc3 100644
--- a/time/getdate.c
+++ b/time/getdate.c
@@ -25,6 +25,8 @@
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
+#include <ctype.h>
+#include <alloca.h>
#define TM_YEAR_BASE 1900
@@ -135,6 +137,44 @@ __getdate_r (const char *string, struct tm *tp)
/* No threads reading this stream. */
__fsetlocking (fp, FSETLOCKING_BYCALLER);
+ /* Skip leading whitespace. */
+ while (isspace (*string))
+ string++;
+
+ size_t inlen, oldlen;
+
+ oldlen = inlen = strlen (string);
+
+ /* Skip trailing whitespace. */
+ while (inlen > 0 && isspace (string[inlen - 1]))
+ inlen--;
+
+ char *instr = NULL;
+
+ if (inlen < oldlen)
+ {
+ bool using_malloc = false;
+
+ if (__libc_use_alloca (inlen + 1))
+ instr = alloca (inlen + 1);
+ else
+ {
+ instr = malloc (inlen + 1);
+ if (instr == NULL)
+ {
+ fclose (fp);
+ return 6;
+ }
+ using_malloc = true;
+ }
+ memcpy (instr, string, inlen);
+ instr[inlen] = '\0';
+ string = instr;
+
+ if (!using_malloc)
+ instr = NULL;
+ }
+
line = NULL;
len = 0;
do
@@ -159,6 +199,8 @@ __getdate_r (const char *string, struct tm *tp)
}
while (!feof_unlocked (fp));
+ free (instr);
+
/* Free the buffer. */
free (line);
diff --git a/time/tst-getdate.c b/time/tst-getdate.c
index 7604e83..dc8ecf4 100644
--- a/time/tst-getdate.c
+++ b/time/tst-getdate.c
@@ -31,6 +31,10 @@ static const struct
} tests [] =
{
{"21:01:10 1999-1-31", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}},
+ {"21:01:10 1999-1-31", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}},
+ {" 21:01:10 1999-1-31", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}},
+ {"21:01:10 1999-1-31 ", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}},
+ {" 21:01:10 1999-1-31 ", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}},
{"21:01:10 1999-2-28", "Universal", 0, {10, 1, 21, 28, 1, 99, 0, 0, 0}},
{"16:30:46 2000-2-29", "Universal", 0, {46, 30,16, 29, 1, 100, 0, 0, 0}},
{"01-08-2000 05:06:07", "Europe/Berlin", 0, {7, 6, 5, 1, 7, 100, 0, 0, 0}}

View File

@ -27,7 +27,7 @@
Summary: The GNU libc libraries
Name: glibc
Version: %{glibcversion}
Release: 9%{?dist}
Release: 10%{?dist}
# GPLv2+ is used in a bunch of programs, LGPLv2+ is used for libraries.
# Things that are linked directly into dynamically linked programs
# and shared libraries (e.g. crt files, lib*_nonshared.a) have an additional
@ -116,6 +116,10 @@ Patch0038: %{name}-rh959034.patch
#
Patch1000: %{name}-rh905877.patch
Patch1001: %{name}-rh958652.patch
Patch1002: %{name}-rh977870.patch
Patch1003: %{name}-rh977872.patch
Patch1004: %{name}-rh977874.patch
Patch1005: %{name}-rh977875.patch
#
# Patches submitted, but not yet approved upstream.
@ -415,6 +419,10 @@ package or when debugging this package.
%patch0038 -p1
%patch2039 -p1
%patch1001 -p1
%patch1002 -p1
%patch1003 -p1
%patch1004 -p1
%patch1005 -p1
# On powerpc32, hp timing is only available in power4/power6
# libs, not in base, so pre-power4 dynamic linker is incompatible
@ -1210,6 +1218,12 @@ rm -f *.filelist*
%endif
%changelog
* Tue Jun 25 2013 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-10
- Preserve errno across _PC_CHOWN_RESTRICTED call on XFS (#977870).
- Remove PIPE_BUF Linux-specific code (#977872).
- Fix FPE in memusagestat when malloc utilization is zero (#977874).
- Accept leading and trailing spaces in getdate input string (#977875).
* Thu Jun 20 2013 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-9
- Set EAI_SYSTEM only when h_errno is NETDB_INTERNAL (#958652).