mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-05-11 09:48:24 +02:00
Merge branch 'master' into kernel-4.9
Signed-off-by: Arne Fitzenreiter <arne_f@ipfire.org>
This commit is contained in:
1697
src/patches/DirectFB-1.5.3-add-missing-davinci-files.patch
Normal file
1697
src/patches/DirectFB-1.5.3-add-missing-davinci-files.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,59 +0,0 @@
|
||||
diff -urN SDL-1.2.11.orig/src/video/fbcon/SDL_fbvideo.c SDL-1.2.11/src/video/fbcon/SDL_fbvideo.c
|
||||
--- SDL-1.2.11.orig/src/video/fbcon/SDL_fbvideo.c 2006-05-17 06:16:06.000000000 +0300
|
||||
+++ SDL-1.2.11/src/video/fbcon/SDL_fbvideo.c 2007-06-24 22:19:41.000000000 +0300
|
||||
@@ -29,9 +29,17 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
-#include <asm/page.h> /* For definition of PAGE_SIZE */
|
||||
#include <linux/vt.h>
|
||||
|
||||
+#if defined(linux)
|
||||
+#define HAS_MMAP_ANON
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/mman.h>
|
||||
+#include <asm/page.h> /* PAGE_SIZE */
|
||||
+#define HAS_SC_PAGESIZE /* _SC_PAGESIZE may be an enum for Linux */
|
||||
+#define HAS_GETPAGESIZE
|
||||
+#endif /* linux */
|
||||
+
|
||||
#include "SDL_video.h"
|
||||
#include "SDL_mouse.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
@@ -474,6 +482,7 @@
|
||||
unsigned int current_h;
|
||||
const char *SDL_fbdev;
|
||||
FILE *modesdb;
|
||||
+ int pagesize = -1;
|
||||
|
||||
/* Initialize the library */
|
||||
SDL_fbdev = SDL_getenv("SDL_FBDEV");
|
||||
@@ -545,9 +554,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
+#if defined(_SC_PAGESIZE) && defined(HAS_SC_PAGESIZE)
|
||||
+ pagesize = sysconf(_SC_PAGESIZE);
|
||||
+#endif
|
||||
+#ifdef _SC_PAGE_SIZE
|
||||
+ if (pagesize == -1)
|
||||
+ pagesize = sysconf(_SC_PAGE_SIZE);
|
||||
+#endif
|
||||
+#ifdef HAS_GETPAGESIZE
|
||||
+ if (pagesize == -1)
|
||||
+ pagesize = getpagesize();
|
||||
+#endif
|
||||
+#ifdef PAGE_SIZE
|
||||
+ if (pagesize == -1)
|
||||
+ pagesize = PAGE_SIZE;
|
||||
+#endif
|
||||
+ if (pagesize == -1)
|
||||
+ pagesize = 4096;
|
||||
+
|
||||
/* Memory map the device, compensating for buggy PPC mmap() */
|
||||
mapped_offset = (((long)finfo.smem_start) -
|
||||
- (((long)finfo.smem_start)&~(PAGE_SIZE-1)));
|
||||
+ (((long)finfo.smem_start)&~(pagesize-1)));
|
||||
mapped_memlen = finfo.smem_len+mapped_offset;
|
||||
mapped_mem = do_mmap(NULL, mapped_memlen,
|
||||
PROT_READ|PROT_WRITE, MAP_SHARED, console_fd, 0);
|
||||
@@ -1,104 +0,0 @@
|
||||
BASH PATCH REPORT
|
||||
=================
|
||||
|
||||
Bash-Release: 3.2
|
||||
Patch-ID: bash32-052
|
||||
|
||||
Bug-Reported-by: Stephane Chazelas <stephane.chazelas@gmail.com>
|
||||
Bug-Reference-ID:
|
||||
Bug-Reference-URL:
|
||||
|
||||
Bug-Description:
|
||||
|
||||
Under certain circumstances, bash will execute user code while processing the
|
||||
environment for exported function definitions.
|
||||
|
||||
Patch (apply with `patch -p0'):
|
||||
|
||||
*** ../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 ----
|
||||
*** ../bash-3.2/patchlevel.h Thu Apr 13 08:31:04 2006
|
||||
--- patchlevel.h Mon Oct 16 14:22:54 2006
|
||||
***************
|
||||
*** 26,30 ****
|
||||
looks for to find the patch level (for the sccs version string). */
|
||||
|
||||
! #define PATCHLEVEL 51
|
||||
|
||||
#endif /* _PATCHLEVEL_H_ */
|
||||
--- 26,30 ----
|
||||
looks for to find the patch level (for the sccs version string). */
|
||||
|
||||
! #define PATCHLEVEL 52
|
||||
|
||||
#endif /* _PATCHLEVEL_H_ */
|
||||
@@ -1,54 +0,0 @@
|
||||
BASH PATCH REPORT
|
||||
=================
|
||||
|
||||
Bash-Release: 3.2
|
||||
Patch-ID: bash32-053
|
||||
|
||||
Bug-Reported-by: Tavis Ormandy <taviso () cmpxchg8b com>
|
||||
Bug-Reference-ID:
|
||||
Bug-Reference-URL: http://twitter.com/taviso/statuses/514887394294652929
|
||||
|
||||
Bug-Description:
|
||||
|
||||
Under certain circumstances, bash can incorrectly save a lookahead character and
|
||||
return it on a subsequent call, even when reading a new line.
|
||||
|
||||
Patch:
|
||||
|
||||
*** ../bash-3.2.52/parse.y 2008-04-29 21:24:55.000000000 -0400
|
||||
--- parse.y 2014-09-25 16:18:41.000000000 -0400
|
||||
***************
|
||||
*** 2504,2507 ****
|
||||
--- 2504,2509 ----
|
||||
word_desc_to_read = (WORD_DESC *)NULL;
|
||||
|
||||
+ eol_ungetc_lookahead = 0;
|
||||
+
|
||||
last_read_token = '\n';
|
||||
token_to_read = '\n';
|
||||
*** ../bash-3.2.52/y.tab.c 2006-09-25 08:15:16.000000000 -0400
|
||||
--- y.tab.c 2014-09-25 20:28:17.000000000 -0400
|
||||
***************
|
||||
*** 3833,3836 ****
|
||||
--- 3833,3838 ----
|
||||
word_desc_to_read = (WORD_DESC *)NULL;
|
||||
|
||||
+ eol_ungetc_lookahead = 0;
|
||||
+
|
||||
last_read_token = '\n';
|
||||
token_to_read = '\n';
|
||||
*** ../bash-3.2/patchlevel.h Thu Apr 13 08:31:04 2006
|
||||
--- patchlevel.h Mon Oct 16 14:22:54 2006
|
||||
***************
|
||||
*** 26,30 ****
|
||||
looks for to find the patch level (for the sccs version string). */
|
||||
|
||||
! #define PATCHLEVEL 52
|
||||
|
||||
#endif /* _PATCHLEVEL_H_ */
|
||||
--- 26,30 ----
|
||||
looks for to find the patch level (for the sccs version string). */
|
||||
|
||||
! #define PATCHLEVEL 53
|
||||
|
||||
#endif /* _PATCHLEVEL_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
84
src/patches/clamav-0.99.2-gcc-6.patch
Normal file
84
src/patches/clamav-0.99.2-gcc-6.patch
Normal file
@@ -0,0 +1,84 @@
|
||||
diff --git a/libclamav/c++/llvm/include/llvm/ADT/StringMap.h b/libclamav/c++/llvm/include/llvm/ADT/StringMap.h
|
||||
index 59ff6aa..1325394 100644
|
||||
--- a/libclamav/c++/llvm/include/llvm/ADT/StringMap.h
|
||||
+++ b/libclamav/c++/llvm/include/llvm/ADT/StringMap.h
|
||||
@@ -169,3 +169,3 @@ public:
|
||||
KeyLength+1;
|
||||
- unsigned Alignment = alignof<StringMapEntry>();
|
||||
+ unsigned Alignment = alignOf<StringMapEntry>();
|
||||
|
||||
diff --git a/libclamav/c++/llvm/include/llvm/CodeGen/SlotIndexes.h b/libclamav/c++/llvm/include/llvm/CodeGen/SlotIndexes.h
|
||||
index 88044c7..86b0f40 100644
|
||||
--- a/libclamav/c++/llvm/include/llvm/CodeGen/SlotIndexes.h
|
||||
+++ b/libclamav/c++/llvm/include/llvm/CodeGen/SlotIndexes.h
|
||||
@@ -417,3 +417,3 @@ namespace llvm {
|
||||
ileAllocator.Allocate(sizeof(IndexListEntry),
|
||||
- alignof<IndexListEntry>()));
|
||||
+ alignOf<IndexListEntry>()));
|
||||
|
||||
diff --git a/libclamav/c++/llvm/include/llvm/Support/AlignOf.h b/libclamav/c++/llvm/include/llvm/Support/AlignOf.h
|
||||
index 6a7a1a6..979e597 100644
|
||||
--- a/libclamav/c++/llvm/include/llvm/Support/AlignOf.h
|
||||
+++ b/libclamav/c++/llvm/include/llvm/Support/AlignOf.h
|
||||
@@ -51,8 +51,8 @@ struct AlignOf {
|
||||
|
||||
-/// alignof - A templated function that returns the mininum alignment of
|
||||
+/// alignOf - A templated function that returns the mininum alignment of
|
||||
/// of a type. This provides no extra functionality beyond the AlignOf
|
||||
/// class besides some cosmetic cleanliness. Example usage:
|
||||
-/// alignof<int>() returns the alignment of an int.
|
||||
+/// alignOf<int>() returns the alignment of an int.
|
||||
template <typename T>
|
||||
-static inline unsigned alignof() { return AlignOf<T>::Alignment; }
|
||||
+static inline unsigned alignOf() { return AlignOf<T>::Alignment; }
|
||||
|
||||
diff --git a/libclamav/c++/llvm/include/llvm/Support/Allocator.h b/libclamav/c++/llvm/include/llvm/Support/Allocator.h
|
||||
index 4a7251f..17caf5e 100644
|
||||
--- a/libclamav/c++/llvm/include/llvm/Support/Allocator.h
|
||||
+++ b/libclamav/c++/llvm/include/llvm/Support/Allocator.h
|
||||
@@ -203,3 +203,3 @@ public:
|
||||
for (char *Ptr = (char*)(Slab+1); Ptr < End; Ptr += sizeof(T)) {
|
||||
- Ptr = Allocator.AlignPtr(Ptr, alignof<T>());
|
||||
+ Ptr = Allocator.AlignPtr(Ptr, alignOf<T>());
|
||||
if (Ptr + sizeof(T) <= End)
|
||||
diff --git a/libclamav/c++/llvm/lib/Analysis/ScalarEvolution.cpp b/libclamav/c++/llvm/lib/Analysis/ScalarEvolution.cpp
|
||||
index b892d85..dc72346 100644
|
||||
--- a/libclamav/c++/llvm/lib/Analysis/ScalarEvolution.cpp
|
||||
+++ b/libclamav/c++/llvm/lib/Analysis/ScalarEvolution.cpp
|
||||
@@ -495,3 +495,3 @@ void SCEVUnknown::print(raw_ostream &OS) const {
|
||||
if (isAlignOf(AllocTy)) {
|
||||
- OS << "alignof(" << *AllocTy << ")";
|
||||
+ OS << "alignOf(" << *AllocTy << ")";
|
||||
return;
|
||||
diff --git a/libclamav/c++/llvm/lib/Target/X86/X86CodeEmitter.cpp b/libclamav/c++/llvm/lib/Target/X86/X86CodeEmitter.cpp
|
||||
index 824021c..757ca50 100644
|
||||
--- a/libclamav/c++/llvm/lib/Target/X86/X86CodeEmitter.cpp
|
||||
+++ b/libclamav/c++/llvm/lib/Target/X86/X86CodeEmitter.cpp
|
||||
@@ -569,3 +569,3 @@ void Emitter<CodeEmitter>::emitMemModRMByte(const MachineInstr &MI,
|
||||
// Calculate what the SS field value should be...
|
||||
- static const unsigned SSTable[] = { ~0, 0, 1, ~0, 2, ~0, ~0, ~0, 3 };
|
||||
+ static const unsigned SSTable[] = { ~0u, 0u, 1u, ~0u, 2u, ~0u, ~0u, ~0u, 3u };
|
||||
unsigned SS = SSTable[Scale.getImm()];
|
||||
diff --git a/libclamav/c++/llvm/lib/Target/X86/X86MCCodeEmitter.cpp b/libclamav/c++/llvm/lib/Target/X86/X86MCCodeEmitter.cpp
|
||||
index 9564fe0..b2b7986 100644
|
||||
--- a/libclamav/c++/llvm/lib/Target/X86/X86MCCodeEmitter.cpp
|
||||
+++ b/libclamav/c++/llvm/lib/Target/X86/X86MCCodeEmitter.cpp
|
||||
@@ -332,3 +332,3 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
|
||||
// Calculate what the SS field value should be...
|
||||
- static const unsigned SSTable[] = { ~0, 0, 1, ~0, 2, ~0, ~0, ~0, 3 };
|
||||
+ static const unsigned SSTable[] = { ~0u, 0u, 1u, ~0u, 2u, ~0u, ~0u, ~0u, 3u };
|
||||
unsigned SS = SSTable[Scale.getImm()];
|
||||
diff --git a/libclamav/mpool.c b/libclamav/mpool.c
|
||||
index cd38e15..b5e537d 100644
|
||||
--- a/libclamav/mpool.c
|
||||
+++ b/libclamav/mpool.c
|
||||
@@ -417,3 +417,3 @@ static size_t from_bits(unsigned int bits) {
|
||||
|
||||
-static inline unsigned int alignof(size_t size)
|
||||
+static inline unsigned int alignOf(size_t size)
|
||||
{
|
||||
@@ -609,3 +609,3 @@ static void* allocate_aligned(struct MPMAP *mpm, size_t size, unsigned align, co
|
||||
void *mpool_malloc(struct MP *mp, size_t size) {
|
||||
- size_t align = alignof(size);
|
||||
+ size_t align = alignOf(size);
|
||||
size_t i, needed = align_increase(size+FRAG_OVERHEAD, align);
|
||||
File diff suppressed because it is too large
Load Diff
170
src/patches/coreutils-8.27-uname-1.patch
Normal file
170
src/patches/coreutils-8.27-uname-1.patch
Normal file
@@ -0,0 +1,170 @@
|
||||
Submitted by: DJ Lucas (dj_at_linuxfromscratch_dot_org)
|
||||
Date: 2012-04-21
|
||||
Initial Package Version: 8.16
|
||||
Upstream Status: Rejected
|
||||
Origin: Based on Gentoo patch
|
||||
Description: Makes uname -m output more descriptive
|
||||
|
||||
diff -Naurp coreutils-8.16-orig/src/uname.c coreutils-8.16/src/uname.c
|
||||
--- coreutils-8.16-orig/src/uname.c 2012-04-22 20:02:39.000000000 +0000
|
||||
+++ coreutils-8.16/src/uname.c 2012-04-22 20:02:50.000000000 +0000
|
||||
@@ -49,6 +49,11 @@
|
||||
# include <mach-o/arch.h>
|
||||
#endif
|
||||
|
||||
+#if defined(__linux__)
|
||||
+# define USE_PROCINFO
|
||||
+# define UNAME_HARDWARE_PLATFORM
|
||||
+#endif
|
||||
+
|
||||
#include "system.h"
|
||||
#include "die.h"
|
||||
#include "error.h"
|
||||
@@ -153,6 +158,117 @@ Print machine architecture.\n\
|
||||
exit (status);
|
||||
}
|
||||
|
||||
+#if defined(USE_PROCINFO)
|
||||
+
|
||||
+# if defined(__s390__) || defined(__s390x__)
|
||||
+# define CPUINFO_FILE "/proc/sysinfo"
|
||||
+# define CPUINFO_FORMAT "%64[^\t :]%*[ :]%256[^\n]%c"
|
||||
+# else
|
||||
+# define CPUINFO_FILE "/proc/cpuinfo"
|
||||
+# define CPUINFO_FORMAT "%64[^\t:]\t:%256[^\n]%c"
|
||||
+# endif
|
||||
+
|
||||
+# define PROCINFO_PROCESSOR 0
|
||||
+# define PROCINFO_HARDWARE_PLATFORM 1
|
||||
+
|
||||
+static void __eat_cpuinfo_space(char *buf)
|
||||
+{
|
||||
+ /* first eat trailing space */
|
||||
+ char *tmp = buf + strlen(buf) - 1;
|
||||
+ while (tmp > buf && isspace(*tmp))
|
||||
+ *tmp-- = '\0';
|
||||
+ /* then eat leading space */
|
||||
+ tmp = buf;
|
||||
+ while (*tmp && isspace(*tmp))
|
||||
+ tmp++;
|
||||
+ if (tmp != buf)
|
||||
+ memmove(buf, tmp, strlen(tmp)+1);
|
||||
+ /* finally collapse whitespace */
|
||||
+ tmp = buf;
|
||||
+ while (tmp[0] && tmp[1]) {
|
||||
+ if (isspace(tmp[0]) && isspace(tmp[1])) {
|
||||
+ memmove(tmp, tmp+1, strlen(tmp));
|
||||
+ continue;
|
||||
+ }
|
||||
+ ++tmp;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int __linux_procinfo(int x, char *fstr, size_t s)
|
||||
+{
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ char *procinfo_keys[] = {
|
||||
+ /* --processor --hardware-platform */
|
||||
+ #if defined(__alpha__)
|
||||
+ "cpu model", "system type"
|
||||
+ #elif defined(__arm__)
|
||||
+ "Processor", "Hardware"
|
||||
+ #elif defined(__avr32__)
|
||||
+ "processor", "cpu family"
|
||||
+ #elif defined(__bfin__)
|
||||
+ "CPU", "BOARD Name"
|
||||
+ #elif defined(__cris__)
|
||||
+ "cpu", "cpu model"
|
||||
+ #elif defined(__frv__)
|
||||
+ "CPU-Core", "System"
|
||||
+ #elif defined(__i386__) || defined(__x86_64__)
|
||||
+ "model name", "vendor_id"
|
||||
+ #elif defined(__ia64__)
|
||||
+ "family", "vendor"
|
||||
+ #elif defined(__hppa__)
|
||||
+ "cpu", "model"
|
||||
+ #elif defined(__m68k__)
|
||||
+ "CPU", "MMU"
|
||||
+ #elif defined(__mips__)
|
||||
+ "cpu model", "system type"
|
||||
+ #elif defined(__powerpc__) || defined(__powerpc64__)
|
||||
+ "cpu", "machine"
|
||||
+ #elif defined(__s390__) || defined(__s390x__)
|
||||
+ "Type", "Manufacturer"
|
||||
+ #elif defined(__sh__)
|
||||
+ "cpu type", "machine"
|
||||
+ #elif defined(sparc) || defined(__sparc__)
|
||||
+ "type", "cpu"
|
||||
+ #elif defined(__vax__)
|
||||
+ "cpu type", "cpu"
|
||||
+ #else
|
||||
+ "unknown", "unknown"
|
||||
+ #endif
|
||||
+ };
|
||||
+
|
||||
+ if ((fp = fopen(CPUINFO_FILE, "r")) != NULL) {
|
||||
+ char key[65], value[257], eol, *ret = NULL;
|
||||
+
|
||||
+ while (fscanf(fp, CPUINFO_FORMAT, key, value, &eol) != EOF) {
|
||||
+ __eat_cpuinfo_space(key);
|
||||
+ if (!strcmp(key, procinfo_keys[x])) {
|
||||
+ __eat_cpuinfo_space(value);
|
||||
+ ret = value;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (eol != '\n') {
|
||||
+ /* we need two fscanf's here in case the previous
|
||||
+ * length limit caused us to read right up to the
|
||||
+ * newline ... doing "%*[^\n]\n" wont eat the newline
|
||||
+ */
|
||||
+ fscanf(fp, "%*[^\n]");
|
||||
+ fscanf(fp, "\n");
|
||||
+ }
|
||||
+ }
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ if (ret) {
|
||||
+ strncpy(fstr, ret, s);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
/* Print ELEMENT, preceded by a space if something has already been
|
||||
printed. */
|
||||
|
||||
@@ -300,10 +416,14 @@ main (int argc, char **argv)
|
||||
if (toprint & PRINT_PROCESSOR)
|
||||
{
|
||||
char const *element = unknown;
|
||||
-#if HAVE_SYSINFO && defined SI_ARCHITECTURE
|
||||
+#if ( HAVE_SYSINFO && defined SI_ARCHITECTURE ) || defined(USE_PROCINFO)
|
||||
{
|
||||
static char processor[257];
|
||||
+#if defined(USE_PROCINFO)
|
||||
+ if (0 <= __linux_procinfo (PROCINFO_PROCESSOR, processor, sizeof processor))
|
||||
+#else
|
||||
if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
|
||||
+#endif
|
||||
element = processor;
|
||||
}
|
||||
#endif
|
||||
@@ -356,9 +476,13 @@ main (int argc, char **argv)
|
||||
if (element == unknown)
|
||||
{
|
||||
static char hardware_platform[257];
|
||||
+#if defined(USE_PROCINFO)
|
||||
+ if (0 <= __linux_procinfo (PROCINFO_HARDWARE_PLATFORM, hardware_platform, sizeof hardware_platform))
|
||||
+#else
|
||||
size_t s = sizeof hardware_platform;
|
||||
static int mib[] = { CTL_HW, UNAME_HARDWARE_PLATFORM };
|
||||
if (sysctl (mib, 2, hardware_platform, &s, 0, 0) >= 0)
|
||||
+#endif
|
||||
element = hardware_platform;
|
||||
}
|
||||
#endif
|
||||
@@ -1,11 +0,0 @@
|
||||
--- dbus-1.0.1.orig/dbus/dbus-sysdeps-unix.c 2009-01-01 03:50:33.000000000 +0200
|
||||
+++ dbus-1.0.1.orig/dbus/dbus-sysdeps-unix.c 2009-01-01 04:09:24.000000000 +0200
|
||||
@@ -992,7 +992,7 @@
|
||||
_dbus_verbose ("read credentials byte\n");
|
||||
|
||||
{
|
||||
-#ifdef SO_PEERCRED
|
||||
+#if defined(SO_PEERCRED) && defined(HAVE_GETPEERUCRED)
|
||||
struct ucred cr;
|
||||
int cr_len = sizeof (cr);
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
From 20cddc824c6501c2082cac41b162c34cd5fcc530 Mon Sep 17 00:00:00 2001
|
||||
From: Khem Raj <raj.khem@gmail.com>
|
||||
Date: Sun, 11 Dec 2016 14:32:00 -0800
|
||||
Subject: [PATCH] Avoid conflicts with integer width macros from TS
|
||||
18661-1:2014
|
||||
|
||||
glibc 2.25+ has now defined these macros in <limits.h>
|
||||
https://sourceware.org/git/?p=glibc.git;a=commit;h=5b17fd0da62bf923cb61d1bb7b08cf2e1f1f9c1a
|
||||
|
||||
Signed-off-by: Khem Raj <raj.khem@gmail.com>
|
||||
---
|
||||
Upstream-Status: Submitted
|
||||
|
||||
fontconfig/fontconfig.h | 2 +-
|
||||
src/fcobjs.h | 2 +-
|
||||
src/fcobjshash.gperf | 2 +-
|
||||
src/fcobjshash.h | 2 +-
|
||||
4 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
Index: fontconfig-2.12.1/fontconfig/fontconfig.h
|
||||
===================================================================
|
||||
--- fontconfig-2.12.1.orig/fontconfig/fontconfig.h
|
||||
+++ fontconfig-2.12.1/fontconfig/fontconfig.h
|
||||
@@ -128,7 +128,8 @@ typedef int FcBool;
|
||||
#define FC_USER_CACHE_FILE ".fonts.cache-" FC_CACHE_VERSION
|
||||
|
||||
/* Adjust outline rasterizer */
|
||||
-#define FC_CHAR_WIDTH "charwidth" /* Int */
|
||||
+#define FC_CHARWIDTH "charwidth" /* Int */
|
||||
+#define FC_CHAR_WIDTH FC_CHARWIDTH
|
||||
#define FC_CHAR_HEIGHT "charheight"/* Int */
|
||||
#define FC_MATRIX "matrix" /* FcMatrix */
|
||||
|
||||
Index: fontconfig-2.12.1/src/fcobjs.h
|
||||
===================================================================
|
||||
--- fontconfig-2.12.1.orig/src/fcobjs.h
|
||||
+++ fontconfig-2.12.1/src/fcobjs.h
|
||||
@@ -51,7 +51,7 @@ FC_OBJECT (DPI, FcTypeDouble, NULL)
|
||||
FC_OBJECT (RGBA, FcTypeInteger, NULL)
|
||||
FC_OBJECT (SCALE, FcTypeDouble, NULL)
|
||||
FC_OBJECT (MINSPACE, FcTypeBool, NULL)
|
||||
-FC_OBJECT (CHAR_WIDTH, FcTypeInteger, NULL)
|
||||
+FC_OBJECT (CHARWIDTH, FcTypeInteger, NULL)
|
||||
FC_OBJECT (CHAR_HEIGHT, FcTypeInteger, NULL)
|
||||
FC_OBJECT (MATRIX, FcTypeMatrix, NULL)
|
||||
FC_OBJECT (CHARSET, FcTypeCharSet, FcCompareCharSet)
|
||||
Index: fontconfig-2.12.1/src/fcobjshash.gperf
|
||||
===================================================================
|
||||
--- fontconfig-2.12.1.orig/src/fcobjshash.gperf
|
||||
+++ fontconfig-2.12.1/src/fcobjshash.gperf
|
||||
@@ -44,7 +44,7 @@ int id;
|
||||
"rgba",FC_RGBA_OBJECT
|
||||
"scale",FC_SCALE_OBJECT
|
||||
"minspace",FC_MINSPACE_OBJECT
|
||||
-"charwidth",FC_CHAR_WIDTH_OBJECT
|
||||
+"charwidth",FC_CHARWIDTH_OBJECT
|
||||
"charheight",FC_CHAR_HEIGHT_OBJECT
|
||||
"matrix",FC_MATRIX_OBJECT
|
||||
"charset",FC_CHARSET_OBJECT
|
||||
Index: fontconfig-2.12.1/src/fcobjshash.h
|
||||
===================================================================
|
||||
--- fontconfig-2.12.1.orig/src/fcobjshash.h
|
||||
+++ fontconfig-2.12.1/src/fcobjshash.h
|
||||
@@ -284,7 +284,7 @@ FcObjectTypeLookup (register const char
|
||||
{(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str43,FC_CHARSET_OBJECT},
|
||||
{-1},
|
||||
#line 47 "fcobjshash.gperf"
|
||||
- {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str45,FC_CHAR_WIDTH_OBJECT},
|
||||
+ {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str45,FC_CHARWIDTH_OBJECT},
|
||||
#line 48 "fcobjshash.gperf"
|
||||
{(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str46,FC_CHAR_HEIGHT_OBJECT},
|
||||
#line 55 "fcobjshash.gperf"
|
||||
21
src/patches/fuse-2.9.2-namespace-conflict-fix.patch
Normal file
21
src/patches/fuse-2.9.2-namespace-conflict-fix.patch
Normal file
@@ -0,0 +1,21 @@
|
||||
diff -up fuse-2.9.2/include/fuse_kernel.h.conflictfix fuse-2.9.2/include/fuse_kernel.h
|
||||
--- fuse-2.9.2/include/fuse_kernel.h.conflictfix 2013-06-26 09:31:57.862198038 -0400
|
||||
+++ fuse-2.9.2/include/fuse_kernel.h 2013-06-26 09:32:19.679198365 -0400
|
||||
@@ -88,12 +88,16 @@
|
||||
#ifndef _LINUX_FUSE_H
|
||||
#define _LINUX_FUSE_H
|
||||
|
||||
-#include <sys/types.h>
|
||||
+#ifdef __linux__
|
||||
+#include <linux/types.h>
|
||||
+#else
|
||||
+#include <stdint.h>
|
||||
#define __u64 uint64_t
|
||||
#define __s64 int64_t
|
||||
#define __u32 uint32_t
|
||||
#define __s32 int32_t
|
||||
#define __u16 uint16_t
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Version negotiation:
|
||||
@@ -1,43 +0,0 @@
|
||||
Submitted By: Matthew Burgess <matthew@linuxfromscratch.org>
|
||||
Date: 2005-09-24
|
||||
Initial Package Version: 3.1.5
|
||||
Upstream Status: From Upstream
|
||||
Origin: http://lists.gnu.org/archive/html/bug-gnu-utils/2005-08/msg00047.html
|
||||
Description: Fixes a bug which causes gawk to segfault when operating on a non-existent file.
|
||||
|
||||
diff -Naur gawk-3.1.5.orig/io.c gawk-3.1.5/io.c
|
||||
--- gawk-3.1.5.orig/io.c 2005-07-26 18:07:43.000000000 +0000
|
||||
+++ gawk-3.1.5/io.c 2005-09-24 14:43:13.771380264 +0000
|
||||
@@ -2480,9 +2480,12 @@
|
||||
{
|
||||
struct stat sbuf;
|
||||
struct open_hook *oh;
|
||||
+ int iop_malloced = FALSE;
|
||||
|
||||
- if (iop == NULL)
|
||||
+ if (iop == NULL) {
|
||||
emalloc(iop, IOBUF *, sizeof(IOBUF), "iop_alloc");
|
||||
+ iop_malloced = TRUE;
|
||||
+ }
|
||||
memset(iop, '\0', sizeof(IOBUF));
|
||||
iop->flag = 0;
|
||||
iop->fd = fd;
|
||||
@@ -2495,7 +2498,8 @@
|
||||
}
|
||||
|
||||
if (iop->fd == INVALID_HANDLE) {
|
||||
- free(iop);
|
||||
+ if (iop_malloced)
|
||||
+ free(iop);
|
||||
return NULL;
|
||||
}
|
||||
if (isatty(iop->fd))
|
||||
@@ -2503,7 +2507,7 @@
|
||||
iop->readsize = iop->size = optimal_bufsize(iop->fd, & sbuf);
|
||||
iop->sbuf = sbuf;
|
||||
if (do_lint && S_ISREG(sbuf.st_mode) && sbuf.st_size == 0)
|
||||
- lintwarn(_("data file `%s' is empty"), name);
|
||||
+ lintwarn(_("data file `%s' is empty"), name);
|
||||
errno = 0;
|
||||
iop->count = iop->scanoff = 0;
|
||||
emalloc(iop->buf, char *, iop->size += 2, "iop_alloc");
|
||||
@@ -1,33 +0,0 @@
|
||||
Submitted By: Jeremy Huntwork (jhuntwork AT linuxfromscratch DOT org)
|
||||
Date: 2008-12-05
|
||||
Initial Package Version: 4.3.2
|
||||
Upstream Status: See below.
|
||||
Origin: DIY Linux, See below.
|
||||
Description: Original patch follows:
|
||||
|
||||
# DIY Linux Patch
|
||||
Date: 2008-09-09
|
||||
Author: Refer Origin.
|
||||
Origin: Partial revert of http://gcc.gnu.org/ml/gcc-cvs/2006-11/msg00416.html
|
||||
Maker: Greg Schafer <gschafer@zip.com.au>
|
||||
Upstream Status: Not applicable. Tweak only for Temptools phase GCC-Pass2.
|
||||
Description: Partially revert GCC driver to pre-GCC-4.3 state to allow startfiles to be
|
||||
found in $prefix when GCC is configured for a non-standard prefix eg: /temptools. Full
|
||||
background info in thread starting here: http://gcc.gnu.org/ml/gcc/2008-03/msg00095.html
|
||||
and GCC bugzilla here: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35532
|
||||
|
||||
diff -Naur gcc-4.3.0-RC-20080222.orig/gcc/gcc.c gcc-4.3.0-RC-20080222/gcc/gcc.c
|
||||
--- gcc-4.3.0-RC-20080222.orig/gcc/gcc.c 2008-01-24 18:57:12.000000000 +0000
|
||||
+++ gcc-4.3.0-RC-20080222/gcc/gcc.c 2008-03-02 06:07:36.000000000 +0000
|
||||
@@ -6370,6 +6370,11 @@
|
||||
machine_suffix,
|
||||
standard_startfile_prefix, NULL),
|
||||
NULL, PREFIX_PRIORITY_LAST, 0, 1);
|
||||
+ add_prefix (&startfile_prefixes,
|
||||
+ concat (standard_exec_prefix,
|
||||
+ machine_suffix,
|
||||
+ standard_startfile_prefix, NULL),
|
||||
+ NULL, PREFIX_PRIORITY_LAST, 0, 1);
|
||||
}
|
||||
|
||||
/* Sysrooted prefixes are relocated because target_system_root is
|
||||
@@ -1,89 +0,0 @@
|
||||
diff -Naur gcc-4.4.7.org/gcc/doc/cppopts.texi gcc-4.4.7/gcc/doc/cppopts.texi
|
||||
--- gcc-4.4.7.org/gcc/doc/cppopts.texi 2008-06-15 11:42:13.000000000 +0200
|
||||
+++ gcc-4.4.7/gcc/doc/cppopts.texi 2013-09-08 16:50:14.353507748 +0200
|
||||
@@ -758,7 +758,7 @@
|
||||
Enable special code to work around file systems which only permit very
|
||||
short file names, such as MS-DOS@.
|
||||
|
||||
-@itemx --help
|
||||
+@item --help
|
||||
@itemx --target-help
|
||||
@opindex help
|
||||
@opindex target-help
|
||||
diff -Naur gcc-4.4.7.org/gcc/doc/c-tree.texi gcc-4.4.7/gcc/doc/c-tree.texi
|
||||
--- gcc-4.4.7.org/gcc/doc/c-tree.texi 2009-02-20 16:20:38.000000000 +0100
|
||||
+++ gcc-4.4.7/gcc/doc/c-tree.texi 2013-09-08 17:53:21.055167463 +0200
|
||||
@@ -2338,13 +2338,13 @@
|
||||
not matter. The type of the operands and that of the result are
|
||||
always of @code{BOOLEAN_TYPE} or @code{INTEGER_TYPE}.
|
||||
|
||||
-@itemx POINTER_PLUS_EXPR
|
||||
+@item POINTER_PLUS_EXPR
|
||||
This node represents pointer arithmetic. The first operand is always
|
||||
a pointer/reference type. The second operand is always an unsigned
|
||||
integer type compatible with sizetype. This is the only binary
|
||||
arithmetic operand that can operate on pointer types.
|
||||
|
||||
-@itemx PLUS_EXPR
|
||||
+@item PLUS_EXPR
|
||||
@itemx MINUS_EXPR
|
||||
@itemx MULT_EXPR
|
||||
These nodes represent various binary arithmetic operations.
|
||||
diff -Naur gcc-4.4.7.org/gcc/doc/invoke.texi gcc-4.4.7/gcc/doc/invoke.texi
|
||||
--- gcc-4.4.7.org/gcc/doc/invoke.texi 2011-03-23 23:02:12.000000000 +0100
|
||||
+++ gcc-4.4.7/gcc/doc/invoke.texi 2013-09-08 17:10:49.503066254 +0200
|
||||
@@ -4645,11 +4645,11 @@
|
||||
@option{-fdump-rtl-ce3} enable dumping after the three
|
||||
if conversion passes.
|
||||
|
||||
-@itemx -fdump-rtl-cprop_hardreg
|
||||
+@item -fdump-rtl-cprop_hardreg
|
||||
@opindex fdump-rtl-cprop_hardreg
|
||||
Dump after hard register copy propagation.
|
||||
|
||||
-@itemx -fdump-rtl-csa
|
||||
+@item -fdump-rtl-csa
|
||||
@opindex fdump-rtl-csa
|
||||
Dump after combining stack adjustments.
|
||||
|
||||
@@ -4660,11 +4660,11 @@
|
||||
@option{-fdump-rtl-cse1} and @option{-fdump-rtl-cse2} enable dumping after
|
||||
the two common sub-expression elimination passes.
|
||||
|
||||
-@itemx -fdump-rtl-dce
|
||||
+@item -fdump-rtl-dce
|
||||
@opindex fdump-rtl-dce
|
||||
Dump after the standalone dead code elimination passes.
|
||||
|
||||
-@itemx -fdump-rtl-dbr
|
||||
+@item -fdump-rtl-dbr
|
||||
@opindex fdump-rtl-dbr
|
||||
Dump after delayed branch scheduling.
|
||||
|
||||
@@ -4709,7 +4709,7 @@
|
||||
@opindex fdump-rtl-initvals
|
||||
Dump after the computation of the initial value sets.
|
||||
|
||||
-@itemx -fdump-rtl-into_cfglayout
|
||||
+@item -fdump-rtl-into_cfglayout
|
||||
@opindex fdump-rtl-into_cfglayout
|
||||
Dump after converting to cfglayout mode.
|
||||
|
||||
@@ -4739,7 +4739,7 @@
|
||||
@opindex fdump-rtl-rnreg
|
||||
Dump after register renumbering.
|
||||
|
||||
-@itemx -fdump-rtl-outof_cfglayout
|
||||
+@item -fdump-rtl-outof_cfglayout
|
||||
@opindex fdump-rtl-outof_cfglayout
|
||||
Dump after converting from cfglayout mode.
|
||||
|
||||
@@ -4751,7 +4751,7 @@
|
||||
@opindex fdump-rtl-postreload
|
||||
Dump after post-reload optimizations.
|
||||
|
||||
-@itemx -fdump-rtl-pro_and_epilogue
|
||||
+@item -fdump-rtl-pro_and_epilogue
|
||||
@opindex fdump-rtl-pro_and_epilogue
|
||||
Dump after generating the function pro and epilogues.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +0,0 @@
|
||||
--- libgomp/configure.tgt.jj 2008-01-10 20:53:48.000000000 +0100
|
||||
+++ libgomp/configure.tgt 2008-03-27 12:44:51.000000000 +0100
|
||||
@@ -67,7 +67,7 @@ if test $enable_linux_futex = yes; then
|
||||
;;
|
||||
*)
|
||||
if test -z "$with_arch"; then
|
||||
- XCFLAGS="${XCFLAGS} -march=i486 -mtune=${target_cpu}"
|
||||
+ XCFLAGS="${XCFLAGS} -march=i486 -mtune=generic"
|
||||
fi
|
||||
esac
|
||||
;;
|
||||
@@ -1,27 +0,0 @@
|
||||
libtool sucks.
|
||||
--- ltmain.sh.jj 2007-12-07 14:53:21.000000000 +0100
|
||||
+++ ltmain.sh 2008-09-05 21:51:48.000000000 +0200
|
||||
@@ -5394,6 +5394,7 @@ EOF
|
||||
rpath="$finalize_rpath"
|
||||
test "$mode" != relink && rpath="$compile_rpath$rpath"
|
||||
for libdir in $rpath; do
|
||||
+ case "$libdir" in /usr/lib|/usr/lib64|/usr/lib/../lib|/usr/lib/../lib64) continue;; esac
|
||||
if test -n "$hardcode_libdir_flag_spec"; then
|
||||
if test -n "$hardcode_libdir_separator"; then
|
||||
if test -z "$hardcode_libdirs"; then
|
||||
@@ -6071,6 +6072,7 @@ EOF
|
||||
rpath=
|
||||
hardcode_libdirs=
|
||||
for libdir in $compile_rpath $finalize_rpath; do
|
||||
+ case "$libdir" in /usr/lib|/usr/lib64|/usr/lib/../lib|/usr/lib/../lib64) continue;; esac
|
||||
if test -n "$hardcode_libdir_flag_spec"; then
|
||||
if test -n "$hardcode_libdir_separator"; then
|
||||
if test -z "$hardcode_libdirs"; then
|
||||
@@ -6120,6 +6122,7 @@ EOF
|
||||
rpath=
|
||||
hardcode_libdirs=
|
||||
for libdir in $finalize_rpath; do
|
||||
+ case "$libdir" in /usr/lib|/usr/lib64|/usr/lib/../lib|/usr/lib/../lib64) continue;; esac
|
||||
if test -n "$hardcode_libdir_flag_spec"; then
|
||||
if test -n "$hardcode_libdir_separator"; then
|
||||
if test -z "$hardcode_libdirs"; then
|
||||
@@ -1,50 +0,0 @@
|
||||
2010-02-08 Roland McGrath <roland@redhat.com>
|
||||
|
||||
* config/rs6000/sysv4.h (LINK_EH_SPEC): Pass --no-add-needed to the
|
||||
linker.
|
||||
* config/gnu-user.h (LINK_EH_SPEC): Likewise.
|
||||
* config/alpha/elf.h (LINK_EH_SPEC): Likewise.
|
||||
* config/ia64/linux.h (LINK_EH_SPEC): Likewise.
|
||||
|
||||
--- gcc/config/alpha/elf.h.jj 2011-01-03 12:52:31.118056764 +0100
|
||||
+++ gcc/config/alpha/elf.h 2011-01-04 18:14:10.931874160 +0100
|
||||
@@ -165,5 +165,5 @@ extern int alpha_this_gpdisp_sequence_nu
|
||||
I imagine that other systems will catch up. In the meantime, it
|
||||
doesn't harm to make sure that the data exists to be used later. */
|
||||
#if defined(HAVE_LD_EH_FRAME_HDR)
|
||||
-#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
|
||||
+#define LINK_EH_SPEC "--no-add-needed %{!static:--eh-frame-hdr} "
|
||||
#endif
|
||||
--- gcc/config/ia64/linux.h.jj 2011-01-03 13:02:11.462994522 +0100
|
||||
+++ gcc/config/ia64/linux.h 2011-01-04 18:14:10.931874160 +0100
|
||||
@@ -77,7 +77,7 @@ do { \
|
||||
Signalize that because we have fde-glibc, we don't need all C shared libs
|
||||
linked against -lgcc_s. */
|
||||
#undef LINK_EH_SPEC
|
||||
-#define LINK_EH_SPEC ""
|
||||
+#define LINK_EH_SPEC "--no-add-needed "
|
||||
|
||||
/* Put all *tf routines in libgcc. */
|
||||
#undef LIBGCC2_HAS_TF_MODE
|
||||
--- gcc/config/gnu-user.h.jj 2011-01-03 12:53:03.739057299 +0100
|
||||
+++ gcc/config/gnu-user.h 2011-01-04 18:14:10.932814884 +0100
|
||||
@@ -82,7 +82,7 @@ see the files COPYING3 and COPYING.RUNTI
|
||||
#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC
|
||||
|
||||
#if defined(HAVE_LD_EH_FRAME_HDR)
|
||||
-#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
|
||||
+#define LINK_EH_SPEC "--no-add-needed %{!static:--eh-frame-hdr} "
|
||||
#endif
|
||||
|
||||
#undef LINK_GCC_C_SEQUENCE_SPEC
|
||||
--- gcc/config/rs6000/sysv4.h.jj 2011-01-03 13:02:18.255994215 +0100
|
||||
+++ gcc/config/rs6000/sysv4.h 2011-01-04 18:14:10.933888871 +0100
|
||||
@@ -820,7 +820,7 @@ extern int fixuplabelno;
|
||||
-dynamic-linker " GNU_USER_DYNAMIC_LINKER "}}"
|
||||
|
||||
#if defined(HAVE_LD_EH_FRAME_HDR)
|
||||
-# define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
|
||||
+# define LINK_EH_SPEC "--no-add-needed %{!static:--eh-frame-hdr} "
|
||||
#endif
|
||||
|
||||
#define CPP_OS_LINUX_SPEC "-D__unix__ -D__gnu_linux__ -D__linux__ \
|
||||
@@ -1,106 +0,0 @@
|
||||
2009-03-18 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR debug/38757
|
||||
* langhooks.h (struct lang_hooks): Add source_language langhook.
|
||||
* langhooks-def.h (LANG_HOOKS_SOURCE_LANGUAGE): Define to NULL.
|
||||
(LANG_HOOKS_INITIALIZER): Add LANG_HOOKS_SOURCE_LANGUAGE.
|
||||
* dwarf2out.c (add_prototyped_attribute): Add DW_AT_prototype
|
||||
also for DW_LANG_{C,C99,ObjC}.
|
||||
(gen_compile_unit_die): Use lang_hooks.source_language () to
|
||||
determine if DW_LANG_C99 or DW_LANG_C89 should be returned.
|
||||
c/
|
||||
* c-lang.c (c_source_language): New function.
|
||||
(LANG_HOOKS_SOURCE_LANGUAGE): Define.
|
||||
|
||||
--- gcc/langhooks.h.jj 2011-01-03 12:53:05.125745450 +0100
|
||||
+++ gcc/langhooks.h 2011-01-04 17:59:43.166744926 +0100
|
||||
@@ -467,6 +467,10 @@ struct lang_hooks
|
||||
gimplification. */
|
||||
bool deep_unsharing;
|
||||
|
||||
+ /* Return year of the source language standard version if the FE supports
|
||||
+ multiple versions of the standard. */
|
||||
+ int (*source_language) (void);
|
||||
+
|
||||
/* Whenever you add entries here, make sure you adjust langhooks-def.h
|
||||
and langhooks.c accordingly. */
|
||||
};
|
||||
--- gcc/langhooks-def.h.jj 2011-01-03 12:53:05.000000000 +0100
|
||||
+++ gcc/langhooks-def.h 2011-01-04 18:00:44.858851030 +0100
|
||||
@@ -118,6 +118,7 @@ extern void lhd_omp_firstprivatize_type_
|
||||
#define LANG_HOOKS_BLOCK_MAY_FALLTHRU hook_bool_const_tree_true
|
||||
#define LANG_HOOKS_EH_USE_CXA_END_CLEANUP false
|
||||
#define LANG_HOOKS_DEEP_UNSHARING false
|
||||
+#define LANG_HOOKS_SOURCE_LANGUAGE NULL
|
||||
|
||||
/* Attribute hooks. */
|
||||
#define LANG_HOOKS_ATTRIBUTE_TABLE NULL
|
||||
@@ -303,7 +304,8 @@ extern void lhd_end_section (void);
|
||||
LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS, \
|
||||
LANG_HOOKS_BLOCK_MAY_FALLTHRU, \
|
||||
LANG_HOOKS_EH_USE_CXA_END_CLEANUP, \
|
||||
- LANG_HOOKS_DEEP_UNSHARING \
|
||||
+ LANG_HOOKS_DEEP_UNSHARING, \
|
||||
+ LANG_HOOKS_SOURCE_LANGUAGE \
|
||||
}
|
||||
|
||||
#endif /* GCC_LANG_HOOKS_DEF_H */
|
||||
--- gcc/c/c-lang.c.jj 2011-01-03 12:53:05.376056936 +0100
|
||||
+++ gcc/c/c-lang.c 2011-01-04 17:59:43.167743798 +0100
|
||||
@@ -36,6 +36,12 @@ along with GCC; see the file COPYING3.
|
||||
|
||||
enum c_language_kind c_language = clk_c;
|
||||
|
||||
+static int
|
||||
+c_source_language (void)
|
||||
+{
|
||||
+ return flag_isoc99 ? 1999 : 1989;
|
||||
+}
|
||||
+
|
||||
/* Lang hooks common to C and ObjC are declared in c-objc-common.h;
|
||||
consequently, there should be very few hooks below. */
|
||||
|
||||
@@ -45,6 +51,8 @@ enum c_language_kind c_language = clk_c;
|
||||
#define LANG_HOOKS_INIT c_objc_common_init
|
||||
#undef LANG_HOOKS_INIT_TS
|
||||
#define LANG_HOOKS_INIT_TS c_common_init_ts
|
||||
+#undef LANG_HOOKS_SOURCE_LANGUAGE
|
||||
+#define LANG_HOOKS_SOURCE_LANGUAGE c_source_language
|
||||
|
||||
/* Each front end provides its own lang hook initializer. */
|
||||
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
|
||||
--- gcc/dwarf2out.c.jj 2011-01-03 12:53:05.102056475 +0100
|
||||
+++ gcc/dwarf2out.c 2011-01-04 18:03:14.534151763 +0100
|
||||
@@ -16109,9 +16109,18 @@ add_bit_size_attribute (dw_die_ref die,
|
||||
static inline void
|
||||
add_prototyped_attribute (dw_die_ref die, tree func_type)
|
||||
{
|
||||
- if (get_AT_unsigned (comp_unit_die (), DW_AT_language) == DW_LANG_C89
|
||||
- && prototype_p (func_type))
|
||||
- add_AT_flag (die, DW_AT_prototyped, 1);
|
||||
+ switch (get_AT_unsigned (comp_unit_die (), DW_AT_language))
|
||||
+ {
|
||||
+ case DW_LANG_C:
|
||||
+ case DW_LANG_C89:
|
||||
+ case DW_LANG_C99:
|
||||
+ case DW_LANG_ObjC:
|
||||
+ if (prototype_p (func_type))
|
||||
+ add_AT_flag (die, DW_AT_prototyped, 1);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Add an 'abstract_origin' attribute below a given DIE. The DIE is found
|
||||
@@ -18915,6 +18924,10 @@ gen_compile_unit_die (const char *filena
|
||||
if (strcmp (language_string, "GNU Go") == 0)
|
||||
language = DW_LANG_Go;
|
||||
}
|
||||
+ else if (strcmp (language_string, "GNU C") == 0
|
||||
+ && lang_hooks.source_language
|
||||
+ && lang_hooks.source_language () >= 1999)
|
||||
+ language = DW_LANG_C99;
|
||||
}
|
||||
/* Use a degraded Fortran setting in strict DWARF2 so is_fortran works. */
|
||||
else if (strcmp (language_string, "GNU Fortran") == 0)
|
||||
@@ -1,17 +0,0 @@
|
||||
2014-12-17 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR sanitizer/64336
|
||||
* tsan.c (instrument_expr): Ignore TREE_READONLY bit
|
||||
on MEM_REFs.
|
||||
|
||||
--- gcc/tsan.c.jj 2014-12-17 10:53:30.000000000 +0100
|
||||
+++ gcc/tsan.c 2014-12-17 11:55:12.793058159 +0100
|
||||
@@ -138,7 +138,7 @@ instrument_expr (gimple_stmt_iterator gs
|
||||
return false;
|
||||
}
|
||||
|
||||
- if (TREE_READONLY (base)
|
||||
+ if ((TREE_READONLY (base) && TREE_CODE (base) != MEM_REF)
|
||||
|| (TREE_CODE (base) == VAR_DECL
|
||||
&& DECL_HARD_REGISTER (base)))
|
||||
return false;
|
||||
@@ -1,35 +0,0 @@
|
||||
From 28d708c44bc47b56f6551ff285f78edcf61c208a Mon Sep 17 00:00:00 2001
|
||||
From: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
|
||||
Date: Thu, 31 Oct 2013 12:37:50 +1000
|
||||
Subject: Accept make versions 4.0 and greater
|
||||
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index f382138..5e61abd 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -4761,7 +4761,7 @@ $as_echo_n "checking version of $MAKE... " >&6; }
|
||||
ac_prog_version=`$MAKE --version 2>&1 | sed -n 's/^.*GNU Make[^0-9]*\([0-9][0-9.]*\).*$/\1/p'`
|
||||
case $ac_prog_version in
|
||||
'') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
|
||||
- 3.79* | 3.[89]*)
|
||||
+ 3.79* | 3.[89]* | [4-9].* | [1-9][0-9]*)
|
||||
ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
|
||||
*) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
|
||||
|
||||
diff --git a/configure.in b/configure.in
|
||||
index 49b70fd..6da8efd 100644
|
||||
--- a/configure.in
|
||||
+++ b/configure.in
|
||||
@@ -984,7 +984,7 @@ AC_CHECK_PROG_VER(CC, ${ac_tool_prefix}gcc ${ac_tool_prefix}cc, -v,
|
||||
critic_missing="$critic_missing gcc")
|
||||
AC_CHECK_PROG_VER(MAKE, gnumake gmake make, --version,
|
||||
[GNU Make[^0-9]*\([0-9][0-9.]*\)],
|
||||
- [3.79* | 3.[89]*], critic_missing="$critic_missing make")
|
||||
+ [3.79* | 3.[89]* | [4-9].* | [1-9][0-9]*], critic_missing="$critic_missing make")
|
||||
|
||||
AC_CHECK_PROG_VER(MSGFMT, gnumsgfmt gmsgfmt msgfmt, --version,
|
||||
[GNU gettext.* \([0-9]*\.[0-9.]*\)],
|
||||
--
|
||||
cgit v0.10.2
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
--- glibc-2.12.2/ports/sysdeps/unix/sysv/linux/arm/sigrestorer.S 2011-09-08 22:22:41.000000000 +0400
|
||||
+++ glibc-2.12.2/ports/sysdeps/unix/sysv/linux/arm/sigrestorer.S 2011-09-08 21:44:49.000000000 +0400
|
||||
@@ -18,16 +18,20 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
+ .text
|
||||
+
|
||||
/* If no SA_RESTORER function was specified by the application we use
|
||||
one of these. This avoids the need for the kernel to synthesise a return
|
||||
instruction on the stack, which would involve expensive cache flushes. */
|
||||
|
||||
ENTRY(__default_sa_restorer)
|
||||
swi SYS_ify(sigreturn)
|
||||
+PSEUDO_END (__default_sa_restorer)
|
||||
|
||||
#ifdef __NR_rt_sigreturn
|
||||
|
||||
ENTRY(__default_rt_sa_restorer)
|
||||
swi SYS_ify(rt_sigreturn)
|
||||
+PSEUDO_END (__default_rt_sa_restorer)
|
||||
|
||||
#endif
|
||||
11
src/patches/glibc-localedef-no-archive.patch
Normal file
11
src/patches/glibc-localedef-no-archive.patch
Normal file
@@ -0,0 +1,11 @@
|
||||
diff -Nrup a/localedata/Makefile b/localedata/Makefile
|
||||
--- a/localedata/Makefile 2012-06-05 07:42:49.000000000 -0600
|
||||
+++ b/localedata/Makefile 2012-06-07 12:15:21.776318827 -0600
|
||||
@@ -211,6 +211,7 @@ $(INSTALL-SUPPORTED-LOCALES): install-lo
|
||||
echo -n '...'; \
|
||||
input=`echo $$locale | sed 's/\([^.]*\)[^@]*\(.*\)/\1\2/'`; \
|
||||
$(LOCALEDEF) --alias-file=../intl/locale.alias \
|
||||
+ --no-archive \
|
||||
-i locales/$$input -c -f charmaps/$$charset \
|
||||
$(addprefix --prefix=,$(install_root)) $$locale \
|
||||
&& echo ' done'; \
|
||||
@@ -1,150 +0,0 @@
|
||||
From 4a531bb0b3b582cb693de9f76d2d97d970f9a5d5 Mon Sep 17 00:00:00 2001
|
||||
From: H.J. Lu <hongjiu.lu@intel.com>
|
||||
Date: Fri, 24 Dec 2010 20:14:37 -0500
|
||||
Subject: [PATCH] Remove `.ctors' and `.dtors' output sections
|
||||
|
||||
---
|
||||
config.h.in | 3 +
|
||||
configure.in | 2 +
|
||||
elf/sofini.c | 2 +
|
||||
elf/soinit.c | 2 +
|
||||
sysdeps/i386/init-first.c | 2 +
|
||||
sysdeps/mach/hurd/i386/init-first.c | 2 +-
|
||||
sysdeps/mach/hurd/powerpc/init-first.c | 2 +-
|
||||
sysdeps/sh/init-first.c | 2 +
|
||||
sysdeps/unix/sysv/linux/init-first.c | 2 +-
|
||||
9 files changed, 16 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/config.h.in b/config.h.in
|
||||
index 18bf01a..9e797eb 100644
|
||||
--- a/config.h.in
|
||||
+++ b/config.h.in
|
||||
@@ -201,6 +201,9 @@
|
||||
/* Define if multi-arch DSOs should be generated. */
|
||||
#undef USE_MULTIARCH
|
||||
|
||||
+/* Define if `.ctors' and `.dtors' sections shouldn't be used. */
|
||||
+#undef NO_CTORS_DTORS_SECTIONS
|
||||
+
|
||||
/*
|
||||
*/
|
||||
|
||||
diff --git a/configure.in b/configure.in
|
||||
index d8cd5f1..ad25b9b 100644
|
||||
--- a/configure.in
|
||||
+++ b/configure.in
|
||||
@@ -1497,6 +1497,8 @@ EOF
|
||||
rm -f conftest*])
|
||||
if test $libc_cv_initfini_array != yes; then
|
||||
AC_MSG_ERROR([Need linker with .init_array/.fini_array support.])
|
||||
+ elif AC_TRY_COMMAND([${CC-cc} -Wl,--verbose 2>&1|grep SORT_BY_INIT_PRIORITY 1>&AS_MESSAGE_LOG_FD]); then
|
||||
+ AC_DEFINE(NO_CTORS_DTORS_SECTIONS)
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK(for libunwind-support in compiler,
|
||||
diff --git a/elf/sofini.c b/elf/sofini.c
|
||||
index 5e06f0c..13e74b7 100644
|
||||
--- a/elf/sofini.c
|
||||
+++ b/elf/sofini.c
|
||||
@@ -1,12 +1,14 @@
|
||||
/* Finalizer module for ELF shared C library. This provides terminating
|
||||
null pointer words in the `.ctors' and `.dtors' sections. */
|
||||
|
||||
+#ifndef NO_CTORS_DTORS_SECTIONS
|
||||
static void (*const __CTOR_END__[1]) (void)
|
||||
__attribute__ ((used, section (".ctors")))
|
||||
= { 0 };
|
||||
static void (*const __DTOR_END__[1]) (void)
|
||||
__attribute__ ((used, section (".dtors")))
|
||||
= { 0 };
|
||||
+#endif
|
||||
|
||||
/* Terminate the frame unwind info section with a 4byte 0 as a sentinel;
|
||||
this would be the 'length' field in a real FDE. */
|
||||
diff --git a/elf/soinit.c b/elf/soinit.c
|
||||
index 6fecbb5..1db676a 100644
|
||||
--- a/elf/soinit.c
|
||||
+++ b/elf/soinit.c
|
||||
@@ -3,6 +3,7 @@
|
||||
the `.ctors' and `.dtors' sections so the lists are terminated, and
|
||||
calling those lists of functions. */
|
||||
|
||||
+#ifndef NO_CTORS_DTORS_SECTIONS
|
||||
#include <libc-internal.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -40,3 +41,4 @@ __libc_fini (void)
|
||||
|
||||
void (*_fini_ptr) (void) __attribute__ ((section (".fini_array")))
|
||||
= &__libc_fini;
|
||||
+#endif
|
||||
diff --git a/sysdeps/i386/init-first.c b/sysdeps/i386/init-first.c
|
||||
index c6355a8..2af042f 100644
|
||||
--- a/sysdeps/i386/init-first.c
|
||||
+++ b/sysdeps/i386/init-first.c
|
||||
@@ -59,7 +59,9 @@ _init (int argc, ...)
|
||||
{
|
||||
init (&argc);
|
||||
|
||||
+#ifndef NO_CTORS_DTORS_SECTIONS
|
||||
__libc_global_ctors ();
|
||||
+#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/sysdeps/mach/hurd/i386/init-first.c b/sysdeps/mach/hurd/i386/init-first.c
|
||||
index f9a7a58..60823bd 100644
|
||||
--- a/sysdeps/mach/hurd/i386/init-first.c
|
||||
+++ b/sysdeps/mach/hurd/i386/init-first.c
|
||||
@@ -92,7 +92,7 @@ posixland_init (int argc, char **argv, char **envp)
|
||||
__getopt_clean_environment (envp);
|
||||
#endif
|
||||
|
||||
-#ifdef SHARED
|
||||
+#if defined SHARED && !defined NO_CTORS_DTORS_SECTIONS
|
||||
__libc_global_ctors ();
|
||||
#endif
|
||||
}
|
||||
diff --git a/sysdeps/mach/hurd/powerpc/init-first.c b/sysdeps/mach/hurd/powerpc/init-first.c
|
||||
index 20fa1d4..21b5054 100644
|
||||
--- a/sysdeps/mach/hurd/powerpc/init-first.c
|
||||
+++ b/sysdeps/mach/hurd/powerpc/init-first.c
|
||||
@@ -82,7 +82,7 @@ posixland_init (int argc, char **argv, char **envp)
|
||||
__getopt_clean_environment (__environ);
|
||||
#endif
|
||||
|
||||
-#ifdef SHARED
|
||||
+#if defined SHARED && !defined NO_CTORS_DTORS_SECTIONS
|
||||
__libc_global_ctors ();
|
||||
#endif
|
||||
}
|
||||
diff --git a/sysdeps/sh/init-first.c b/sysdeps/sh/init-first.c
|
||||
index d816625..1f3a821 100644
|
||||
--- a/sysdeps/sh/init-first.c
|
||||
+++ b/sysdeps/sh/init-first.c
|
||||
@@ -59,7 +59,9 @@ _init (int argc, ...)
|
||||
{
|
||||
init (&argc);
|
||||
|
||||
+#ifndef NO_CTORS_DTORS_SECTIONS
|
||||
__libc_global_ctors ();
|
||||
+#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/init-first.c b/sysdeps/unix/sysv/linux/init-first.c
|
||||
index 7b2333d..a60212f 100644
|
||||
--- a/sysdeps/unix/sysv/linux/init-first.c
|
||||
+++ b/sysdeps/unix/sysv/linux/init-first.c
|
||||
@@ -93,7 +93,7 @@ _init (int argc, char **argv, char **envp)
|
||||
__getopt_clean_environment (envp);
|
||||
#endif
|
||||
|
||||
-#ifdef SHARED
|
||||
+#if defined SHARED && !defined NO_CTORS_DTORS_SECTIONS
|
||||
__libc_global_ctors ();
|
||||
#endif
|
||||
}
|
||||
--
|
||||
1.7.3.4
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
From e057a1b5930ec538c2b8abbba700a436ef2c81d5 Mon Sep 17 00:00:00 2001
|
||||
From: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Wed, 21 Sep 2011 13:27:50 -0700
|
||||
Subject: [PATCH] Link libresolv.so with ld.so for __stack_chk_guard.
|
||||
|
||||
---
|
||||
resolv/Makefile | 8 +++++++-
|
||||
1 files changed, 7 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/resolv/Makefile b/resolv/Makefile
|
||||
index ec3788f..b4287de 100644
|
||||
--- a/resolv/Makefile
|
||||
+++ b/resolv/Makefile
|
||||
@@ -1,4 +1,5 @@
|
||||
-# Copyright (C) 1994-2001,2003,2004,2007,2008 Free Software Foundation, Inc.
|
||||
+# Copyright (C) 1994-2001,2003,2004,2007,2008,2011
|
||||
+# 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
|
||||
@@ -88,6 +89,11 @@ CFLAGS-res_hconf.c = -fexceptions
|
||||
# This ensures they will load libc.so for needed symbols if loaded by
|
||||
# a statically-linked program that hasn't already loaded it.
|
||||
$(objpfx)libresolv.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a
|
||||
+# Some hosts need '__stack_chk_guard', so pull in the definition from
|
||||
+# ld.so if required.
|
||||
+ifeq (yesyes,$(have-ssp)$(elf))
|
||||
+LDLIBS-resolv.so += $(as-needed) $(elfobjdir)/ld.so $(no-as-needed)
|
||||
+endif
|
||||
|
||||
# The DNS NSS modules needs the resolver.
|
||||
$(objpfx)libnss_dns.so: $(objpfx)libresolv.so $(common-objpfx)libc.so \
|
||||
--
|
||||
1.7.3.4
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
diff -Naur glibc-2.12-2-gc4ccff1.org/nptl/sysdeps/pthread/unwind-forcedunwind.c glibc-2.12-2-gc4ccff1/nptl/sysdeps/pthread/unwind-forcedunwind.c
|
||||
index db56428..495f4b7 100644
|
||||
--- glibc-2.12-2-gc4ccff1.org/nptl/sysdeps/pthread/unwind-forcedunwind.c
|
||||
+++ glibc-2.12-2-gc4ccff1/nptl/sysdeps/pthread/unwind-forcedunwind.c
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <unwind.h>
|
||||
#include <pthreadP.h>
|
||||
#include <sysdep.h>
|
||||
-#include <libgcc_s.h>
|
||||
+#include <gnu/lib-names.h>
|
||||
|
||||
static void *libgcc_s_handle;
|
||||
static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
|
||||
diff -Naur glibc-2.12-2-gc4ccff1.org/scripts/test-installation.pl glibc-2.12-2-gc4ccff1/scripts/test-installation.pl
|
||||
index 25a919b..3f409ab 100755
|
||||
--- glibc-2.12-2-gc4ccff1.org/scripts/test-installation.pl
|
||||
+++ glibc-2.12-2-gc4ccff1/scripts/test-installation.pl
|
||||
@@ -106,9 +106,10 @@ while (<SOVERSIONS>) {
|
||||
# - libnss1_* from glibc-compat add-on
|
||||
# - libthread_db since it contains unresolved references
|
||||
# - it's just a test NSS module
|
||||
+ # - We don't provide the libgcc so we don't test it
|
||||
if ($name ne "nss_ldap" && $name ne "db1"
|
||||
&& !($name =~/^nss1_/) && $name ne "thread_db"
|
||||
- && $name ne "nss_test1") {
|
||||
+ && $name ne "nss_test1" && $name ne "libgcc_s") {
|
||||
$link_libs .= " -l$name";
|
||||
$versions{$name} = $version;
|
||||
}
|
||||
diff -Naur glibc-2.12-2-gc4ccff1.org/shlib-versions glibc-2.12-2-gc4ccff1/shlib-versions
|
||||
index d3e8407..ac98e49 100644
|
||||
--- glibc-2.12-2-gc4ccff1.org/shlib-versions
|
||||
+++ glibc-2.12-2-gc4ccff1/shlib-versions
|
||||
@@ -138,3 +138,7 @@ sparc64.*-.*-.* libBrokenLocale=1 GLIBC_2.2
|
||||
|
||||
# The asynchronous name lookup library.
|
||||
.*-.*-.* libanl=1
|
||||
+
|
||||
+# This defines the libgcc soname version this glibc is to load for
|
||||
+# asynchronous cancellation to work correctly.
|
||||
+.*-.*-.* libgcc_s=1
|
||||
diff -Naur glibc-2.12-2-gc4ccff1.org/sysdeps/generic/framestate.c glibc-2.12-2-gc4ccff1/sysdeps/generic/framestate.c
|
||||
index 80375bb..edc3539 100644
|
||||
--- glibc-2.12-2-gc4ccff1.org/sysdeps/generic/framestate.c
|
||||
+++ glibc-2.12-2-gc4ccff1/sysdeps/generic/framestate.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* __frame_state_for unwinder helper function wrapper.
|
||||
- Copyright (C) 2001, 2003 Free Software Foundation, Inc.
|
||||
+ Copyright (C) 2001-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2001.
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#define __frame_state_for fallback_frame_state_for
|
||||
#include <unwind-dw2.c>
|
||||
#undef __frame_state_for
|
||||
-#include <libgcc_s.h>
|
||||
+#include <gnu/lib-names.h>
|
||||
|
||||
typedef struct frame_state * (*framesf)(void *pc, struct frame_state *);
|
||||
struct frame_state *__frame_state_for (void *pc,
|
||||
diff -Naur glibc-2.12-2-gc4ccff1.org/sysdeps/generic/libgcc_s.h glibc-2.12-2-gc4ccff1.org/sysdeps/generic/libgcc_s.h
|
||||
deleted file mode 100644
|
||||
index e74a103..0000000
|
||||
--- glibc-2.12-2-gc4ccff1.org/sysdeps/generic/libgcc_s.h
|
||||
+++ /dev/null
|
||||
@@ -1,2 +0,0 @@
|
||||
-/* Name of libgcc_s library provided by gcc. */
|
||||
-#define LIBGCC_S_SO "libgcc_s.so.1"
|
||||
diff -Naur glibc-2.12-2-gc4ccff1.org/sysdeps/gnu/unwind-resume.c glibc-2.12-2-gc4ccff1/sysdeps/gnu/unwind-resume.c
|
||||
index f8ff0c4..dab4370 100644
|
||||
--- glibc-2.12-2-gc4ccff1.org/sysdeps/gnu/unwind-resume.c
|
||||
+++ glibc-2.12-2-gc4ccff1/sysdeps/gnu/unwind-resume.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
+/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>.
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <unwind.h>
|
||||
#include <pthreadP.h>
|
||||
#include <sysdep.h>
|
||||
-#include <libgcc_s.h>
|
||||
+#include <gnu/lib-names.h>
|
||||
|
||||
static void *libgcc_s_handle;
|
||||
static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
|
||||
@@ -1,31 +0,0 @@
|
||||
From 9191c04a7e19fffbea0a08523e579cd8e55142df Mon Sep 17 00:00:00 2001
|
||||
From: Ulrich Drepper <drepper@gmail.com>
|
||||
Date: Sat, 23 Jul 2011 15:28:31 -0400
|
||||
Subject: [PATCH] Adjust test for correct installation
|
||||
|
||||
diff --git a/scripts/test-installation.pl b/scripts/test-installation.pl
|
||||
index 90cd9d7..25a919b 100755
|
||||
--- a/scripts/test-installation.pl
|
||||
+++ b/scripts/test-installation.pl
|
||||
@@ -1,5 +1,5 @@
|
||||
#! /usr/bin/perl -w
|
||||
-# Copyright (C) 1997, 1998, 1999, 2004 Free Software Foundation, Inc.
|
||||
+# Copyright (C) 1997, 1998, 1999, 2004, 2011 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
# Contributed by Andreas Jaeger <aj@arthur.rhein-neckar.de>, 1997.
|
||||
|
||||
@@ -105,8 +105,10 @@ while (<SOVERSIONS>) {
|
||||
# - libdb1 since it conflicts with libdb
|
||||
# - libnss1_* from glibc-compat add-on
|
||||
# - libthread_db since it contains unresolved references
|
||||
+ # - it's just a test NSS module
|
||||
if ($name ne "nss_ldap" && $name ne "db1"
|
||||
- && !($name =~/^nss1_/) && $name ne "thread_db") {
|
||||
+ && !($name =~/^nss1_/) && $name ne "thread_db"
|
||||
+ && $name ne "nss_test1") {
|
||||
$link_libs .= " -l$name";
|
||||
$versions{$name} = $version;
|
||||
}
|
||||
--
|
||||
1.7.3.4
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
Index: glibc-2.12-2-gc4ccff1/elf/Makefile
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/elf/Makefile
|
||||
+++ glibc-2.12-2-gc4ccff1/elf/Makefile
|
||||
@@ -129,6 +129,7 @@ include ../Makeconfig
|
||||
ifeq ($(unwind-find-fde),yes)
|
||||
routines += unwind-dw2-fde-glibc
|
||||
shared-only-routines += unwind-dw2-fde-glibc
|
||||
+CFLAGS-unwind-dw2-fde-glibc.c += -fno-strict-aliasing
|
||||
endif
|
||||
|
||||
before-compile = $(objpfx)trusted-dirs.h
|
||||
Index: glibc-2.12-2-gc4ccff1/inet/Makefile
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/inet/Makefile
|
||||
+++ glibc-2.12-2-gc4ccff1/inet/Makefile
|
||||
@@ -57,6 +57,8 @@ tests := htontest test_ifindex tst-ntoa
|
||||
|
||||
include ../Rules
|
||||
|
||||
+CFLAGS-tst-inet6_rth.c += -fno-strict-aliasing
|
||||
+
|
||||
ifeq ($(have-thread-library),yes)
|
||||
|
||||
CFLAGS-gethstbyad_r.c = -DUSE_NSCD=1 -fexceptions
|
||||
Index: glibc-2.12-2-gc4ccff1/nis/Makefile
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/nis/Makefile
|
||||
+++ glibc-2.12-2-gc4ccff1/nis/Makefile
|
||||
@@ -69,6 +69,8 @@ libnss_nisplus-inhibit-o = $(filter-out
|
||||
|
||||
include ../Rules
|
||||
|
||||
+CFLAGS-nis_findserv.c += -fno-strict-aliasing
|
||||
+CFLAGS-ypclnt.c += -fno-strict-aliasing
|
||||
|
||||
$(objpfx)libnss_compat.so: $(objpfx)libnsl.so$(libnsl.so-version)
|
||||
$(objpfx)libnss_nis.so: $(objpfx)libnsl.so$(libnsl.so-version) \
|
||||
Index: glibc-2.12-2-gc4ccff1/nss/Makefile
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/nss/Makefile
|
||||
+++ glibc-2.12-2-gc4ccff1/nss/Makefile
|
||||
@@ -74,6 +74,7 @@ endif
|
||||
|
||||
include ../Rules
|
||||
|
||||
+CFLAGS-files-hosts.c += -fno-strict-aliasing
|
||||
|
||||
ifeq (yes,$(build-static-nss))
|
||||
$(objpfx)getent: $(objpfx)libnss_files.a
|
||||
Index: glibc-2.12-2-gc4ccff1/resolv/Makefile
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/resolv/Makefile
|
||||
+++ glibc-2.12-2-gc4ccff1/resolv/Makefile
|
||||
@@ -77,6 +77,7 @@ CPPFLAGS += -Dgethostbyname=res_gethostb
|
||||
-Dgetnetbyaddr=res_getnetbyaddr
|
||||
|
||||
CFLAGS-res_hconf.c = -fexceptions
|
||||
+CFLAGS-res_send.c += -fno-strict-aliasing
|
||||
|
||||
# The BIND code elicits some harmless warnings.
|
||||
+cflags += -Wno-strict-prototypes -Wno-write-strings
|
||||
Index: glibc-2.12-2-gc4ccff1/sunrpc/Makefile
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/sunrpc/Makefile
|
||||
+++ glibc-2.12-2-gc4ccff1/sunrpc/Makefile
|
||||
@@ -129,6 +129,10 @@ CFLAGS-openchild.c = -fexceptions
|
||||
|
||||
CPPFLAGS += -D_RPC_THREAD_SAFE_
|
||||
|
||||
+CFLAGS-clnt_tcp.c += -fno-strict-aliasing
|
||||
+CFLAGS-clnt_udp.c += -fno-strict-aliasing
|
||||
+CFLAGS-clnt_unix.c += -fno-strict-aliasing
|
||||
+
|
||||
include ../Rules
|
||||
|
||||
$(objpfx)rpcgen: $(addprefix $(objpfx),$(rpcgen-objs)) \
|
||||
Index: glibc-2.12-2-gc4ccff1/sysdeps/powerpc/powerpc64/elf/Makefile
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/powerpc/powerpc64/elf/Makefile
|
||||
+++ glibc-2.12-2-gc4ccff1/sysdeps/powerpc/powerpc64/elf/Makefile
|
||||
@@ -9,3 +9,5 @@ CFLAGS-rtld-mempcpy.os = $(no-special-re
|
||||
CFLAGS-rtld-memmove.os = $(no-special-regs)
|
||||
CFLAGS-rtld-memchr.os = $(no-special-regs)
|
||||
CFLAGS-rtld-strnlen.os = $(no-special-regs)
|
||||
+
|
||||
+CFLAGS-gmon-start.c += -fno-strict-aliasing
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,36 +0,0 @@
|
||||
2010-05-05 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
[BZ #11571]
|
||||
* sysdeps/unix/sysv/linux/getlogin_r.c (__getlogin_r_loginuid): Handle
|
||||
too small buffers according to the standard.
|
||||
|
||||
Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/getlogin_r.c
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/unix/sysv/linux/getlogin_r.c
|
||||
+++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/getlogin_r.c
|
||||
@@ -81,13 +81,22 @@ __getlogin_r_loginuid (name, namesize)
|
||||
if (tpwd == NULL)
|
||||
goto fail;
|
||||
|
||||
- strncpy (name, pwd.pw_name, namesize - 1);
|
||||
- name[namesize - 1] = '\0';
|
||||
+ int result = 0;
|
||||
+ size_t needed = strlen (pwd.pw_name) + 1;
|
||||
+ if (needed > namesize)
|
||||
+ {
|
||||
+ __set_errno (ERANGE);
|
||||
+ result = ERANGE;
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
+ memcpy (name, pwd.pw_name, needed);
|
||||
+
|
||||
+ out:
|
||||
if (use_malloc)
|
||||
free (buf);
|
||||
|
||||
- return 0;
|
||||
+ return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
2010-05-04 Andreas Schwab <schwab@redhat.com>
|
||||
|
||||
* SUPPORTED (SUPPORTED-LOCALES): Fix name of tt_RU.UTF-8@iqtelif
|
||||
locale.
|
||||
|
||||
Index: glibc-2.12-2-gc4ccff1/localedata/SUPPORTED
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/localedata/SUPPORTED
|
||||
+++ glibc-2.12-2-gc4ccff1/localedata/SUPPORTED
|
||||
@@ -392,7 +392,7 @@ tr_TR.UTF-8/UTF-8 \
|
||||
tr_TR/ISO-8859-9 \
|
||||
ts_ZA/UTF-8 \
|
||||
tt_RU.UTF-8/UTF-8 \
|
||||
-tt_RU@iqtelif.UTF-8/UTF-8 \
|
||||
+tt_RU.UTF-8@iqtelif/UTF-8 \
|
||||
ug_CN/UTF-8 \
|
||||
uk_UA.UTF-8/UTF-8 \
|
||||
uk_UA/KOI8-U \
|
||||
@@ -1,34 +0,0 @@
|
||||
From: https://sourceware.org/bugzilla/show_bug.cgi?id=12841
|
||||
|
||||
--- libc/rt/bits/mqueue2.h 2009-05-16 19:23:37.000000000 +0200
|
||||
+++ libc/rt/bits/mqueue2.h 2011-06-04 19:05:38.322333773 +0200
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Checking macros for mq functions.
|
||||
- Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
+ Copyright (C) 2007, 2011 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
|
||||
@@ -25,16 +25,18 @@
|
||||
parameter. */
|
||||
extern mqd_t mq_open (__const char *__name, int __oflag, ...)
|
||||
__THROW __nonnull ((1));
|
||||
-extern mqd_t __mq_open_2 (__const char *__name, int __oflag) __nonnull ((1));
|
||||
-extern mqd_t __REDIRECT (__mq_open_alias, (__const char *__name, int __oflag, ...),
|
||||
- mq_open) __nonnull ((1));
|
||||
+extern mqd_t __mq_open_2 (__const char *__name, int __oflag)
|
||||
+ __THROW __nonnull ((1));
|
||||
+extern mqd_t __REDIRECT_NTH (__mq_open_alias, (__const char *__name,
|
||||
+ int __oflag, ...), mq_open)
|
||||
+ __nonnull ((1));
|
||||
__errordecl (__mq_open_wrong_number_of_args,
|
||||
"mq_open can be called either with 2 or 4 arguments");
|
||||
__errordecl (__mq_open_missing_mode_and_attr,
|
||||
"mq_open with O_CREAT in second argument needs 4 arguments");
|
||||
|
||||
__extern_always_inline mqd_t
|
||||
-mq_open (__const char *__name, int __oflag, ...)
|
||||
+__NTH (mq_open (__const char *__name, int __oflag, ...))
|
||||
{
|
||||
if (__va_arg_pack_len () != 0 && __va_arg_pack_len () != 2)
|
||||
__mq_open_wrong_number_of_args ();
|
||||
@@ -1,182 +0,0 @@
|
||||
2010-05-21 Andreas Schwab <schwab@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Add recvmmsg
|
||||
and internal_recvmmsg.
|
||||
* sysdeps/unix/sysv/linux/recvmmsg.c: New file.
|
||||
* sysdeps/unix/sysv/linux/internal_recvmmsg.S: New file.
|
||||
* sysdeps/unix/sysv/linux/socketcall.h (SOCKOP_recvmmsg): Define.
|
||||
* sysdeps/unix/sysv/linux/syscalls.list (recvmmsg): Remove.
|
||||
|
||||
Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/Makefile
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/unix/sysv/linux/Makefile
|
||||
+++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/Makefile
|
||||
@@ -12,7 +12,7 @@ CFLAGS-malloc.c += -DMORECORE_CLEARS=2
|
||||
endif
|
||||
|
||||
ifeq ($(subdir),socket)
|
||||
-sysdep_routines += internal_accept4
|
||||
+sysdep_routines += internal_accept4 recvmmsg internal_recvmmsg
|
||||
endif
|
||||
|
||||
ifeq ($(subdir),misc)
|
||||
Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/internal_recvmmsg.S
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/internal_recvmmsg.S
|
||||
@@ -0,0 +1,14 @@
|
||||
+#include <kernel-features.h>
|
||||
+#include <sys/syscall.h>
|
||||
+#if !defined __NR_recvmmsg && defined __NR_socketcall
|
||||
+# define socket recvmmsg
|
||||
+# ifdef __ASSUME_RECVMMSG
|
||||
+# define __socket recvmmsg
|
||||
+# else
|
||||
+# define __socket __internal_recvmmsg
|
||||
+# endif
|
||||
+# define NARGS 5
|
||||
+# define NEED_CANCELLATION
|
||||
+# define NO_WEAK_ALIAS
|
||||
+# include <socket.S>
|
||||
+#endif
|
||||
Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/kernel-features.h
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/unix/sysv/linux/kernel-features.h
|
||||
+++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/kernel-features.h
|
||||
@@ -547,3 +547,8 @@
|
||||
#if __LINUX_KERNEL_VERSION >= 0x020620
|
||||
# define __ASSUME_F_GETOWN_EX 1
|
||||
#endif
|
||||
+
|
||||
+/* Support for the recvmmsg syscall was added in 2.6.33. */
|
||||
+#if __LINUX_KERNEL_VERSION >= 0x020621
|
||||
+# define __ASSUME_RECVMMSG 1
|
||||
+#endif
|
||||
Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/recvmmsg.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/recvmmsg.c
|
||||
@@ -0,0 +1,100 @@
|
||||
+/* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+ Contributed by Andreas Schwab <schwab@redhat.com>, 2010.
|
||||
+
|
||||
+ 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, write to the Free
|
||||
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
+ 02111-1307 USA. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <sys/socket.h>
|
||||
+
|
||||
+#include <sysdep-cancel.h>
|
||||
+#include <sys/syscall.h>
|
||||
+#include <kernel-features.h>
|
||||
+
|
||||
+
|
||||
+#ifdef __NR_recvmmsg
|
||||
+int
|
||||
+recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
|
||||
+ const struct timespec *tmo)
|
||||
+{
|
||||
+ if (SINGLE_THREAD_P)
|
||||
+ return INLINE_SYSCALL (recvmmsg, 5, fd, vmessages, vlen, flags, tmo);
|
||||
+
|
||||
+ int oldtype = LIBC_CANCEL_ASYNC ();
|
||||
+
|
||||
+ int result = INLINE_SYSCALL (recvmmsg, 5, fd, vmessages, vlen, flags, tmo);
|
||||
+
|
||||
+ LIBC_CANCEL_RESET (oldtype);
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
+#elif defined __NR_socketcall
|
||||
+# ifndef __ASSUME_RECVMMSG
|
||||
+extern int __internal_recvmmsg (int fd, struct mmsghdr *vmessages,
|
||||
+ unsigned int vlen, int flags,
|
||||
+ const struct timespec *tmo)
|
||||
+ attribute_hidden;
|
||||
+
|
||||
+static int have_recvmmsg;
|
||||
+
|
||||
+int
|
||||
+recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
|
||||
+ const struct timespec *tmo)
|
||||
+{
|
||||
+ if (__builtin_expect (have_recvmmsg >= 0, 1))
|
||||
+ {
|
||||
+ int ret = __internal_recvmmsg (fd, vmessages, vlen, flags, tmo);
|
||||
+ /* The kernel returns -EINVAL for unknown socket operations.
|
||||
+ We need to convert that error to an ENOSYS error. */
|
||||
+ if (__builtin_expect (ret < 0, 0)
|
||||
+ && have_recvmmsg == 0
|
||||
+ && errno == EINVAL)
|
||||
+ {
|
||||
+ /* Try another call, this time with an invalid file
|
||||
+ descriptor and all other parameters cleared. This call
|
||||
+ will not cause any harm and it will return
|
||||
+ immediately. */
|
||||
+ ret = __internal_recvmmsg (-1, 0, 0, 0, 0);
|
||||
+ if (errno == EINVAL)
|
||||
+ {
|
||||
+ have_recvmmsg = -1;
|
||||
+ __set_errno (ENOSYS);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ have_recvmmsg = 1;
|
||||
+ __set_errno (EINVAL);
|
||||
+ }
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return ret;
|
||||
+ }
|
||||
+ __set_errno (ENOSYS);
|
||||
+ return -1;
|
||||
+}
|
||||
+# else
|
||||
+/* When __ASSUME_RECVMMSG recvmmsg is defined in internal_recvmmsg.S. */
|
||||
+# endif
|
||||
+#else
|
||||
+int
|
||||
+recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
|
||||
+ const struct timespec *tmo)
|
||||
+{
|
||||
+ __set_errno (ENOSYS);
|
||||
+ return -1;
|
||||
+}
|
||||
+stub_warning (recvmmsg)
|
||||
+#endif
|
||||
Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/socketcall.h
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/unix/sysv/linux/socketcall.h
|
||||
+++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/socketcall.h
|
||||
@@ -44,5 +44,6 @@
|
||||
#define SOCKOP_sendmsg 16
|
||||
#define SOCKOP_recvmsg 17
|
||||
#define SOCKOP_accept4 18
|
||||
+#define SOCKOP_recvmmsg 19
|
||||
|
||||
#endif /* sys/socketcall.h */
|
||||
Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/syscalls.list
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/unix/sysv/linux/syscalls.list
|
||||
+++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/syscalls.list
|
||||
@@ -53,7 +53,6 @@ prctl EXTRA prctl i:iiiii __prctl prc
|
||||
putpmsg - putpmsg i:ippii putpmsg
|
||||
query_module EXTRA query_module i:sipip query_module
|
||||
quotactl EXTRA quotactl i:isip quotactl
|
||||
-recvmmsg EXTRA recvmmsg Ci:ipiip recvmmsg
|
||||
remap_file_pages - remap_file_pages i:piiii __remap_file_pages remap_file_pages
|
||||
sched_getp - sched_getparam i:ip __sched_getparam sched_getparam
|
||||
sched_gets - sched_getscheduler i:i __sched_getscheduler sched_getscheduler
|
||||
@@ -1,45 +0,0 @@
|
||||
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);
|
||||
@@ -1,39 +0,0 @@
|
||||
commit 48b67d71ec677d1b3168e52a68b644784cead604
|
||||
Author: Andreas Schwab <schwab@redhat.com>
|
||||
Date: Wed Sep 14 12:12:25 2011 +0200
|
||||
|
||||
Also relocate in dependency order when doing symbol dependency testing
|
||||
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index 764140d..324d979 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -2027,24 +2027,21 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
{
|
||||
/* We have to do symbol dependency testing. */
|
||||
struct relocate_args args;
|
||||
- struct link_map *l;
|
||||
+ unsigned int i;
|
||||
|
||||
args.reloc_mode = GLRO(dl_lazy) ? RTLD_LAZY : 0;
|
||||
|
||||
- l = main_map;
|
||||
- while (l->l_next != NULL)
|
||||
- l = l->l_next;
|
||||
- do
|
||||
+ i = main_map->l_searchlist.r_nlist;
|
||||
+ while (i-- > 0)
|
||||
{
|
||||
+ struct link_map *l = main_map->l_initfini[i];
|
||||
if (l != &GL(dl_rtld_map) && ! l->l_faked)
|
||||
{
|
||||
args.l = l;
|
||||
_dl_receive_error (print_unresolved, relocate_doit,
|
||||
&args);
|
||||
}
|
||||
- l = l->l_prev;
|
||||
}
|
||||
- while (l != NULL);
|
||||
|
||||
if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
|
||||
&& rtld_multiple_ref)
|
||||
@@ -1,20 +0,0 @@
|
||||
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;
|
||||
@@ -1,64 +0,0 @@
|
||||
diff -pruN glibc-2.17-c758a686/nptl/Makefile glibc-2.17-c758a686.new/nptl/Makefile
|
||||
--- glibc-2.17-c758a686/nptl/Makefile 2013-07-31 11:51:24.882747234 +0530
|
||||
+++ glibc-2.17-c758a686.new/nptl/Makefile 2013-07-31 11:58:55.964731526 +0530
|
||||
@@ -276,10 +276,7 @@ gen-as-const-headers = pthread-errnos.sy
|
||||
LDFLAGS-tst-cond24 = -lrt
|
||||
LDFLAGS-tst-cond25 = -lrt
|
||||
|
||||
-# The size is 1MB + 4KB. The extra 4KB has been added to prevent allocatestack
|
||||
-# from resizing the input size to avoid the 64K aliasing conflict on Intel
|
||||
-# processors.
|
||||
-DEFAULT_STACKSIZE=1052672
|
||||
+DEFAULT_STACKSIZE=1048576
|
||||
CFLAGS-tst-default-attr.c = -DDEFAULT_STACKSIZE=$(DEFAULT_STACKSIZE)
|
||||
tst-default-attr-ENV = GLIBC_PTHREAD_STACKSIZE=$(DEFAULT_STACKSIZE)
|
||||
|
||||
diff -pruN glibc-2.17-c758a686/nptl/tst-default-attr.c glibc-2.17-c758a686.new/nptl/tst-default-attr.c
|
||||
--- glibc-2.17-c758a686/nptl/tst-default-attr.c 2013-07-31 11:51:24.885747234 +0530
|
||||
+++ glibc-2.17-c758a686.new/nptl/tst-default-attr.c 2013-07-31 12:18:10.016691337 +0530
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
/* DEFAULT_STACKSIZE macro is defined in the Makefile. */
|
||||
static size_t stacksize = DEFAULT_STACKSIZE;
|
||||
+long int pagesize;
|
||||
|
||||
static int
|
||||
verify_stacksize_result (pthread_attr_t *attr)
|
||||
@@ -46,12 +47,20 @@ verify_stacksize_result (pthread_attr_t
|
||||
|
||||
RETURN_IF_FAIL (pthread_attr_getstacksize, attr, &stack);
|
||||
|
||||
- if (stacksize != stack)
|
||||
+ /* pthread_create perturbs the stack size by a page if it aligns to 64K to
|
||||
+ avoid the 64K aliasing conflict. We cannot simply add 4K to the size in
|
||||
+ the Makefile because it breaks the test on powerpc since the page size
|
||||
+ there is 64K, resulting in a resize in __pthread_initialize_minimal.
|
||||
+ Hence, our check is to ensure that the stack size is not more than a page
|
||||
+ more than the requested size. */
|
||||
+ if (stack < stacksize || stack > stacksize + pagesize)
|
||||
{
|
||||
printf ("failed to set default stacksize (%zu, %zu)\n", stacksize, stack);
|
||||
return 1;
|
||||
}
|
||||
|
||||
+ printf ("Requested %zu and got %zu\n", stacksize, stack);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -101,6 +110,15 @@ run_threads (void)
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
+ pthread_attr_t attr;
|
||||
+
|
||||
+ pagesize = sysconf (_SC_PAGESIZE);
|
||||
+ if (pagesize < 0)
|
||||
+ {
|
||||
+ printf ("sysconf failed: %s\n", strerror (errno));
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
RETURN_IF_FAIL (run_threads);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,287 +0,0 @@
|
||||
commit 0699f766b10c86912b75f35bef697106b70c1cf6
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
Date: Thu Apr 10 18:31:53 2014 -0400
|
||||
|
||||
nscd: Make SELinux checks dynamic.
|
||||
|
||||
The SELinux team has indicated to me that glibc's SELinux checks
|
||||
in nscd are not being carried out as they would expect the API
|
||||
to be used today. They would like to move away from static header
|
||||
defines for class and permissions and instead use dynamic checks
|
||||
at runtime that provide an answer which is dependent on the runtime
|
||||
status of SELinux i.e. more dynamic.
|
||||
|
||||
The following patch is a minimal change that moves us forward in
|
||||
this direction.
|
||||
|
||||
It does the following:
|
||||
|
||||
* Stop checking for SELinux headers that define NSCD__SHMEMHOST.
|
||||
Check only for the presence or absence of the library.
|
||||
|
||||
* Don't encode the specific SELinux permission constants into a
|
||||
table at build time, and instead use the symbolic name for the
|
||||
permission as expected.
|
||||
|
||||
* Lookup the "What do we do if we don't know this permission?"
|
||||
policy and use that if we find SELinux's policy is older than
|
||||
the glibc policy e.g. we make a request for a permission that
|
||||
SELinux doesn't know about.
|
||||
|
||||
* Lastly, translate the class and permission and then make
|
||||
the permission check. This is done every time we lookup
|
||||
a permission, and this is the expected way to use the API.
|
||||
SELinux will optimize this for us, and we expect the network
|
||||
latencies to hide these extra library calls.
|
||||
|
||||
Tested on x86, x86-64, and via Fedora Rawhide since November 2013.
|
||||
|
||||
See:
|
||||
https://sourceware.org/ml/libc-alpha/2014-04/msg00179.html
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index abefcdb..8b0b222 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -7774,64 +7774,10 @@ else
|
||||
have_selinux=no
|
||||
fi
|
||||
|
||||
- # See if we have the SELinux header with the NSCD permissions in it.
|
||||
- if test x$have_selinux = xyes ; then
|
||||
- { $as_echo "$as_me:$LINENO: checking for NSCD Flask permissions in selinux/av_permissions.h" >&5
|
||||
-$as_echo_n "checking for NSCD Flask permissions in selinux/av_permissions.h... " >&6; }
|
||||
- cat >conftest.$ac_ext <<_ACEOF
|
||||
-/* confdefs.h. */
|
||||
-_ACEOF
|
||||
-cat confdefs.h >>conftest.$ac_ext
|
||||
-cat >>conftest.$ac_ext <<_ACEOF
|
||||
-/* end confdefs.h. */
|
||||
-#include <selinux/av_permissions.h>
|
||||
-int
|
||||
-main ()
|
||||
-{
|
||||
-#ifdef NSCD__SHMEMHOST
|
||||
- return 0;
|
||||
- #else
|
||||
- #error NSCD__SHMEMHOST not defined
|
||||
- #endif
|
||||
- ;
|
||||
- return 0;
|
||||
-}
|
||||
-_ACEOF
|
||||
-rm -f conftest.$ac_objext
|
||||
-if { (ac_try="$ac_compile"
|
||||
-case "(($ac_try" in
|
||||
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
- *) ac_try_echo=$ac_try;;
|
||||
-esac
|
||||
-eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
|
||||
-$as_echo "$ac_try_echo") >&5
|
||||
- (eval "$ac_compile") 2>conftest.er1
|
||||
- ac_status=$?
|
||||
- grep -v '^ *+' conftest.er1 >conftest.err
|
||||
- rm -f conftest.er1
|
||||
- cat conftest.err >&5
|
||||
- $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
- (exit $ac_status); } && {
|
||||
- test -z "$ac_c_werror_flag" ||
|
||||
- test ! -s conftest.err
|
||||
- } && test -s conftest.$ac_objext; then
|
||||
- have_selinux=yes
|
||||
-else
|
||||
- $as_echo "$as_me: failed program was:" >&5
|
||||
-sed 's/^/| /' conftest.$ac_ext >&5
|
||||
-
|
||||
- have_selinux=no
|
||||
-fi
|
||||
-
|
||||
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
- { $as_echo "$as_me:$LINENO: result: $have_selinux" >&5
|
||||
-$as_echo "$have_selinux" >&6; }
|
||||
- fi
|
||||
-
|
||||
if test x$with_selinux = xyes ; then
|
||||
if test x$have_selinux = xno ; then
|
||||
- { { $as_echo "$as_me:$LINENO: error: SELinux explicitly required, but sufficiently recent SELinux library not found" >&5
|
||||
-$as_echo "$as_me: error: SELinux explicitly required, but sufficiently recent SELinux library not found" >&2;}
|
||||
+ { { $as_echo "$as_me:$LINENO: error: SELinux explicitly required, but SELinux library not found" >&5
|
||||
+$as_echo "$as_me: error: SELinux explicitly required, but SELinux library not found" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
fi
|
||||
diff --git a/configure.in b/configure.in
|
||||
index 6291872..97a9591 100644
|
||||
--- a/configure.in
|
||||
+++ b/configure.in
|
||||
@@ -1945,22 +1945,9 @@ else
|
||||
# See if we have the SELinux library
|
||||
AC_CHECK_LIB(selinux, is_selinux_enabled,
|
||||
have_selinux=yes, have_selinux=no)
|
||||
- # See if we have the SELinux header with the NSCD permissions in it.
|
||||
- if test x$have_selinux = xyes ; then
|
||||
- AC_MSG_CHECKING([for NSCD Flask permissions in selinux/av_permissions.h])
|
||||
- AC_TRY_COMPILE([#include <selinux/av_permissions.h>],
|
||||
- [#ifdef NSCD__SHMEMHOST
|
||||
- return 0;
|
||||
- #else
|
||||
- #error NSCD__SHMEMHOST not defined
|
||||
- #endif],
|
||||
- have_selinux=yes, have_selinux=no)
|
||||
- AC_MSG_RESULT($have_selinux)
|
||||
- fi
|
||||
-
|
||||
if test x$with_selinux = xyes ; then
|
||||
if test x$have_selinux = xno ; then
|
||||
- AC_MSG_ERROR([SELinux explicitly required, but sufficiently recent SELinux library not found])
|
||||
+ AC_MSG_ERROR([SELinux explicitly required, but SELinux library not found])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
diff --git a/nscd/selinux.c b/nscd/selinux.c
|
||||
index 46b0ea9..9a8a5a8 100644
|
||||
--- a/nscd/selinux.c
|
||||
+++ b/nscd/selinux.c
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/prctl.h>
|
||||
-#include <selinux/av_permissions.h>
|
||||
#include <selinux/avc.h>
|
||||
#include <selinux/flask.h>
|
||||
#include <selinux/selinux.h>
|
||||
@@ -44,35 +43,31 @@
|
||||
/* Global variable to tell if the kernel has SELinux support. */
|
||||
int selinux_enabled;
|
||||
|
||||
-/* Define mappings of access vector permissions to request types. */
|
||||
-static const access_vector_t perms[LASTREQ] =
|
||||
+/* Define mappings of request type to AVC permission name. */
|
||||
+static const char *perms[LASTREQ] =
|
||||
{
|
||||
- [GETPWBYNAME] = NSCD__GETPWD,
|
||||
- [GETPWBYUID] = NSCD__GETPWD,
|
||||
- [GETGRBYNAME] = NSCD__GETGRP,
|
||||
- [GETGRBYGID] = NSCD__GETGRP,
|
||||
- [GETHOSTBYNAME] = NSCD__GETHOST,
|
||||
- [GETHOSTBYNAMEv6] = NSCD__GETHOST,
|
||||
- [GETHOSTBYADDR] = NSCD__GETHOST,
|
||||
- [GETHOSTBYADDRv6] = NSCD__GETHOST,
|
||||
- [GETSTAT] = NSCD__GETSTAT,
|
||||
- [SHUTDOWN] = NSCD__ADMIN,
|
||||
- [INVALIDATE] = NSCD__ADMIN,
|
||||
- [GETFDPW] = NSCD__SHMEMPWD,
|
||||
- [GETFDGR] = NSCD__SHMEMGRP,
|
||||
- [GETFDHST] = NSCD__SHMEMHOST,
|
||||
- [GETAI] = NSCD__GETHOST,
|
||||
- [INITGROUPS] = NSCD__GETGRP,
|
||||
-#ifdef NSCD__GETSERV
|
||||
- [GETSERVBYNAME] = NSCD__GETSERV,
|
||||
- [GETSERVBYPORT] = NSCD__GETSERV,
|
||||
- [GETFDSERV] = NSCD__SHMEMSERV,
|
||||
-#endif
|
||||
-#ifdef NSCD__GETNETGRP
|
||||
- [GETNETGRENT] = NSCD__GETNETGRP,
|
||||
- [INNETGR] = NSCD__GETNETGRP,
|
||||
- [GETFDNETGR] = NSCD__SHMEMNETGRP,
|
||||
-#endif
|
||||
+ [GETPWBYNAME] = "getpwd",
|
||||
+ [GETPWBYUID] = "getpwd",
|
||||
+ [GETGRBYNAME] = "getgrp",
|
||||
+ [GETGRBYGID] = "getgrp",
|
||||
+ [GETHOSTBYNAME] = "gethost",
|
||||
+ [GETHOSTBYNAMEv6] = "gethost",
|
||||
+ [GETHOSTBYADDR] = "gethost",
|
||||
+ [GETHOSTBYADDRv6] = "gethost",
|
||||
+ [SHUTDOWN] = "admin",
|
||||
+ [GETSTAT] = "getstat",
|
||||
+ [INVALIDATE] = "admin",
|
||||
+ [GETFDPW] = "shmempwd",
|
||||
+ [GETFDGR] = "shmemgrp",
|
||||
+ [GETFDHST] = "shmemhost",
|
||||
+ [GETAI] = "gethost",
|
||||
+ [INITGROUPS] = "getgrp",
|
||||
+ [GETSERVBYNAME] = "getserv",
|
||||
+ [GETSERVBYPORT] = "getserv",
|
||||
+ [GETFDSERV] = "shmemserv",
|
||||
+ [GETNETGRENT] = "getnetgrp",
|
||||
+ [INNETGR] = "getnetgrp",
|
||||
+ [GETFDNETGR] = "shmemnetgrp",
|
||||
};
|
||||
|
||||
/* Store an entry ref to speed AVC decisions. */
|
||||
@@ -344,7 +339,16 @@ nscd_avc_init (void)
|
||||
|
||||
|
||||
/* Check the permission from the caller (via getpeercon) to nscd.
|
||||
- Returns 0 if access is allowed, 1 if denied, and -1 on error. */
|
||||
+ Returns 0 if access is allowed, 1 if denied, and -1 on error.
|
||||
+
|
||||
+ The SELinux policy, enablement, and permission bits are all dynamic and the
|
||||
+ caching done by glibc is not entirely correct. This nscd support should be
|
||||
+ rewritten to use selinux_check_permission. A rewrite is risky though and
|
||||
+ requires some refactoring. Currently we use symbolic mappings instead of
|
||||
+ compile time constants (which SELinux upstream says are going away), and we
|
||||
+ use security_deny_unknown to determine what to do if selinux-policy* doesn't
|
||||
+ have a definition for the the permission or object class we are looking
|
||||
+ up. */
|
||||
int
|
||||
nscd_request_avc_has_perm (int fd, request_type req)
|
||||
{
|
||||
@@ -354,6 +358,33 @@ nscd_request_avc_has_perm (int fd, request_type req)
|
||||
security_id_t ssid = NULL;
|
||||
security_id_t tsid = NULL;
|
||||
int rc = -1;
|
||||
+ security_class_t sc_nscd;
|
||||
+ access_vector_t perm;
|
||||
+ int avc_deny_unknown;
|
||||
+
|
||||
+ /* Check if SELinux denys or allows unknown object classes
|
||||
+ and permissions. It is 0 if they are allowed, 1 if they
|
||||
+ are not allowed and -1 on error. */
|
||||
+ if ((avc_deny_unknown = security_deny_unknown ()) == -1)
|
||||
+ dbg_log (_("Error querying policy for undefined object classes "
|
||||
+ "or permissions."));
|
||||
+
|
||||
+ /* Get the security class for nscd. If this fails we will likely be
|
||||
+ unable to do anything unless avc_deny_unknown is 0. */
|
||||
+ sc_nscd = string_to_security_class ("nscd");
|
||||
+ if (perm == 0 && avc_deny_unknown == 1)
|
||||
+ dbg_log (_("Error getting security class for nscd."));
|
||||
+
|
||||
+ /* Convert permission to AVC bits. */
|
||||
+ perm = string_to_av_perm (sc_nscd, perms[req]);
|
||||
+ if (perm == 0 && avc_deny_unknown == 1)
|
||||
+ dbg_log (_("Error translating permission name "
|
||||
+ "\"%s\" to access vector bit."), perms[req]);
|
||||
+
|
||||
+ /* If the nscd security class was not found or perms were not
|
||||
+ found and AVC does not deny unknown values then allow it. */
|
||||
+ if ((sc_nscd == 0 || perm == 0) && avc_deny_unknown == 0)
|
||||
+ return 0;
|
||||
|
||||
if (getpeercon (fd, &scon) < 0)
|
||||
{
|
||||
@@ -372,15 +403,13 @@ nscd_request_avc_has_perm (int fd, request_type req)
|
||||
goto out;
|
||||
}
|
||||
|
||||
-#ifndef NSCD__GETSERV
|
||||
- if (perms[req] == 0)
|
||||
- {
|
||||
- dbg_log (_("compile-time support for database policy missing"));
|
||||
- goto out;
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- rc = avc_has_perm (ssid, tsid, SECCLASS_NSCD, perms[req], &aeref, NULL) < 0;
|
||||
+ /* The SELinux API for avc_has_perm conflates access denied and error into
|
||||
+ the return code -1, while nscd_request_avs_has_perm has distinct error
|
||||
+ (-1) and denied (1) return codes. We map the avc_has_perm access denied or
|
||||
+ error into an access denied at the nscd interface level (we do accurately
|
||||
+ report error for the getpeercon, getcon, and avc_context_to_sid interfaces
|
||||
+ used above). */
|
||||
+ rc = avc_has_perm (ssid, tsid, sc_nscd, perm, &aeref, NULL) < 0;
|
||||
|
||||
out:
|
||||
if (scon)
|
||||
@@ -1,58 +0,0 @@
|
||||
commit 362b47fe09ca9a928d444c7e2f7992f7f61bfc3e
|
||||
Author: Maxim Kuvyrkov <maxim@kugelworks.com>
|
||||
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;
|
||||
@@ -1,28 +0,0 @@
|
||||
commit 4d653a59ffeae0f46f76a40230e2cfa9587b7e7e
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Fri May 30 22:43:52 2014 +0530
|
||||
|
||||
Add mmap usage in malloc_info output
|
||||
|
||||
The current malloc_info xml output only has information about
|
||||
allocations on the heap. Display information about number of mappings
|
||||
and total mmapped size to this to complete the picture.
|
||||
|
||||
diff -pruN a/malloc/malloc.c b/malloc/malloc.c
|
||||
--- a/malloc/malloc.c 2014-06-02 07:35:22.573256155 +0530
|
||||
+++ b/malloc/malloc.c 2014-06-02 07:34:58.856257177 +0530
|
||||
@@ -6553,12 +6553,14 @@ malloc_info (int options, FILE *fp)
|
||||
fprintf (fp,
|
||||
"<total type=\"fast\" count=\"%zu\" size=\"%zu\"/>\n"
|
||||
"<total type=\"rest\" count=\"%zu\" size=\"%zu\"/>\n"
|
||||
+ "<total type=\"mmap\" count=\"%d\" size=\"%zu\"/>\n"
|
||||
"<system type=\"current\" size=\"%zu\"/>\n"
|
||||
"<system type=\"max\" size=\"%zu\"/>\n"
|
||||
"<aspace type=\"total\" size=\"%zu\"/>\n"
|
||||
"<aspace type=\"mprotect\" size=\"%zu\"/>\n"
|
||||
"</malloc>\n",
|
||||
total_nfastblocks, total_fastavail, total_nblocks, total_avail,
|
||||
+ mp_.n_mmaps, mp_.mmapped_mem,
|
||||
total_system, total_max_system,
|
||||
total_aspace, total_aspace_mprotect);
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
From a5675717e35a02a3eba7e13701c6f9c0d7222e13 Mon Sep 17 00:00:00 2001
|
||||
From: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
|
||||
Date: Fri, 7 Jun 2013 14:50:23 -0500
|
||||
Subject: [PATCH 2/2] PowerPC: gettimeofday optimization by using IFUNC
|
||||
|
||||
Backport of ef26eece6331a1f6d959818e37c438cc7ce68e53 from master.
|
||||
---
|
||||
sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h | 10 ++++
|
||||
sysdeps/unix/sysv/linux/powerpc/gettimeofday.c | 49 +++++++++++++++-------
|
||||
2 files changed, 44 insertions(+), 15 deletions(-)
|
||||
|
||||
commit 76a9b9986141b1a7d9fd290c349d27fcee780c7a
|
||||
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
|
||||
Date: Thu Nov 7 05:34:22 2013 -0600
|
||||
|
||||
PowerPC: Fix vDSO missing ODP entries
|
||||
|
||||
This patch fixes the vDSO symbol used directed in IFUNC resolver where
|
||||
they do not have an associated ODP entry leading to undefined behavior
|
||||
in some cases. It adds an artificial OPD static entry to such cases
|
||||
and set its TOC to non 0 to avoid triggering lazy resolutions.
|
||||
|
||||
commit d98720e07f67fbeec00f9e1347840404240d3c48
|
||||
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
|
||||
Date: Mon Jan 20 12:29:51 2014 -0600
|
||||
|
||||
PowerPC: Fix gettimeofday ifunc selection
|
||||
|
||||
The IFUNC selector for gettimeofday runs before _libc_vdso_platform_setup where
|
||||
__vdso_gettimeofday is set. The selector then sets __gettimeofday (the internal
|
||||
version used within GLIBC) to use the system call version instead of the vDSO one.
|
||||
This patch changes the check if vDSO is available to get its value directly
|
||||
instead of rely on __vdso_gettimeofday.
|
||||
|
||||
This patch changes it by getting the vDSO value directly.
|
||||
|
||||
It fixes BZ#16431.
|
||||
|
||||
diff -pruN a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
|
||||
--- a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h 2014-05-20 14:46:51.026871920 +0530
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h 2014-05-20 14:44:39.294877321 +0530
|
||||
@@ -33,6 +33,36 @@ extern void *__vdso_get_tbfreq;
|
||||
|
||||
extern void *__vdso_getcpu;
|
||||
|
||||
+#if defined(__PPC64__) || defined(__powerpc64__)
|
||||
+/* The correct solution is for _dl_vdso_vsym to return the address of the OPD
|
||||
+ for the kernel VDSO function. That address would then be stored in the
|
||||
+ __vdso_* variables and returned as the result of the IFUNC resolver function.
|
||||
+ Yet, the kernel does not contain any OPD entries for the VDSO functions
|
||||
+ (incomplete implementation). However, PLT relocations for IFUNCs still expect
|
||||
+ the address of an OPD to be returned from the IFUNC resolver function (since
|
||||
+ PLT entries on PPC64 are just copies of OPDs). The solution for now is to
|
||||
+ create an artificial static OPD for each VDSO function returned by a resolver
|
||||
+ function. The TOC value is set to a non-zero value to avoid triggering lazy
|
||||
+ symbol resolution via .glink0/.plt0 for a zero TOC (requires thread-safe PLT
|
||||
+ sequences) when the dynamic linker isn't prepared for it e.g. RTLD_NOW. None
|
||||
+ of the kernel VDSO routines use the TOC or AUX values so any non-zero value
|
||||
+ will work. Note that function pointer comparisons will not use this artificial
|
||||
+ static OPD since those are resolved via ADDR64 relocations and will point at
|
||||
+ the non-IFUNC default OPD for the symbol. Lastly, because the IFUNC relocations
|
||||
+ are processed immediately at startup the resolver functions and this code need
|
||||
+ not be thread-safe, but if the caller writes to a PLT slot it must do so in a
|
||||
+ thread-safe manner with all the required barriers. */
|
||||
+#define VDSO_IFUNC_RET(value) \
|
||||
+ ({ \
|
||||
+ static Elf64_FuncDesc vdso_opd = { .fd_toc = ~0x0 }; \
|
||||
+ vdso_opd.fd_func = (Elf64_Addr)value; \
|
||||
+ &vdso_opd; \
|
||||
+ })
|
||||
+
|
||||
+#else
|
||||
+#define VDSO_IFUNC_RET(value) ((void *) (value))
|
||||
+#endif
|
||||
+
|
||||
#endif
|
||||
|
||||
#endif /* _LIBC_VDSO_H */
|
||||
diff -pruN a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
|
||||
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c 2010-05-04 16:57:23.000000000 +0530
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c 2014-05-20 14:44:39.298877321 +0530
|
||||
@@ -16,27 +16,51 @@
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
-#include <sysdep.h>
|
||||
-#include <bp-checks.h>
|
||||
-#include <stddef.h>
|
||||
#include <sys/time.h>
|
||||
-#include <time.h>
|
||||
-#include <hp-timing.h>
|
||||
|
||||
-#undef __gettimeofday
|
||||
-#include <bits/libc-vdso.h>
|
||||
+#ifdef SHARED
|
||||
|
||||
-/* Get the current time of day and timezone information,
|
||||
- putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
|
||||
- Returns 0 on success, -1 on errors. */
|
||||
-
|
||||
-int
|
||||
-__gettimeofday (tv, tz)
|
||||
- struct timeval *tv;
|
||||
- struct timezone *tz;
|
||||
+# include <dl-vdso.h>
|
||||
+# include <bits/libc-vdso.h>
|
||||
+# include <dl-machine.h>
|
||||
+
|
||||
+void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
|
||||
+
|
||||
+static int
|
||||
+__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
|
||||
+{
|
||||
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
|
||||
+}
|
||||
+
|
||||
+void *
|
||||
+gettimeofday_ifunc (void)
|
||||
+{
|
||||
+ PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
|
||||
+
|
||||
+ /* If the vDSO is not available we fall back syscall. */
|
||||
+ void *vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
|
||||
+ return (vdso_gettimeofday ? VDSO_IFUNC_RET (vdso_gettimeofday)
|
||||
+ : (void*)__gettimeofday_syscall);
|
||||
+}
|
||||
+asm (".type __gettimeofday, %gnu_indirect_function");
|
||||
+
|
||||
+/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
|
||||
+ let us do it in C because it doesn't know we're defining __gettimeofday
|
||||
+ here in this file. */
|
||||
+asm (".globl __GI___gettimeofday\n"
|
||||
+ "__GI___gettimeofday = __gettimeofday");
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+# include <sysdep.h>
|
||||
+# include <errno.h>
|
||||
+
|
||||
+int
|
||||
+__gettimeofday (struct timeval *tv, struct timezone *tz)
|
||||
{
|
||||
- return INLINE_VSYSCALL (gettimeofday, 2, CHECK_1 (tv), CHECK_1 (tz));
|
||||
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
|
||||
}
|
||||
|
||||
+#endif
|
||||
INTDEF (__gettimeofday)
|
||||
weak_alias (__gettimeofday, gettimeofday)
|
||||
@@ -1,166 +0,0 @@
|
||||
commit 028478fa40d85a73b19638dbe3f83b1acebf370c
|
||||
Author: Ulrich Drepper <drepper@gmail.com>
|
||||
Date: Thu Mar 10 12:51:33 2011 -0500
|
||||
|
||||
Fix copy relocations handling of unique objects.
|
||||
|
||||
2011-03-06 Ulrich Drepper <drepper@gmail.com>
|
||||
|
||||
and a part of:
|
||||
|
||||
commit 33f85a3fb9fe432e0ebf6a3481bc2d5e29cb605f
|
||||
Author: Ulrich Drepper <drepper@gmail.com>
|
||||
Date: Thu Mar 10 03:18:21 2011 -0500
|
||||
|
||||
Don't run tests checking xecutable stack when SELinux is enforcing.
|
||||
|
||||
since the latter incorrectly had a bit of the former changes.
|
||||
|
||||
Additionally, the test case needs -lstdc++ to build.
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index c427679..56cb1b1 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -201,7 +201,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||
unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \
|
||||
tst-audit1 tst-audit2 tst-audit9 \
|
||||
tst-stackguard1 tst-addr1 tst-thrlock \
|
||||
- tst-unique1 tst-unique2
|
||||
+ tst-unique1 tst-unique2 tst-unique3
|
||||
# reldep9
|
||||
test-srcs = tst-pathopt
|
||||
tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog
|
||||
@@ -255,6 +255,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||
order2mod1 order2mod2 order2mod3 order2mod4 \
|
||||
tst-unique1mod1 tst-unique1mod2 \
|
||||
tst-unique2mod1 tst-unique2mod2 \
|
||||
+ tst-unique3lib tst-unique3lib2 \
|
||||
tst-auditmod9a tst-auditmod9b
|
||||
ifeq (yes,$(have-initfini-array))
|
||||
modules-names += tst-array2dep tst-array5dep
|
||||
@@ -1178,6 +1179,11 @@ $(objpfx)tst-unique1.out: $(objpfx)tst-unique1mod1.so \
|
||||
$(objpfx)tst-unique2: $(libdl) $(objpfx)tst-unique2mod1.so
|
||||
$(objpfx)tst-unique2.out: $(objpfx)tst-unique2mod2.so
|
||||
|
||||
+LDLIBS-tst-unique3lib.so = -lstdc++
|
||||
+LDLIBS-tst-unique3lib2.so = -lstdc++
|
||||
+$(objpfx)tst-unique3: $(libdl) $(objpfx)tst-unique3lib.so
|
||||
+$(objpfx)tst-unique3.out: $(objpfx)tst-unique3lib2.so
|
||||
+
|
||||
ifeq (yes,$(config-cflags-avx))
|
||||
CFLAGS-tst-audit4.c += -mavx
|
||||
CFLAGS-tst-auditmod4a.c += -mavx
|
||||
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
|
||||
index 78c8669..874a4bb 100644
|
||||
--- a/elf/dl-lookup.c
|
||||
+++ b/elf/dl-lookup.c
|
||||
@@ -364,8 +363,19 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
|
||||
if (entries[idx].hashval == new_hash
|
||||
&& strcmp (entries[idx].name, undef_name) == 0)
|
||||
{
|
||||
- result->s = entries[idx].sym;
|
||||
- result->m = (struct link_map *) entries[idx].map;
|
||||
+ if ((type_class & ELF_RTYPE_CLASS_COPY) != 0)
|
||||
+ {
|
||||
+ /* We possibly have to initialize the central
|
||||
+ copy from the copy addressed through the
|
||||
+ relocation. */
|
||||
+ result->s = sym;
|
||||
+ result->m = (struct link_map *) map;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ result->s = entries[idx].sym;
|
||||
+ result->m = (struct link_map *) entries[idx].map;
|
||||
+ }
|
||||
__rtld_lock_unlock_recursive (tab->lock);
|
||||
return 1;
|
||||
}
|
||||
diff --git a/elf/tst-unique3.cc b/elf/tst-unique3.cc
|
||||
new file mode 100644
|
||||
index 0000000..b2c9593
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-unique3.cc
|
||||
@@ -0,0 +1,23 @@
|
||||
+#include "tst-unique3.h"
|
||||
+#include <cstdio>
|
||||
+#include "../dlfcn/dlfcn.h"
|
||||
+
|
||||
+int t = S<char>::i;
|
||||
+
|
||||
+int
|
||||
+main (void)
|
||||
+{
|
||||
+ std::printf ("%d %d\n", S<char>::i, t);
|
||||
+ int result = S<char>::i++ != 1 || t != 1;
|
||||
+ result |= in_lib ();
|
||||
+ void *d = dlopen ("$ORIGIN/tst-unique3lib2.so", RTLD_LAZY);
|
||||
+ int (*fp) ();
|
||||
+ if (d == NULL || (fp = (int(*)()) dlsym (d, "in_lib2")) == NULL)
|
||||
+ {
|
||||
+ std::printf ("failed to get symbol in_lib2\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ result |= fp ();
|
||||
+ dlclose (d);
|
||||
+ return result;
|
||||
+}
|
||||
diff --git a/elf/tst-unique3.h b/elf/tst-unique3.h
|
||||
new file mode 100644
|
||||
index 0000000..716d236
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-unique3.h
|
||||
@@ -0,0 +1,8 @@
|
||||
+// BZ 12510
|
||||
+template<typename T>
|
||||
+struct S
|
||||
+{
|
||||
+ static int i;
|
||||
+};
|
||||
+
|
||||
+extern int in_lib (void);
|
||||
diff --git a/elf/tst-unique3lib.cc b/elf/tst-unique3lib.cc
|
||||
new file mode 100644
|
||||
index 0000000..fa8e85a
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-unique3lib.cc
|
||||
@@ -0,0 +1,11 @@
|
||||
+#include <cstdio>
|
||||
+#include "tst-unique3.h"
|
||||
+template<typename T> int S<T>::i = 1;
|
||||
+static int i = S<char>::i;
|
||||
+
|
||||
+int
|
||||
+in_lib (void)
|
||||
+{
|
||||
+ std::printf ("in_lib: %d %d\n", S<char>::i, i);
|
||||
+ return S<char>::i++ != 2 || i != 1;
|
||||
+}
|
||||
diff --git a/elf/tst-unique3lib2.cc b/elf/tst-unique3lib2.cc
|
||||
new file mode 100644
|
||||
index 0000000..17d817e
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-unique3lib2.cc
|
||||
@@ -0,0 +1,12 @@
|
||||
+#include <cstdio>
|
||||
+#include "tst-unique3.h"
|
||||
+
|
||||
+template<typename T> int S<T>::i;
|
||||
+
|
||||
+extern "C"
|
||||
+int
|
||||
+in_lib2 ()
|
||||
+{
|
||||
+ std::printf ("in_lib2: %d\n", S<char>::i);
|
||||
+ return S<char>::i != 3;
|
||||
+}
|
||||
diff --git a/include/bits/dlfcn.h b/include/bits/dlfcn.h
|
||||
index cb4a5c2..c31a645 100644
|
||||
--- a/include/bits/dlfcn.h
|
||||
+++ b/include/bits/dlfcn.h
|
||||
@@ -1,4 +1,3 @@
|
||||
#include_next <bits/dlfcn.h>
|
||||
|
||||
-extern void _dl_mcount_wrapper_check (void *__selfpc);
|
||||
libc_hidden_proto (_dl_mcount_wrapper_check)
|
||||
@@ -1,141 +0,0 @@
|
||||
commit 9a3c6a6ff602c88d7155139a7d7d0000b7b7e946
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Thu Jan 2 10:05:27 2014 +0530
|
||||
|
||||
Fix return code from getent netgroup when the netgroup is not found (bz #16366)
|
||||
|
||||
nscd incorrectly returns a success even when the netgroup in question
|
||||
is not found and adds a positive result in the cache. this patch
|
||||
fixes this behaviour by adding a negative lookup entry to cache and
|
||||
returning an error when the netgroup is not found.
|
||||
|
||||
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
|
||||
index 50936ee..9fc1664 100644
|
||||
--- a/nscd/netgroupcache.c
|
||||
+++ b/nscd/netgroupcache.c
|
||||
@@ -65,6 +65,55 @@ struct dataset
|
||||
char strdata[0];
|
||||
};
|
||||
|
||||
+/* Sends a notfound message and prepares a notfound dataset to write to the
|
||||
+ cache. Returns true if there was enough memory to allocate the dataset and
|
||||
+ returns the dataset in DATASETP, total bytes to write in TOTALP and the
|
||||
+ timeout in TIMEOUTP. KEY_COPY is set to point to the copy of the key in the
|
||||
+ dataset. */
|
||||
+static bool
|
||||
+do_notfound (struct database_dyn *db, int fd, request_header *req,
|
||||
+ const char *key, struct dataset **datasetp, ssize_t *totalp,
|
||||
+ time_t *timeoutp, char **key_copy)
|
||||
+{
|
||||
+ struct dataset *dataset;
|
||||
+ ssize_t total;
|
||||
+ time_t timeout;
|
||||
+ bool cacheable = false;
|
||||
+
|
||||
+ total = sizeof (notfound);
|
||||
+ timeout = time (NULL) + db->negtimeout;
|
||||
+
|
||||
+ if (fd != -1)
|
||||
+ TEMP_FAILURE_RETRY (send (fd, ¬found, total, MSG_NOSIGNAL));
|
||||
+
|
||||
+ dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1);
|
||||
+ /* If we cannot permanently store the result, so be it. */
|
||||
+ if (dataset != NULL)
|
||||
+ {
|
||||
+ dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
|
||||
+ dataset->head.recsize = total;
|
||||
+ dataset->head.notfound = true;
|
||||
+ dataset->head.nreloads = 0;
|
||||
+ dataset->head.usable = true;
|
||||
+
|
||||
+ /* Compute the timeout time. */
|
||||
+ timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
|
||||
+ dataset->head.ttl = db->negtimeout;
|
||||
+
|
||||
+ /* This is the reply. */
|
||||
+ memcpy (&dataset->resp, ¬found, total);
|
||||
+
|
||||
+ /* Copy the key data. */
|
||||
+ memcpy (dataset->strdata, key, req->key_len);
|
||||
+ *key_copy = dataset->strdata;
|
||||
+
|
||||
+ cacheable = true;
|
||||
+ }
|
||||
+ *timeoutp = timeout;
|
||||
+ *totalp = total;
|
||||
+ *datasetp = dataset;
|
||||
+ return cacheable;
|
||||
+}
|
||||
|
||||
static time_t
|
||||
addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
@@ -84,6 +133,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
struct dataset *dataset;
|
||||
bool cacheable = false;
|
||||
ssize_t total;
|
||||
+ bool found = false;
|
||||
|
||||
char *key_copy = NULL;
|
||||
struct __netgrent data;
|
||||
@@ -103,35 +153,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
&& __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database))
|
||||
{
|
||||
/* No such service. */
|
||||
- total = sizeof (notfound);
|
||||
- timeout = time (NULL) + db->negtimeout;
|
||||
-
|
||||
- if (fd != -1)
|
||||
- TEMP_FAILURE_RETRY (send (fd, ¬found, total, MSG_NOSIGNAL));
|
||||
-
|
||||
- dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1);
|
||||
- /* If we cannot permanently store the result, so be it. */
|
||||
- if (dataset != NULL)
|
||||
- {
|
||||
- dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
|
||||
- dataset->head.recsize = total;
|
||||
- dataset->head.notfound = true;
|
||||
- dataset->head.nreloads = 0;
|
||||
- dataset->head.usable = true;
|
||||
-
|
||||
- /* Compute the timeout time. */
|
||||
- timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
|
||||
- dataset->head.ttl = db->negtimeout;
|
||||
-
|
||||
- /* This is the reply. */
|
||||
- memcpy (&dataset->resp, ¬found, total);
|
||||
-
|
||||
- /* Copy the key data. */
|
||||
- memcpy (dataset->strdata, key, req->key_len);
|
||||
-
|
||||
- cacheable = true;
|
||||
- }
|
||||
-
|
||||
+ cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
|
||||
+ &key_copy);
|
||||
goto writeout;
|
||||
}
|
||||
|
||||
@@ -167,6 +190,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
{
|
||||
+ found = true;
|
||||
union
|
||||
{
|
||||
enum nss_status (*f) (struct __netgrent *, char *, size_t,
|
||||
@@ -326,6 +350,15 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
}
|
||||
}
|
||||
|
||||
+ /* No results. Return a failure and write out a notfound record in the
|
||||
+ cache. */
|
||||
+ if (!found)
|
||||
+ {
|
||||
+ cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
|
||||
+ &key_copy);
|
||||
+ goto writeout;
|
||||
+ }
|
||||
+
|
||||
total = buffilled;
|
||||
|
||||
/* Fill in the dataset. */
|
||||
@@ -1,145 +0,0 @@
|
||||
commit af37a8a3496327a6e5617a2c76f17aa1e8db835e
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Mon Jan 27 11:32:44 2014 +0530
|
||||
|
||||
Avoid undefined behaviour in netgroupcache
|
||||
|
||||
Using a buffer after it has been reallocated is undefined behaviour,
|
||||
so get offsets of the triplets in the old buffer before reallocating
|
||||
it.
|
||||
|
||||
commit 5d41dadf31bc8a2f9c34c40d52a442d3794e405c
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Fri Jan 24 13:51:15 2014 +0530
|
||||
|
||||
Adjust pointers to triplets in netgroup query data (BZ #16474)
|
||||
|
||||
The _nss_*_getnetgrent_r query populates the netgroup results in the
|
||||
allocated buffer and then sets the result triplet to point to strings
|
||||
in the buffer. This is a problem when the buffer is reallocated since
|
||||
the pointers to the triplet strings are no longer valid. The pointers
|
||||
need to be adjusted so that they now point to strings in the
|
||||
reallocated buffer.
|
||||
|
||||
commit 980cb5180e1b71224a57ca52b995c959b7148c09
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Thu Jan 16 10:20:22 2014 +0530
|
||||
|
||||
Don't use alloca in addgetnetgrentX (BZ #16453)
|
||||
|
||||
addgetnetgrentX has a buffer which is grown as per the needs of the
|
||||
requested size either by using alloca or by falling back to malloc if
|
||||
the size is larger than 1K. There are two problems with the alloca
|
||||
bits: firstly, it doesn't really extend the buffer since it does not
|
||||
use the return value of the extend_alloca macro, which is the location
|
||||
of the reallocated buffer. Due to this the buffer does not actually
|
||||
extend itself and hence a subsequent write may overwrite stuff on the
|
||||
stack.
|
||||
|
||||
The second problem is more subtle - the buffer growth on the stack is
|
||||
discontinuous due to block scope local variables. Combine that with
|
||||
the fact that unlike realloc, extend_alloca does not copy over old
|
||||
content and you have a situation where the buffer just has garbage in
|
||||
the space where it should have had data.
|
||||
|
||||
This could have been fixed by adding code to copy over old data
|
||||
whenever we call extend_alloca, but it seems unnecessarily
|
||||
complicated. This code is not exactly a performance hotspot (it's
|
||||
called when there is a cache miss, so factors like network lookup or
|
||||
file reads will dominate over memory allocation/reallocation), so this
|
||||
premature optimization is unnecessary.
|
||||
|
||||
Thanks Brad Hubbard <bhubbard@redhat.com> for his help with debugging
|
||||
the problem.
|
||||
|
||||
diff -pruN glibc-2.12-2-gc4ccff1/nscd/netgroupcache.c glibc-2.12-2-gc4ccff1.patched/nscd/netgroupcache.c
|
||||
--- glibc-2.12-2-gc4ccff1/nscd/netgroupcache.c 2014-04-09 12:13:58.618582111 +0530
|
||||
+++ glibc-2.12-2-gc4ccff1.patched/nscd/netgroupcache.c 2014-04-09 12:07:21.486598665 +0530
|
||||
@@ -93,7 +93,6 @@ addgetnetgrentX (struct database_dyn *db
|
||||
size_t buffilled = sizeof (*dataset);
|
||||
char *buffer = NULL;
|
||||
size_t nentries = 0;
|
||||
- bool use_malloc = false;
|
||||
size_t group_len = strlen (key) + 1;
|
||||
union
|
||||
{
|
||||
@@ -138,7 +137,7 @@ addgetnetgrentX (struct database_dyn *db
|
||||
}
|
||||
|
||||
memset (&data, '\0', sizeof (data));
|
||||
- buffer = alloca (buflen);
|
||||
+ buffer = xmalloc (buflen);
|
||||
first_needed.elem.next = &first_needed.elem;
|
||||
memcpy (first_needed.elem.name, key, group_len);
|
||||
data.needed_groups = &first_needed.elem;
|
||||
@@ -218,21 +217,24 @@ addgetnetgrentX (struct database_dyn *db
|
||||
|
||||
if (buflen - req->key_len - bufused < needed)
|
||||
{
|
||||
- size_t newsize = MAX (2 * buflen,
|
||||
- buflen + 2 * needed);
|
||||
- if (use_malloc || newsize > 1024 * 1024)
|
||||
- {
|
||||
- buflen = newsize;
|
||||
- char *newbuf = xrealloc (use_malloc
|
||||
- ? buffer
|
||||
- : NULL,
|
||||
- buflen);
|
||||
-
|
||||
- buffer = newbuf;
|
||||
- use_malloc = true;
|
||||
- }
|
||||
- else
|
||||
- extend_alloca (buffer, buflen, newsize);
|
||||
+ buflen += MAX (buflen, 2 * needed);
|
||||
+ /* Save offset in the old buffer. We don't
|
||||
+ bother with the NULL check here since
|
||||
+ we'll do that later anyway. */
|
||||
+ size_t nhostdiff = nhost - buffer;
|
||||
+ size_t nuserdiff = nuser - buffer;
|
||||
+ size_t ndomaindiff = ndomain - buffer;
|
||||
+
|
||||
+ char *newbuf = xrealloc (buffer, buflen);
|
||||
+ /* Fix up the triplet pointers into the new
|
||||
+ buffer. */
|
||||
+ nhost = (nhost ? newbuf + nhostdiff
|
||||
+ : NULL);
|
||||
+ nuser = (nuser ? newbuf + nuserdiff
|
||||
+ : NULL);
|
||||
+ ndomain = (ndomain ? newbuf + ndomaindiff
|
||||
+ : NULL);
|
||||
+ buffer = newbuf;
|
||||
}
|
||||
|
||||
nhost = memcpy (buffer + bufused,
|
||||
@@ -299,18 +301,8 @@ addgetnetgrentX (struct database_dyn *db
|
||||
}
|
||||
else if (status == NSS_STATUS_UNAVAIL && e == ERANGE)
|
||||
{
|
||||
- size_t newsize = 2 * buflen;
|
||||
- if (use_malloc || newsize > 1024 * 1024)
|
||||
- {
|
||||
- buflen = newsize;
|
||||
- char *newbuf = xrealloc (use_malloc
|
||||
- ? buffer : NULL, buflen);
|
||||
-
|
||||
- buffer = newbuf;
|
||||
- use_malloc = true;
|
||||
- }
|
||||
- else
|
||||
- extend_alloca (buffer, buflen, newsize);
|
||||
+ buflen *= 2;
|
||||
+ buffer = xrealloc (buffer, buflen);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,8 +438,7 @@ addgetnetgrentX (struct database_dyn *db
|
||||
}
|
||||
|
||||
out:
|
||||
- if (use_malloc)
|
||||
- free (buffer);
|
||||
+ free (buffer);
|
||||
|
||||
*resultp = dataset;
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
commit cf26a0cb6a0bbaca46a01ddad6662e5e5159a32a
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
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;
|
||||
@@ -1,214 +0,0 @@
|
||||
#
|
||||
# Based on the commit:
|
||||
#
|
||||
# commit 6c82a2f8d7c8e21e39237225c819f182ae438db3
|
||||
# Author: Carlos O'Donell <carlos@redhat.com>
|
||||
# Date: Fri Sep 6 01:02:30 2013 -0400
|
||||
#
|
||||
# Coordinate IPv6 definitions for Linux and glibc
|
||||
#
|
||||
# This change synchronizes the glibc headers with the Linux kernel
|
||||
# headers and arranges to coordinate the definition of structures
|
||||
# already defined the Linux kernel UAPI headers.
|
||||
#
|
||||
# It is now safe to include glibc's netinet/in.h or Linux's linux/in6.h
|
||||
# in any order in a userspace application and you will get the same
|
||||
# ABI. The ABI is guaranteed by UAPI and glibc.
|
||||
#
|
||||
# 2013-09-05 Carlos O'Donell <carlos@redhat.com>
|
||||
# Cong Wang <amwang@redhat.com>
|
||||
#
|
||||
# * sysdeps/unix/sysv/linux/bits/in.h
|
||||
# [_UAPI_LINUX_IN6_H]: Define __USE_KERNEL_IPV6_DEFS.
|
||||
# * inet/netinet/in.h: Move in_addr definition and bits/in.h inclusion
|
||||
# before __USE_KERNEL_IPV6_DEFS uses.
|
||||
# * inet/netinet/in.h [!__USE_KERNEL_IPV6_DEFS]: Define IPPROTO_MH, and
|
||||
# IPPROTO_BEETPH.
|
||||
# [__USE_KERNEL_IPV6_DEFS]: Don't define any of IPPROTO_*, in6_addr,
|
||||
# sockaddr_in6, or ipv6_mreq.
|
||||
#
|
||||
diff -urN glibc-2.12-2-gc4ccff1/inet/netinet/in.h glibc-2.12-2-gc4ccff1.mod/inet/netinet/in.h
|
||||
--- glibc-2.12-2-gc4ccff1/inet/netinet/in.h 2010-05-04 07:27:23.000000000 -0400
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/inet/netinet/in.h 2015-02-18 13:06:56.436802873 -0500
|
||||
@@ -28,13 +28,21 @@
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
+/* Internet address. */
|
||||
+typedef uint32_t in_addr_t;
|
||||
+struct in_addr
|
||||
+ {
|
||||
+ in_addr_t s_addr;
|
||||
+ };
|
||||
+
|
||||
+/* Get system-specific definitions. */
|
||||
+#include <bits/in.h>
|
||||
+
|
||||
/* Standard well-defined IP protocols. */
|
||||
enum
|
||||
{
|
||||
IPPROTO_IP = 0, /* Dummy protocol for TCP. */
|
||||
#define IPPROTO_IP IPPROTO_IP
|
||||
- IPPROTO_HOPOPTS = 0, /* IPv6 Hop-by-Hop options. */
|
||||
-#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS
|
||||
IPPROTO_ICMP = 1, /* Internet Control Message Protocol. */
|
||||
#define IPPROTO_ICMP IPPROTO_ICMP
|
||||
IPPROTO_IGMP = 2, /* Internet Group Management Protocol. */
|
||||
@@ -57,10 +65,6 @@
|
||||
#define IPPROTO_DCCP IPPROTO_DCCP
|
||||
IPPROTO_IPV6 = 41, /* IPv6 header. */
|
||||
#define IPPROTO_IPV6 IPPROTO_IPV6
|
||||
- IPPROTO_ROUTING = 43, /* IPv6 routing header. */
|
||||
-#define IPPROTO_ROUTING IPPROTO_ROUTING
|
||||
- IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header. */
|
||||
-#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT
|
||||
IPPROTO_RSVP = 46, /* Reservation Protocol. */
|
||||
#define IPPROTO_RSVP IPPROTO_RSVP
|
||||
IPPROTO_GRE = 47, /* General Routing Encapsulation. */
|
||||
@@ -69,14 +73,10 @@
|
||||
#define IPPROTO_ESP IPPROTO_ESP
|
||||
IPPROTO_AH = 51, /* authentication header. */
|
||||
#define IPPROTO_AH IPPROTO_AH
|
||||
- IPPROTO_ICMPV6 = 58, /* ICMPv6. */
|
||||
-#define IPPROTO_ICMPV6 IPPROTO_ICMPV6
|
||||
- IPPROTO_NONE = 59, /* IPv6 no next header. */
|
||||
-#define IPPROTO_NONE IPPROTO_NONE
|
||||
- IPPROTO_DSTOPTS = 60, /* IPv6 destination options. */
|
||||
-#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS
|
||||
IPPROTO_MTP = 92, /* Multicast Transport Protocol. */
|
||||
#define IPPROTO_MTP IPPROTO_MTP
|
||||
+ IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET. */
|
||||
+#define IPPROTO_BEETPH IPPROTO_BEETPH
|
||||
IPPROTO_ENCAP = 98, /* Encapsulation Header. */
|
||||
#define IPPROTO_ENCAP IPPROTO_ENCAP
|
||||
IPPROTO_PIM = 103, /* Protocol Independent Multicast. */
|
||||
@@ -92,6 +92,28 @@
|
||||
IPPROTO_MAX
|
||||
};
|
||||
|
||||
+/* If __USER_KERNEL_IPV6_DEFS is defined then the user has included the kernel
|
||||
+ network headers first and we should use those ABI-identical definitions
|
||||
+ instead of our own. */
|
||||
+#ifndef __USE_KERNEL_IPV6_DEFS
|
||||
+enum
|
||||
+ {
|
||||
+ IPPROTO_HOPOPTS = 0, /* IPv6 Hop-by-Hop options. */
|
||||
+#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS
|
||||
+ IPPROTO_ROUTING = 43, /* IPv6 routing header. */
|
||||
+#define IPPROTO_ROUTING IPPROTO_ROUTING
|
||||
+ IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header. */
|
||||
+#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT
|
||||
+ IPPROTO_ICMPV6 = 58, /* ICMPv6. */
|
||||
+#define IPPROTO_ICMPV6 IPPROTO_ICMPV6
|
||||
+ IPPROTO_NONE = 59, /* IPv6 no next header. */
|
||||
+#define IPPROTO_NONE IPPROTO_NONE
|
||||
+ IPPROTO_DSTOPTS = 60, /* IPv6 destination options. */
|
||||
+#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS
|
||||
+ IPPROTO_MH = 135, /* IPv6 mobility header. */
|
||||
+#define IPPROTO_MH IPPROTO_MH
|
||||
+ };
|
||||
+#endif /* !__USE_KERNEL_IPV6_DEFS */
|
||||
|
||||
/* Type to represent a port. */
|
||||
typedef uint16_t in_port_t;
|
||||
@@ -136,15 +158,6 @@
|
||||
IPPORT_USERRESERVED = 5000
|
||||
};
|
||||
|
||||
-
|
||||
-/* Internet address. */
|
||||
-typedef uint32_t in_addr_t;
|
||||
-struct in_addr
|
||||
- {
|
||||
- in_addr_t s_addr;
|
||||
- };
|
||||
-
|
||||
-
|
||||
/* Definitions of the bits in an Internet address integer.
|
||||
|
||||
On subnets, host and network parts are found according to
|
||||
@@ -193,7 +206,7 @@
|
||||
#define INADDR_ALLRTRS_GROUP ((in_addr_t) 0xe0000002) /* 224.0.0.2 */
|
||||
#define INADDR_MAX_LOCAL_GROUP ((in_addr_t) 0xe00000ff) /* 224.0.0.255 */
|
||||
|
||||
-
|
||||
+#ifndef __USE_KERNEL_IPV6_DEFS
|
||||
/* IPv6 address */
|
||||
struct in6_addr
|
||||
{
|
||||
@@ -211,6 +224,7 @@
|
||||
# define s6_addr32 __in6_u.__u6_addr32
|
||||
#endif
|
||||
};
|
||||
+#endif /* !__USE_KERNEL_IPV6_DEFS */
|
||||
|
||||
extern const struct in6_addr in6addr_any; /* :: */
|
||||
extern const struct in6_addr in6addr_loopback; /* ::1 */
|
||||
@@ -235,6 +249,7 @@
|
||||
sizeof (struct in_addr)];
|
||||
};
|
||||
|
||||
+#ifndef __USE_KERNEL_IPV6_DEFS
|
||||
/* Ditto, for IPv6. */
|
||||
struct sockaddr_in6
|
||||
{
|
||||
@@ -244,7 +259,7 @@
|
||||
struct in6_addr sin6_addr; /* IPv6 address */
|
||||
uint32_t sin6_scope_id; /* IPv6 scope-id */
|
||||
};
|
||||
-
|
||||
+#endif /* !__USE_KERNEL_IPV6_DEFS */
|
||||
|
||||
#if defined __USE_MISC || defined __USE_GNU
|
||||
/* IPv4 multicast request. */
|
||||
@@ -270,7 +285,7 @@
|
||||
};
|
||||
#endif
|
||||
|
||||
-
|
||||
+#ifndef __USE_KERNEL_IPV6_DEFS
|
||||
/* Likewise, for IPv6. */
|
||||
struct ipv6_mreq
|
||||
{
|
||||
@@ -280,7 +295,7 @@
|
||||
/* local interface */
|
||||
unsigned int ipv6mr_interface;
|
||||
};
|
||||
-
|
||||
+#endif /* !__USE_KERNEL_IPV6_DEFS */
|
||||
|
||||
#if defined __USE_MISC || defined __USE_GNU
|
||||
/* Multicast group request. */
|
||||
@@ -351,10 +366,6 @@
|
||||
* sizeof (struct sockaddr_storage)))
|
||||
#endif
|
||||
|
||||
-
|
||||
-/* Get system-specific definitions. */
|
||||
-#include <bits/in.h>
|
||||
-
|
||||
/* Functions to convert between host and network byte order.
|
||||
|
||||
Please note that these functions normally take `unsigned long int' or
|
||||
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/bits/in.h glibc-2.12-2-gc4ccff1.mod/sysdeps/unix/sysv/linux/bits/in.h
|
||||
--- glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/bits/in.h 2015-02-18 13:04:15.547734092 -0500
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/unix/sysv/linux/bits/in.h 2015-02-18 13:06:56.436802873 -0500
|
||||
@@ -22,6 +22,18 @@
|
||||
# error "Never use <bits/in.h> directly; include <netinet/in.h> instead."
|
||||
#endif
|
||||
|
||||
+/* If the application has already included linux/in6.h from a linux-based
|
||||
+ kernel then we will not define the IPv6 IPPROTO_* defines, in6_addr (nor the
|
||||
+ defines), sockaddr_in6, or ipv6_mreq. The ABI used by the linux-kernel and
|
||||
+ glibc match exactly. Neither the linux kernel nor glibc should break this
|
||||
+ ABI without coordination. */
|
||||
+#ifdef _UAPI_LINUX_IN6_H
|
||||
+/* This is not quite the same API since the kernel always defines s6_addr16 and
|
||||
+ s6_addr32. This is not a violation of POSIX since POSIX says "at least the
|
||||
+ following member" and that holds true. */
|
||||
+# define __USE_KERNEL_IPV6_DEFS
|
||||
+#endif
|
||||
+
|
||||
/* Options for use with `getsockopt' and `setsockopt' at the IP level.
|
||||
The first word in the comment at the right is the data type used;
|
||||
"bool" means a boolean value stored in an `int'. */
|
||||
@@ -1,57 +0,0 @@
|
||||
commit fbd6b5a4052316f7eb03c4617eebfaafc59dcc06
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Thu Mar 27 07:15:22 2014 +0530
|
||||
|
||||
Fix nscd lookup for innetgr when netgroup has wildcards (BZ #16758)
|
||||
|
||||
nscd works correctly when the request in innetgr is a wildcard,
|
||||
i.e. when one or more of host, user or domain parameters is NULL.
|
||||
However, it does not work when the the triplet in the netgroup
|
||||
definition has a wildcard. This is easy to reproduce for a triplet
|
||||
defined as follows:
|
||||
|
||||
foonet (,foo,)
|
||||
|
||||
Here, an innetgr call that looks like this:
|
||||
|
||||
innetgr ("foonet", "foohost", "foo", NULL);
|
||||
|
||||
should succeed and so should:
|
||||
|
||||
innetgr ("foonet", NULL, "foo", "foodomain");
|
||||
|
||||
It does succeed with nscd disabled, but not with nscd enabled. This
|
||||
fix adds this additional check for all three parts of the triplet so
|
||||
that it gives the correct result.
|
||||
|
||||
[BZ #16758]
|
||||
* nscd/netgroupcache.c (addinnetgrX): Succeed if triplet has
|
||||
blank values.
|
||||
|
||||
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
|
||||
index 5ba1e1f..5d15aa4 100644
|
||||
--- a/nscd/netgroupcache.c
|
||||
+++ b/nscd/netgroupcache.c
|
||||
@@ -560,15 +560,19 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
- if (host != NULL)
|
||||
+ /* For the host, user and domain in each triplet, we assume success
|
||||
+ if the value is blank because that is how the wildcard entry to
|
||||
+ match anything is stored in the netgroup cache. */
|
||||
+ if (host != NULL && *triplets != '\0')
|
||||
success = strcmp (host, triplets) == 0;
|
||||
triplets = (const char *) rawmemchr (triplets, '\0') + 1;
|
||||
|
||||
- if (success && user != NULL)
|
||||
+ if (success && user != NULL && *triplets != '\0')
|
||||
success = strcmp (user, triplets) == 0;
|
||||
triplets = (const char *) rawmemchr (triplets, '\0') + 1;
|
||||
|
||||
- if (success && (domain == NULL || strcmp (domain, triplets) == 0))
|
||||
+ if (success && (domain == NULL || *triplets == '\0'
|
||||
+ || strcmp (domain, triplets) == 0))
|
||||
{
|
||||
dataset->resp.result = 1;
|
||||
break;
|
||||
@@ -1,620 +0,0 @@
|
||||
diff --git a/malloc/Makefile b/malloc/Makefile
|
||||
index e7ec1ab..5330a3b 100644
|
||||
--- a/malloc/Makefile
|
||||
+++ b/malloc/Makefile
|
||||
@@ -27,7 +27,8 @@ all:
|
||||
dist-headers := malloc.h
|
||||
headers := $(dist-headers) obstack.h mcheck.h
|
||||
tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
|
||||
- tst-mallocstate tst-mcheck tst-mallocfork tst-trim1
|
||||
+ tst-mallocstate tst-mcheck tst-mallocfork tst-trim1 \
|
||||
+ tst-malloc-backtrace
|
||||
test-srcs = tst-mtrace
|
||||
|
||||
distribute = thread-m.h mtrace.pl mcheck-init.c stackinfo.h memusage.h \
|
||||
@@ -49,6 +50,9 @@ extra-libs-others = $(extra-libs)
|
||||
libmemusage-routines = memusage
|
||||
libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
|
||||
|
||||
+$(objpfx)tst-malloc-backtrace: $(common-objpfx)nptl/libpthread.so \
|
||||
+ $(common-objpfx)nptl/libpthread_nonshared.a
|
||||
+
|
||||
# These should be removed by `make clean'.
|
||||
extra-objs = mcheck-init.o libmcheck.a
|
||||
|
||||
diff --git a/malloc/arena.c b/malloc/arena.c
|
||||
index 18bea2b..5180516 100644
|
||||
--- a/malloc/arena.c
|
||||
+++ b/malloc/arena.c
|
||||
@@ -123,7 +123,7 @@ int __malloc_initialized = -1;
|
||||
|
||||
#ifdef PER_THREAD
|
||||
#define arena_lock(ptr, size) do { \
|
||||
- if(ptr) \
|
||||
+ if(ptr && !arena_is_corrupt (ptr)) \
|
||||
(void)mutex_lock(&ptr->mutex); \
|
||||
else \
|
||||
ptr = arena_get2(ptr, (size), false); \
|
||||
@@ -1011,7 +1011,21 @@ reused_arena (bool retrying)
|
||||
if (retrying && result == &main_arena)
|
||||
result = result->next;
|
||||
|
||||
- /* No arena available. Wait for the next in line. */
|
||||
+ /* Make sure that the arena we get is not corrupted. */
|
||||
+ mstate begin = result;
|
||||
+ while (arena_is_corrupt (result))
|
||||
+ {
|
||||
+ result = result->next;
|
||||
+ if (result == begin)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* We could not find any arena that was either not corrupted or not the one
|
||||
+ we wanted to avoid. */
|
||||
+ if (result == begin)
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* No arena available without contention. Wait for the next in line. */
|
||||
(void)mutex_lock(&result->mutex);
|
||||
|
||||
out:
|
||||
diff --git a/malloc/hooks.c b/malloc/hooks.c
|
||||
index cc83d21..38d2542 100644
|
||||
--- a/malloc/hooks.c
|
||||
+++ b/malloc/hooks.c
|
||||
@@ -220,7 +220,8 @@ top_check()
|
||||
return 0;
|
||||
|
||||
mutex_unlock(&main_arena);
|
||||
- malloc_printerr (check_action, "malloc: top chunk is corrupt", t);
|
||||
+ malloc_printerr (check_action, "malloc: top chunk is corrupt", t,
|
||||
+ &main_arena);
|
||||
mutex_lock(&main_arena);
|
||||
|
||||
/* Try to set up a new top chunk. */
|
||||
@@ -283,7 +284,7 @@ free_check(mem, caller) Void_t* mem; const Void_t *caller;
|
||||
if(!p) {
|
||||
(void)mutex_unlock(&main_arena.mutex);
|
||||
|
||||
- malloc_printerr(check_action, "free(): invalid pointer", mem);
|
||||
+ malloc_printerr(check_action, "free(): invalid pointer", mem, &main_arena);
|
||||
return;
|
||||
}
|
||||
#if HAVE_MMAP
|
||||
@@ -329,7 +330,8 @@ realloc_check(oldmem, bytes, caller)
|
||||
const mchunkptr oldp = mem2chunk_check(oldmem, &magic_p);
|
||||
(void)mutex_unlock(&main_arena.mutex);
|
||||
if(!oldp) {
|
||||
- malloc_printerr(check_action, "realloc(): invalid pointer", oldmem);
|
||||
+ malloc_printerr(check_action, "realloc(): invalid pointer", oldmem,
|
||||
+ &main_arena);
|
||||
return malloc_check(bytes, NULL);
|
||||
}
|
||||
const INTERNAL_SIZE_T oldsize = chunksize(oldp);
|
||||
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||
index 597c7b0..20ac534 100644
|
||||
--- a/malloc/malloc.c
|
||||
+++ b/malloc/malloc.c
|
||||
@@ -1633,7 +1633,7 @@ static size_t mUSABLe(Void_t*);
|
||||
static void mSTATs(void);
|
||||
static int mALLOPt(int, int);
|
||||
static struct mallinfo mALLINFo(mstate);
|
||||
-static void malloc_printerr(int action, const char *str, void *ptr);
|
||||
+static void malloc_printerr(int action, const char *str, void *ptr, mstate av);
|
||||
|
||||
static Void_t* internal_function mem2mem_check(Void_t *p, size_t sz);
|
||||
static int internal_function top_check(void);
|
||||
@@ -2114,7 +2114,8 @@ typedef struct malloc_chunk* mbinptr;
|
||||
BK = P->bk; \
|
||||
if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) { \
|
||||
mutex_unlock(&(AV)->mutex); \
|
||||
- malloc_printerr (check_action, "corrupted double-linked list", P); \
|
||||
+ malloc_printerr (check_action, "corrupted double-linked list", P, \
|
||||
+ AV); \
|
||||
mutex_lock(&(AV)->mutex); \
|
||||
} else { \
|
||||
FD->bk = BK; \
|
||||
@@ -2344,6 +2345,15 @@ typedef struct malloc_chunk* mfastbinptr;
|
||||
#define set_noncontiguous(M) ((M)->flags |= NONCONTIGUOUS_BIT)
|
||||
#define set_contiguous(M) ((M)->flags &= ~NONCONTIGUOUS_BIT)
|
||||
|
||||
+/* ARENA_CORRUPTION_BIT is set if a memory corruption was detected on the
|
||||
+ arena. Such an arena is no longer used to allocate chunks. Chunks
|
||||
+ allocated in that arena before detecting corruption are not freed. */
|
||||
+
|
||||
+#define ARENA_CORRUPTION_BIT (4U)
|
||||
+
|
||||
+#define arena_is_corrupt(A) (((A)->flags & ARENA_CORRUPTION_BIT))
|
||||
+#define set_arena_corrupt(A) ((A)->flags |= ARENA_CORRUPTION_BIT)
|
||||
+
|
||||
/*
|
||||
Set value of max_fast.
|
||||
Use impossibly small value if 0.
|
||||
@@ -3002,8 +3012,9 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;
|
||||
rather than expanding top.
|
||||
*/
|
||||
|
||||
- if ((unsigned long)(nb) >= (unsigned long)(mp_.mmap_threshold) &&
|
||||
- (mp_.n_mmaps < mp_.n_mmaps_max)) {
|
||||
+ if (av == NULL
|
||||
+ || ((unsigned long)(nb) >= (unsigned long)(mp_.mmap_threshold) &&
|
||||
+ (mp_.n_mmaps < mp_.n_mmaps_max))) {
|
||||
|
||||
char* mm; /* return value from mmap call*/
|
||||
|
||||
@@ -3079,6 +3090,10 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;
|
||||
}
|
||||
#endif
|
||||
|
||||
+ /* There are no usable arenas and mmap also failed. */
|
||||
+ if (av == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
/* Record incoming configuration of top */
|
||||
|
||||
old_top = av->top;
|
||||
@@ -3260,7 +3275,7 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;
|
||||
else if (contiguous(av) && old_size && brk < old_end) {
|
||||
/* Oops! Someone else killed our space.. Can't touch anything. */
|
||||
mutex_unlock(&av->mutex);
|
||||
- malloc_printerr (3, "break adjusted to free malloc space", brk);
|
||||
+ malloc_printerr (3, "break adjusted to free malloc space", brk, av);
|
||||
mutex_lock(&av->mutex);
|
||||
}
|
||||
|
||||
@@ -3542,7 +3557,7 @@ munmap_chunk(p) mchunkptr p;
|
||||
if (__builtin_expect (((block | total_size) & (mp_.pagesize - 1)) != 0, 0))
|
||||
{
|
||||
malloc_printerr (check_action, "munmap_chunk(): invalid pointer",
|
||||
- chunk2mem (p));
|
||||
+ chunk2mem (p), NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3625,65 +3640,31 @@ public_mALLOc(size_t bytes)
|
||||
if (__builtin_expect (hook != NULL, 0))
|
||||
return (*hook)(bytes, RETURN_ADDRESS (0));
|
||||
|
||||
- arena_lookup(ar_ptr);
|
||||
-#if 0
|
||||
- // XXX We need double-word CAS and fastbins must be extended to also
|
||||
- // XXX hold a generation counter for each entry.
|
||||
- if (ar_ptr) {
|
||||
- INTERNAL_SIZE_T nb; /* normalized request size */
|
||||
- checked_request2size(bytes, nb);
|
||||
- if (nb <= get_max_fast ()) {
|
||||
- long int idx = fastbin_index(nb);
|
||||
- mfastbinptr* fb = &fastbin (ar_ptr, idx);
|
||||
- mchunkptr pp = *fb;
|
||||
- mchunkptr v;
|
||||
- do
|
||||
- {
|
||||
- v = pp;
|
||||
- if (v == NULL)
|
||||
- break;
|
||||
- }
|
||||
- while ((pp = catomic_compare_and_exchange_val_acq (fb, v->fd, v)) != v);
|
||||
- if (v != 0) {
|
||||
- if (__builtin_expect (fastbin_index (chunksize (v)) != idx, 0))
|
||||
- malloc_printerr (check_action, "malloc(): memory corruption (fast)",
|
||||
- chunk2mem (v));
|
||||
- check_remalloced_chunk(ar_ptr, v, nb);
|
||||
- void *p = chunk2mem(v);
|
||||
- if (__builtin_expect (perturb_byte, 0))
|
||||
- alloc_perturb (p, bytes);
|
||||
- return p;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
+ arena_get(ar_ptr, bytes);
|
||||
|
||||
- arena_lock(ar_ptr, bytes);
|
||||
- if(!ar_ptr)
|
||||
- return 0;
|
||||
victim = _int_malloc(ar_ptr, bytes);
|
||||
- if(!victim) {
|
||||
+ if(!victim && ar_ptr != NULL) {
|
||||
/* Maybe the failure is due to running out of mmapped areas. */
|
||||
if(ar_ptr != &main_arena) {
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
ar_ptr = &main_arena;
|
||||
(void)mutex_lock(&ar_ptr->mutex);
|
||||
victim = _int_malloc(ar_ptr, bytes);
|
||||
- (void)mutex_unlock(&ar_ptr->mutex);
|
||||
} else {
|
||||
#if USE_ARENAS
|
||||
/* ... or sbrk() has failed and there is still a chance to mmap() */
|
||||
mstate prev = ar_ptr->next ? ar_ptr : 0;
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
ar_ptr = arena_get2(prev, bytes, true);
|
||||
- if(ar_ptr) {
|
||||
+ if(ar_ptr)
|
||||
victim = _int_malloc(ar_ptr, bytes);
|
||||
- (void)mutex_unlock(&ar_ptr->mutex);
|
||||
- }
|
||||
#endif
|
||||
}
|
||||
- } else
|
||||
+ }
|
||||
+
|
||||
+ if (ar_ptr != NULL)
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
+
|
||||
assert(!victim || chunk_is_mmapped(mem2chunk(victim)) ||
|
||||
ar_ptr == arena_for_chunk(mem2chunk(victim)));
|
||||
return victim;
|
||||
@@ -3773,6 +3754,11 @@ public_rEALLOc(Void_t* oldmem, size_t bytes)
|
||||
/* its size */
|
||||
const INTERNAL_SIZE_T oldsize = chunksize(oldp);
|
||||
|
||||
+ if (chunk_is_mmapped (oldp))
|
||||
+ ar_ptr = NULL;
|
||||
+ else
|
||||
+ ar_ptr = arena_for_chunk (oldp);
|
||||
+
|
||||
/* Little security check which won't hurt performance: the
|
||||
allocator never wrapps around at the end of the address space.
|
||||
Therefore we can exclude some size values which might appear
|
||||
@@ -3780,7 +3766,8 @@ public_rEALLOc(Void_t* oldmem, size_t bytes)
|
||||
if (__builtin_expect ((uintptr_t) oldp > (uintptr_t) -oldsize, 0)
|
||||
|| __builtin_expect (misaligned_chunk (oldp), 0))
|
||||
{
|
||||
- malloc_printerr (check_action, "realloc(): invalid pointer", oldmem);
|
||||
+ malloc_printerr (check_action, "realloc(): invalid pointer", oldmem,
|
||||
+ ar_ptr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3806,7 +3793,6 @@ public_rEALLOc(Void_t* oldmem, size_t bytes)
|
||||
}
|
||||
#endif
|
||||
|
||||
- ar_ptr = arena_for_chunk(oldp);
|
||||
#if THREAD_STATS
|
||||
if(!mutex_trylock(&ar_ptr->mutex))
|
||||
++(ar_ptr->stat_lock_direct);
|
||||
@@ -3887,31 +3873,29 @@ public_mEMALIGn(size_t alignment, size_t bytes)
|
||||
}
|
||||
|
||||
arena_get(ar_ptr, bytes + alignment + MINSIZE);
|
||||
- if(!ar_ptr)
|
||||
- return 0;
|
||||
p = _int_memalign(ar_ptr, alignment, bytes);
|
||||
- if(!p) {
|
||||
+ if(!p && ar_ptr != NULL) {
|
||||
/* Maybe the failure is due to running out of mmapped areas. */
|
||||
if(ar_ptr != &main_arena) {
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
ar_ptr = &main_arena;
|
||||
(void)mutex_lock(&ar_ptr->mutex);
|
||||
p = _int_memalign(ar_ptr, alignment, bytes);
|
||||
- (void)mutex_unlock(&ar_ptr->mutex);
|
||||
} else {
|
||||
#if USE_ARENAS
|
||||
/* ... or sbrk() has failed and there is still a chance to mmap() */
|
||||
mstate prev = ar_ptr->next ? ar_ptr : 0;
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
ar_ptr = arena_get2(prev, bytes, true);
|
||||
- if(ar_ptr) {
|
||||
+ if(ar_ptr)
|
||||
p = _int_memalign(ar_ptr, alignment, bytes);
|
||||
- (void)mutex_unlock(&ar_ptr->mutex);
|
||||
- }
|
||||
#endif
|
||||
}
|
||||
- } else
|
||||
+ }
|
||||
+
|
||||
+ if (ar_ptr != NULL)
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
+
|
||||
assert(!p || chunk_is_mmapped(mem2chunk(p)) ||
|
||||
ar_ptr == arena_for_chunk(mem2chunk(p)));
|
||||
return p;
|
||||
@@ -3945,31 +3929,29 @@ public_vALLOc(size_t bytes)
|
||||
return (*hook)(pagesz, bytes, RETURN_ADDRESS (0));
|
||||
|
||||
arena_get(ar_ptr, bytes + pagesz + MINSIZE);
|
||||
- if(!ar_ptr)
|
||||
- return 0;
|
||||
p = _int_valloc(ar_ptr, bytes);
|
||||
- if(!p) {
|
||||
+ if(!p && ar_ptr != NULL) {
|
||||
/* Maybe the failure is due to running out of mmapped areas. */
|
||||
if(ar_ptr != &main_arena) {
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
ar_ptr = &main_arena;
|
||||
(void)mutex_lock(&ar_ptr->mutex);
|
||||
p = _int_memalign(ar_ptr, pagesz, bytes);
|
||||
- (void)mutex_unlock(&ar_ptr->mutex);
|
||||
} else {
|
||||
#if USE_ARENAS
|
||||
/* ... or sbrk() has failed and there is still a chance to mmap() */
|
||||
mstate prev = ar_ptr->next ? ar_ptr : 0;
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
ar_ptr = arena_get2(prev, bytes, true);
|
||||
- if(ar_ptr) {
|
||||
+ if(ar_ptr)
|
||||
p = _int_memalign(ar_ptr, pagesz, bytes);
|
||||
- (void)mutex_unlock(&ar_ptr->mutex);
|
||||
- }
|
||||
#endif
|
||||
}
|
||||
- } else
|
||||
+ }
|
||||
+
|
||||
+ if (ar_ptr != NULL)
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
+
|
||||
assert(!p || chunk_is_mmapped(mem2chunk(p)) ||
|
||||
ar_ptr == arena_for_chunk(mem2chunk(p)));
|
||||
|
||||
@@ -4004,28 +3986,28 @@ public_pVALLOc(size_t bytes)
|
||||
|
||||
arena_get(ar_ptr, bytes + 2*pagesz + MINSIZE);
|
||||
p = _int_pvalloc(ar_ptr, bytes);
|
||||
- if(!p) {
|
||||
+ if(!p && ar_ptr != NULL) {
|
||||
/* Maybe the failure is due to running out of mmapped areas. */
|
||||
if(ar_ptr != &main_arena) {
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
ar_ptr = &main_arena;
|
||||
(void)mutex_lock(&ar_ptr->mutex);
|
||||
p = _int_memalign(ar_ptr, pagesz, rounded_bytes);
|
||||
- (void)mutex_unlock(&ar_ptr->mutex);
|
||||
} else {
|
||||
#if USE_ARENAS
|
||||
/* ... or sbrk() has failed and there is still a chance to mmap() */
|
||||
mstate prev = ar_ptr->next ? ar_ptr : 0;
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
ar_ptr = arena_get2(prev, bytes + 2*pagesz + MINSIZE, true);
|
||||
- if(ar_ptr) {
|
||||
+ if(ar_ptr)
|
||||
p = _int_memalign(ar_ptr, pagesz, rounded_bytes);
|
||||
- (void)mutex_unlock(&ar_ptr->mutex);
|
||||
- }
|
||||
#endif
|
||||
}
|
||||
- } else
|
||||
+ }
|
||||
+
|
||||
+ if (ar_ptr != NULL)
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
+
|
||||
assert(!p || chunk_is_mmapped(mem2chunk(p)) ||
|
||||
ar_ptr == arena_for_chunk(mem2chunk(p)));
|
||||
|
||||
@@ -4072,55 +4054,65 @@ public_cALLOc(size_t n, size_t elem_size)
|
||||
sz = bytes;
|
||||
|
||||
arena_get(av, sz);
|
||||
- if(!av)
|
||||
- return 0;
|
||||
|
||||
- /* Check if we hand out the top chunk, in which case there may be no
|
||||
- need to clear. */
|
||||
+ if (av)
|
||||
+ {
|
||||
+ /* Check if we hand out the top chunk, in which case there may be no
|
||||
+ need to clear. */
|
||||
#if MORECORE_CLEARS
|
||||
- oldtop = top(av);
|
||||
- oldtopsize = chunksize(top(av));
|
||||
+ oldtop = top(av);
|
||||
+ oldtopsize = chunksize(top(av));
|
||||
#if MORECORE_CLEARS < 2
|
||||
- /* Only newly allocated memory is guaranteed to be cleared. */
|
||||
- if (av == &main_arena &&
|
||||
- oldtopsize < mp_.sbrk_base + av->max_system_mem - (char *)oldtop)
|
||||
- oldtopsize = (mp_.sbrk_base + av->max_system_mem - (char *)oldtop);
|
||||
+ /* Only newly allocated memory is guaranteed to be cleared. */
|
||||
+ if (av == &main_arena &&
|
||||
+ oldtopsize < mp_.sbrk_base + av->max_system_mem - (char *)oldtop)
|
||||
+ oldtopsize = (mp_.sbrk_base + av->max_system_mem - (char *)oldtop);
|
||||
#endif
|
||||
- if (av != &main_arena)
|
||||
+ if (av != &main_arena)
|
||||
+ {
|
||||
+ heap_info *heap = heap_for_ptr (oldtop);
|
||||
+ if (oldtopsize < (char *) heap + heap->mprotect_size - (char *) oldtop)
|
||||
+ oldtopsize = (char *) heap + heap->mprotect_size - (char *) oldtop;
|
||||
+ }
|
||||
+#endif
|
||||
+ }
|
||||
+ else
|
||||
{
|
||||
- heap_info *heap = heap_for_ptr (oldtop);
|
||||
- if (oldtopsize < (char *) heap + heap->mprotect_size - (char *) oldtop)
|
||||
- oldtopsize = (char *) heap + heap->mprotect_size - (char *) oldtop;
|
||||
+ /* No usable arenas. */
|
||||
+ oldtop = 0;
|
||||
+ oldtopsize = 0;
|
||||
}
|
||||
-#endif
|
||||
mem = _int_malloc(av, sz);
|
||||
|
||||
-
|
||||
assert(!mem || chunk_is_mmapped(mem2chunk(mem)) ||
|
||||
av == arena_for_chunk(mem2chunk(mem)));
|
||||
|
||||
- if (mem == 0) {
|
||||
+ if (mem == 0 && av != NULL) {
|
||||
/* Maybe the failure is due to running out of mmapped areas. */
|
||||
if(av != &main_arena) {
|
||||
(void)mutex_unlock(&av->mutex);
|
||||
(void)mutex_lock(&main_arena.mutex);
|
||||
mem = _int_malloc(&main_arena, sz);
|
||||
- (void)mutex_unlock(&main_arena.mutex);
|
||||
} else {
|
||||
#if USE_ARENAS
|
||||
/* ... or sbrk() has failed and there is still a chance to mmap() */
|
||||
mstate prev = av->next ? av : 0;
|
||||
(void)mutex_unlock(&av->mutex);
|
||||
av = arena_get2(prev, sz, true);
|
||||
- if(av) {
|
||||
+ if(av)
|
||||
mem = _int_malloc(av, sz);
|
||||
- (void)mutex_unlock(&av->mutex);
|
||||
- }
|
||||
#endif
|
||||
}
|
||||
if (mem == 0) return 0;
|
||||
- } else
|
||||
+ }
|
||||
+
|
||||
+ if (av != NULL)
|
||||
(void)mutex_unlock(&av->mutex);
|
||||
+
|
||||
+ /* Allocation failed even after a retry. */
|
||||
+ if (mem == 0)
|
||||
+ return 0;
|
||||
+
|
||||
p = mem2chunk(mem);
|
||||
|
||||
/* Two optional cases in which clearing not necessary */
|
||||
@@ -4175,6 +4167,8 @@ public_cALLOc(size_t n, size_t elem_size)
|
||||
}
|
||||
|
||||
#ifndef _LIBC
|
||||
+/* XXX These functions are not patched to detect arena corruption because they
|
||||
+ are not built in glibc. */
|
||||
|
||||
Void_t**
|
||||
public_iCALLOc(size_t n, size_t elem_size, Void_t** chunks)
|
||||
@@ -4309,6 +4303,16 @@ _int_malloc(mstate av, size_t bytes)
|
||||
|
||||
checked_request2size(bytes, nb);
|
||||
|
||||
+ /* There are no usable arenas. Fall back to sysmalloc to get a chunk from
|
||||
+ mmap. */
|
||||
+ if (__glibc_unlikely (av == NULL))
|
||||
+ {
|
||||
+ void *p = sYSMALLOc (nb, av);
|
||||
+ if (p != NULL)
|
||||
+ alloc_perturb (p, bytes);
|
||||
+ return p;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
If the size qualifies as a fastbin, first check corresponding bin.
|
||||
This code is safe to execute even if av is not yet initialized, so we
|
||||
@@ -4337,7 +4341,7 @@ _int_malloc(mstate av, size_t bytes)
|
||||
errstr = "malloc(): memory corruption (fast)";
|
||||
errout:
|
||||
mutex_unlock(&av->mutex);
|
||||
- malloc_printerr (check_action, errstr, chunk2mem (victim));
|
||||
+ malloc_printerr (check_action, errstr, chunk2mem (victim), av);
|
||||
mutex_lock(&av->mutex);
|
||||
return NULL;
|
||||
}
|
||||
@@ -4429,7 +4433,7 @@ _int_malloc(mstate av, size_t bytes)
|
||||
{
|
||||
void *p = chunk2mem(victim);
|
||||
mutex_unlock(&av->mutex);
|
||||
- malloc_printerr (check_action, "malloc(): memory corruption", p);
|
||||
+ malloc_printerr (check_action, "malloc(): memory corruption", p, av);
|
||||
mutex_lock(&av->mutex);
|
||||
}
|
||||
size = chunksize(victim);
|
||||
@@ -4829,7 +4833,7 @@ _int_free(mstate av, mchunkptr p)
|
||||
if (have_lock || locked)
|
||||
(void)mutex_unlock(&av->mutex);
|
||||
#endif
|
||||
- malloc_printerr (check_action, errstr, chunk2mem(p));
|
||||
+ malloc_printerr (check_action, errstr, chunk2mem(p), av);
|
||||
#ifdef ATOMIC_FASTBINS
|
||||
if (have_lock)
|
||||
mutex_lock(&av->mutex);
|
||||
@@ -5281,7 +5285,7 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
|
||||
errstr = "realloc(): invalid old size";
|
||||
errout:
|
||||
mutex_unlock(&av->mutex);
|
||||
- malloc_printerr (check_action, errstr, chunk2mem(oldp));
|
||||
+ malloc_printerr (check_action, errstr, chunk2mem(oldp), av);
|
||||
mutex_lock(&av->mutex);
|
||||
return NULL;
|
||||
}
|
||||
@@ -5881,6 +5885,10 @@ static int mTRIm(mstate av, size_t pad)
|
||||
static int mTRIm(av, pad) mstate av; size_t pad;
|
||||
#endif
|
||||
{
|
||||
+ /* Don't touch corrupt arenas. */
|
||||
+ if (arena_is_corrupt (av))
|
||||
+ return 0;
|
||||
+
|
||||
/* Ensure initialization/consolidation */
|
||||
malloc_consolidate (av);
|
||||
|
||||
@@ -6320,8 +6328,14 @@ int mALLOPt(param_number, value) int param_number; int value;
|
||||
extern char **__libc_argv attribute_hidden;
|
||||
|
||||
static void
|
||||
-malloc_printerr(int action, const char *str, void *ptr)
|
||||
+malloc_printerr(int action, const char *str, void *ptr, mstate ar_ptr)
|
||||
{
|
||||
+ /* Avoid using this arena in future. We do not attempt to synchronize this
|
||||
+ with anything else because we minimally want to ensure that __libc_message
|
||||
+ gets its resources safely without stumbling on the current corruption. */
|
||||
+ if (ar_ptr)
|
||||
+ set_arena_corrupt (ar_ptr);
|
||||
+
|
||||
if ((action & 5) == 5)
|
||||
__libc_message (action & 2, "%s\n", str);
|
||||
else if (action & 1)
|
||||
diff --git a/malloc/tst-malloc-backtrace.c b/malloc/tst-malloc-backtrace.c
|
||||
new file mode 100644
|
||||
index 0000000..796a42f
|
||||
--- /dev/null
|
||||
+++ b/malloc/tst-malloc-backtrace.c
|
||||
@@ -0,0 +1,50 @@
|
||||
+/* Verify that backtrace does not deadlock on itself on memory corruption.
|
||||
+ Copyright (C) 2015 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 <stdlib.h>
|
||||
+
|
||||
+#define SIZE 4096
|
||||
+
|
||||
+/* Wrap free with a function to prevent gcc from optimizing it out. */
|
||||
+static void
|
||||
+__attribute__((noinline))
|
||||
+call_free (void *ptr)
|
||||
+{
|
||||
+ free (ptr);
|
||||
+ *(size_t *)(ptr - sizeof (size_t)) = 1;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ void *ptr1 = malloc (SIZE);
|
||||
+ void *ptr2 = malloc (SIZE);
|
||||
+
|
||||
+ call_free ((void *) ptr1);
|
||||
+ ptr1 = malloc (SIZE);
|
||||
+
|
||||
+ /* Not reached. The return statement is to put ptr2 into use so that gcc
|
||||
+ doesn't optimize out that malloc call. */
|
||||
+ return (ptr1 == ptr2);
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#define EXPECTED_SIGNAL SIGABRT
|
||||
+
|
||||
+#include "../test-skeleton.c"
|
||||
@@ -1,26 +0,0 @@
|
||||
commit c44496df2f090a56d3bf75df930592dac6bba46f
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Wed Mar 12 17:27:22 2014 +0530
|
||||
|
||||
Provide correct buffer length to netgroup queries in nscd (BZ #16695)
|
||||
|
||||
The buffer to query netgroup entries is allocated sufficient space for
|
||||
the netgroup entries and the key to be appended at the end, but it
|
||||
sends in an incorrect available length to the NSS netgroup query
|
||||
functions, resulting in overflow of the buffer in some special cases.
|
||||
The fix here is to factor in the key length when sending the available
|
||||
buffer and buffer length to the query functions.
|
||||
|
||||
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
|
||||
index 426d3c5..5ba1e1f 100644
|
||||
--- a/nscd/netgroupcache.c
|
||||
+++ b/nscd/netgroupcache.c
|
||||
@@ -202,7 +202,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
{
|
||||
int e;
|
||||
status = getfct.f (&data, buffer + buffilled,
|
||||
- buflen - buffilled, &e);
|
||||
+ buflen - buffilled - req->key_len, &e);
|
||||
if (status == NSS_STATUS_RETURN
|
||||
|| status == NSS_STATUS_NOTFOUND)
|
||||
/* This was either the last one for this group or the
|
||||
@@ -1,398 +0,0 @@
|
||||
commit bc8f194c8c29e46e8ee4034f06e46988dfff38f7
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Wed Apr 30 12:00:39 2014 +0530
|
||||
|
||||
Initialize all of datahead structure in nscd (BZ #16791)
|
||||
|
||||
The datahead structure has an unused padding field that remains
|
||||
uninitialized. Valgrind prints out a warning for it on querying a
|
||||
netgroups entry. This is harmless, but is a potential data leak since
|
||||
it would result in writing out an uninitialized byte to the cache
|
||||
file. Besides, this happens only when there is a cache miss, so we're
|
||||
not adding computation to any fast path.
|
||||
|
||||
commit 1cdeb2372ddecac0dfe0c132a033e9590ffa07d2
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Wed Apr 30 11:57:09 2014 +0530
|
||||
|
||||
Consolidate code to initialize nscd dataset header
|
||||
|
||||
This patch consolidates the code to initialize the header of a dataset
|
||||
into a single set of functions (one for positive and another for
|
||||
negative datasets) primarily to reduce repetition of code. The
|
||||
secondary reason is to simplify Patch 2/2 which fixes the problem of
|
||||
an uninitialized byte in the header by initializing an unused field in
|
||||
the structure and hence preventing a possible data leak into the cache
|
||||
file.
|
||||
|
||||
diff --git a/nscd/aicache.c b/nscd/aicache.c
|
||||
index 98d40a1..d7966bd 100644
|
||||
--- a/nscd/aicache.c
|
||||
+++ b/nscd/aicache.c
|
||||
@@ -383,17 +383,12 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
|
||||
cp = family;
|
||||
}
|
||||
|
||||
- /* Fill in the rest of the dataset. */
|
||||
- dataset->head.allocsize = total + req->key_len;
|
||||
- dataset->head.recsize = total - offsetof (struct dataset, resp);
|
||||
- dataset->head.notfound = false;
|
||||
- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
|
||||
- dataset->head.usable = true;
|
||||
-
|
||||
- /* Compute the timeout time. */
|
||||
- dataset->head.ttl = ttl == INT32_MAX ? db->postimeout : ttl;
|
||||
- timeout = dataset->head.timeout = time (NULL) + dataset->head.ttl;
|
||||
+ timeout = datahead_init_pos (&dataset->head, total + req->key_len,
|
||||
+ total - offsetof (struct dataset, resp),
|
||||
+ he == NULL ? 0 : dh->nreloads + 1,
|
||||
+ ttl == INT32_MAX ? db->postimeout : ttl);
|
||||
|
||||
+ /* Fill in the rest of the dataset. */
|
||||
dataset->resp.version = NSCD_VERSION;
|
||||
dataset->resp.found = 1;
|
||||
dataset->resp.naddrs = naddrs;
|
||||
@@ -528,15 +523,9 @@ next_nip:
|
||||
else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
|
||||
+ req->key_len), 1)) != NULL)
|
||||
{
|
||||
- dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
|
||||
- dataset->head.recsize = total;
|
||||
- dataset->head.notfound = true;
|
||||
- dataset->head.nreloads = 0;
|
||||
- dataset->head.usable = true;
|
||||
-
|
||||
- /* Compute the timeout time. */
|
||||
- timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
|
||||
- dataset->head.ttl = db->negtimeout;
|
||||
+ timeout = datahead_init_neg (&dataset->head,
|
||||
+ sizeof (struct dataset) + req->key_len,
|
||||
+ total, db->negtimeout);
|
||||
|
||||
/* This is the reply. */
|
||||
memcpy (&dataset->resp, ¬found, total);
|
||||
diff --git a/nscd/grpcache.c b/nscd/grpcache.c
|
||||
index b5a33eb..df59fa7 100644
|
||||
--- a/nscd/grpcache.c
|
||||
+++ b/nscd/grpcache.c
|
||||
@@ -128,14 +128,10 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
|
||||
}
|
||||
else if ((dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1)) != NULL)
|
||||
{
|
||||
- dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
|
||||
- dataset->head.recsize = total;
|
||||
- dataset->head.notfound = true;
|
||||
- dataset->head.nreloads = 0;
|
||||
- dataset->head.usable = true;
|
||||
-
|
||||
- /* Compute the timeout time. */
|
||||
- timeout = dataset->head.timeout = t + db->negtimeout;
|
||||
+ timeout = datahead_init_neg (&dataset->head,
|
||||
+ (sizeof (struct dataset)
|
||||
+ + req->key_len), total,
|
||||
+ db->negtimeout);
|
||||
|
||||
/* This is the reply. */
|
||||
memcpy (&dataset->resp, ¬found, total);
|
||||
@@ -232,14 +228,10 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
|
||||
dataset_temporary = true;
|
||||
}
|
||||
|
||||
- dataset->head.allocsize = total + n;
|
||||
- dataset->head.recsize = total - offsetof (struct dataset, resp);
|
||||
- dataset->head.notfound = false;
|
||||
- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
|
||||
- dataset->head.usable = true;
|
||||
-
|
||||
- /* Compute the timeout time. */
|
||||
- timeout = dataset->head.timeout = t + db->postimeout;
|
||||
+ timeout = datahead_init_pos (&dataset->head, total + n,
|
||||
+ total - offsetof (struct dataset, resp),
|
||||
+ he == NULL ? 0 : dh->nreloads + 1,
|
||||
+ db->postimeout);
|
||||
|
||||
dataset->resp.version = NSCD_VERSION;
|
||||
dataset->resp.found = 1;
|
||||
diff --git a/nscd/hstcache.c b/nscd/hstcache.c
|
||||
index a79b67a..d4f1ad2 100644
|
||||
--- a/nscd/hstcache.c
|
||||
+++ b/nscd/hstcache.c
|
||||
@@ -152,15 +152,11 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
|
||||
else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
|
||||
+ req->key_len), 1)) != NULL)
|
||||
{
|
||||
- dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
|
||||
- dataset->head.recsize = total;
|
||||
- dataset->head.notfound = true;
|
||||
- dataset->head.nreloads = 0;
|
||||
- dataset->head.usable = true;
|
||||
-
|
||||
- /* Compute the timeout time. */
|
||||
- dataset->head.ttl = ttl == INT32_MAX ? db->negtimeout : ttl;
|
||||
- timeout = dataset->head.timeout = t + dataset->head.ttl;
|
||||
+ timeout = datahead_init_neg (&dataset->head,
|
||||
+ (sizeof (struct dataset)
|
||||
+ + req->key_len), total,
|
||||
+ (ttl == INT32_MAX
|
||||
+ ? db->negtimeout : ttl));
|
||||
|
||||
/* This is the reply. */
|
||||
memcpy (&dataset->resp, resp, total);
|
||||
@@ -257,15 +253,10 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
|
||||
alloca_used = true;
|
||||
}
|
||||
|
||||
- dataset->head.allocsize = total + req->key_len;
|
||||
- dataset->head.recsize = total - offsetof (struct dataset, resp);
|
||||
- dataset->head.notfound = false;
|
||||
- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
|
||||
- dataset->head.usable = true;
|
||||
-
|
||||
- /* Compute the timeout time. */
|
||||
- dataset->head.ttl = ttl == INT32_MAX ? db->postimeout : ttl;
|
||||
- timeout = dataset->head.timeout = t + dataset->head.ttl;
|
||||
+ timeout = datahead_init_pos (&dataset->head, total + req->key_len,
|
||||
+ total - offsetof (struct dataset, resp),
|
||||
+ he == NULL ? 0 : dh->nreloads + 1,
|
||||
+ ttl == INT32_MAX ? db->postimeout : ttl);
|
||||
|
||||
dataset->resp.version = NSCD_VERSION;
|
||||
dataset->resp.found = 1;
|
||||
diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
|
||||
index 1bf9f0d..361319f 100644
|
||||
--- a/nscd/initgrcache.c
|
||||
+++ b/nscd/initgrcache.c
|
||||
@@ -213,14 +213,10 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
|
||||
else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
|
||||
+ req->key_len), 1)) != NULL)
|
||||
{
|
||||
- dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
|
||||
- dataset->head.recsize = total;
|
||||
- dataset->head.notfound = true;
|
||||
- dataset->head.nreloads = 0;
|
||||
- dataset->head.usable = true;
|
||||
-
|
||||
- /* Compute the timeout time. */
|
||||
- timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
|
||||
+ timeout = datahead_init_neg (&dataset->head,
|
||||
+ (sizeof (struct dataset)
|
||||
+ + req->key_len), total,
|
||||
+ db->negtimeout);
|
||||
|
||||
/* This is the reply. */
|
||||
memcpy (&dataset->resp, ¬found, total);
|
||||
@@ -276,14 +272,10 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
|
||||
alloca_used = true;
|
||||
}
|
||||
|
||||
- dataset->head.allocsize = total + req->key_len;
|
||||
- dataset->head.recsize = total - offsetof (struct dataset, resp);
|
||||
- dataset->head.notfound = false;
|
||||
- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
|
||||
- dataset->head.usable = true;
|
||||
-
|
||||
- /* Compute the timeout time. */
|
||||
- timeout = dataset->head.timeout = time (NULL) + db->postimeout;
|
||||
+ timeout = datahead_init_pos (&dataset->head, total + req->key_len,
|
||||
+ total - offsetof (struct dataset, resp),
|
||||
+ he == NULL ? 0 : dh->nreloads + 1,
|
||||
+ db->postimeout);
|
||||
|
||||
dataset->resp.version = NSCD_VERSION;
|
||||
dataset->resp.found = 1;
|
||||
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
|
||||
index 820d823..b3d40e9 100644
|
||||
--- a/nscd/netgroupcache.c
|
||||
+++ b/nscd/netgroupcache.c
|
||||
@@ -90,15 +90,9 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
|
||||
/* If we cannot permanently store the result, so be it. */
|
||||
if (dataset != NULL)
|
||||
{
|
||||
- dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
|
||||
- dataset->head.recsize = total;
|
||||
- dataset->head.notfound = true;
|
||||
- dataset->head.nreloads = 0;
|
||||
- dataset->head.usable = true;
|
||||
-
|
||||
- /* Compute the timeout time. */
|
||||
- timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
|
||||
- dataset->head.ttl = db->negtimeout;
|
||||
+ timeout = datahead_init_neg (&dataset->head,
|
||||
+ sizeof (struct dataset) + req->key_len,
|
||||
+ total, db->negtimeout);
|
||||
|
||||
/* This is the reply. */
|
||||
memcpy (&dataset->resp, ¬found, total);
|
||||
@@ -359,13 +353,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
|
||||
/* Fill in the dataset. */
|
||||
dataset = (struct dataset *) buffer;
|
||||
- dataset->head.allocsize = total + req->key_len;
|
||||
- dataset->head.recsize = total - offsetof (struct dataset, resp);
|
||||
- dataset->head.notfound = false;
|
||||
- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
|
||||
- dataset->head.usable = true;
|
||||
- dataset->head.ttl = db->postimeout;
|
||||
- timeout = dataset->head.timeout = time (NULL) + dataset->head.ttl;
|
||||
+ timeout = datahead_init_pos (&dataset->head, total + req->key_len,
|
||||
+ total - offsetof (struct dataset, resp),
|
||||
+ he == NULL ? 0 : dh->nreloads + 1,
|
||||
+ db->postimeout);
|
||||
|
||||
dataset->resp.version = NSCD_VERSION;
|
||||
dataset->resp.found = 1;
|
||||
@@ -541,12 +532,12 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
|
||||
dataset = &dataset_mem;
|
||||
}
|
||||
|
||||
- dataset->head.allocsize = sizeof (*dataset) + req->key_len;
|
||||
- dataset->head.recsize = sizeof (innetgroup_response_header);
|
||||
+ datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len,
|
||||
+ sizeof (innetgroup_response_header),
|
||||
+ he == NULL ? 0 : dh->nreloads + 1, result->head.ttl);
|
||||
+ /* Set the notfound status and timeout based on the result from
|
||||
+ getnetgrent. */
|
||||
dataset->head.notfound = result->head.notfound;
|
||||
- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
|
||||
- dataset->head.usable = true;
|
||||
- dataset->head.ttl = result->head.ttl;
|
||||
dataset->head.timeout = timeout;
|
||||
|
||||
dataset->resp.version = NSCD_VERSION;
|
||||
diff --git a/nscd/nscd-client.h b/nscd/nscd-client.h
|
||||
index 98f77e7..ee16df6 100644
|
||||
--- a/nscd/nscd-client.h
|
||||
+++ b/nscd/nscd-client.h
|
||||
@@ -236,6 +236,48 @@ struct datahead
|
||||
} data[0];
|
||||
};
|
||||
|
||||
+static inline time_t
|
||||
+datahead_init_common (struct datahead *head, nscd_ssize_t allocsize,
|
||||
+ nscd_ssize_t recsize, uint32_t ttl)
|
||||
+{
|
||||
+ /* Initialize so that we don't write out junk in uninitialized data to the
|
||||
+ cache. */
|
||||
+ memset (head, 0, sizeof (*head));
|
||||
+
|
||||
+ head->allocsize = allocsize;
|
||||
+ head->recsize = recsize;
|
||||
+ head->usable = true;
|
||||
+
|
||||
+ head->ttl = ttl;
|
||||
+
|
||||
+ /* Compute and return the timeout time. */
|
||||
+ return head->timeout = time (NULL) + ttl;
|
||||
+}
|
||||
+
|
||||
+static inline time_t
|
||||
+datahead_init_pos (struct datahead *head, nscd_ssize_t allocsize,
|
||||
+ nscd_ssize_t recsize, uint8_t nreloads, uint32_t ttl)
|
||||
+{
|
||||
+ time_t ret = datahead_init_common (head, allocsize, recsize, ttl);
|
||||
+
|
||||
+ head->notfound = false;
|
||||
+ head->nreloads = nreloads;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static inline time_t
|
||||
+datahead_init_neg (struct datahead *head, nscd_ssize_t allocsize,
|
||||
+ nscd_ssize_t recsize, uint32_t ttl)
|
||||
+{
|
||||
+ time_t ret = datahead_init_common (head, allocsize, recsize, ttl);
|
||||
+
|
||||
+ /* We don't need to touch nreloads here since it is set to our desired value
|
||||
+ (0) when we clear the structure. */
|
||||
+ head->notfound = true;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
|
||||
/* Structure for one hash table entry. */
|
||||
struct hashentry
|
||||
diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
|
||||
index fa355c3..41c245b 100644
|
||||
--- a/nscd/pwdcache.c
|
||||
+++ b/nscd/pwdcache.c
|
||||
@@ -135,14 +135,10 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
|
||||
else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
|
||||
+ req->key_len), 1)) != NULL)
|
||||
{
|
||||
- dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
|
||||
- dataset->head.recsize = total;
|
||||
- dataset->head.notfound = true;
|
||||
- dataset->head.nreloads = 0;
|
||||
- dataset->head.usable = true;
|
||||
-
|
||||
- /* Compute the timeout time. */
|
||||
- timeout = dataset->head.timeout = t + db->negtimeout;
|
||||
+ timeout = datahead_init_neg (&dataset->head,
|
||||
+ (sizeof (struct dataset)
|
||||
+ + req->key_len), total,
|
||||
+ db->negtimeout);
|
||||
|
||||
/* This is the reply. */
|
||||
memcpy (&dataset->resp, ¬found, total);
|
||||
@@ -215,14 +211,10 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
|
||||
alloca_used = true;
|
||||
}
|
||||
|
||||
- dataset->head.allocsize = total + n;
|
||||
- dataset->head.recsize = total - offsetof (struct dataset, resp);
|
||||
- dataset->head.notfound = false;
|
||||
- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
|
||||
- dataset->head.usable = true;
|
||||
-
|
||||
- /* Compute the timeout time. */
|
||||
- timeout = dataset->head.timeout = t + db->postimeout;
|
||||
+ timeout = datahead_init_pos (&dataset->head, total + n,
|
||||
+ total - offsetof (struct dataset, resp),
|
||||
+ he == NULL ? 0 : dh->nreloads + 1,
|
||||
+ db->postimeout);
|
||||
|
||||
dataset->resp.version = NSCD_VERSION;
|
||||
dataset->resp.found = 1;
|
||||
diff --git a/nscd/servicescache.c b/nscd/servicescache.c
|
||||
index 12ce9b2..95bdcfe 100644
|
||||
--- a/nscd/servicescache.c
|
||||
+++ b/nscd/servicescache.c
|
||||
@@ -120,14 +120,10 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
|
||||
else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
|
||||
+ req->key_len), 1)) != NULL)
|
||||
{
|
||||
- dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
|
||||
- dataset->head.recsize = total;
|
||||
- dataset->head.notfound = true;
|
||||
- dataset->head.nreloads = 0;
|
||||
- dataset->head.usable = true;
|
||||
-
|
||||
- /* Compute the timeout time. */
|
||||
- timeout = dataset->head.timeout = t + db->negtimeout;
|
||||
+ timeout = datahead_init_neg (&dataset->head,
|
||||
+ (sizeof (struct dataset)
|
||||
+ + req->key_len), total,
|
||||
+ db->negtimeout);
|
||||
|
||||
/* This is the reply. */
|
||||
memcpy (&dataset->resp, ¬found, total);
|
||||
@@ -207,14 +203,10 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
|
||||
alloca_used = true;
|
||||
}
|
||||
|
||||
- dataset->head.allocsize = total + req->key_len;
|
||||
- dataset->head.recsize = total - offsetof (struct dataset, resp);
|
||||
- dataset->head.notfound = false;
|
||||
- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
|
||||
- dataset->head.usable = true;
|
||||
-
|
||||
- /* Compute the timeout time. */
|
||||
- timeout = dataset->head.timeout = t + db->postimeout;
|
||||
+ timeout = datahead_init_pos (&dataset->head, total + req->key_len,
|
||||
+ total - offsetof (struct dataset, resp),
|
||||
+ he == NULL ? 0 : dh->nreloads + 1,
|
||||
+ db->postimeout);
|
||||
|
||||
dataset->resp.version = NSCD_VERSION;
|
||||
dataset->resp.found = 1;
|
||||
@@ -1,63 +0,0 @@
|
||||
commit ea7d8b95e2fcb81f68b04ed7787a3dbda023991a
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Thu Mar 27 19:48:15 2014 +0530
|
||||
|
||||
Avoid overlapping addresses to stpcpy calls in nscd (BZ #16760)
|
||||
|
||||
Calls to stpcpy from nscd netgroups code will have overlapping source
|
||||
and destination when all three values in the returned triplet are
|
||||
non-NULL and in the expected (host,user,domain) order. This is seen
|
||||
in valgrind as:
|
||||
|
||||
==3181== Source and destination overlap in stpcpy(0x19973b48, 0x19973b48)
|
||||
==3181== at 0x4C2F30A: stpcpy (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
|
||||
==3181== by 0x12567A: addgetnetgrentX (string3.h:111)
|
||||
==3181== by 0x12722D: addgetnetgrent (netgroupcache.c:665)
|
||||
==3181== by 0x11114C: nscd_run_worker (connections.c:1338)
|
||||
==3181== by 0x4E3C102: start_thread (pthread_create.c:309)
|
||||
==3181== by 0x59B81AC: clone (clone.S:111)
|
||||
==3181==
|
||||
|
||||
Fix this by using memmove instead of stpcpy.
|
||||
|
||||
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
|
||||
index 5d15aa4..820d823 100644
|
||||
--- a/nscd/netgroupcache.c
|
||||
+++ b/nscd/netgroupcache.c
|
||||
@@ -216,6 +216,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
const char *nuser = data.val.triple.user;
|
||||
const char *ndomain = data.val.triple.domain;
|
||||
|
||||
+ size_t hostlen = strlen (nhost ?: "") + 1;
|
||||
+ size_t userlen = strlen (nuser ?: "") + 1;
|
||||
+ size_t domainlen = strlen (ndomain ?: "") + 1;
|
||||
+
|
||||
if (nhost == NULL || nuser == NULL || ndomain == NULL
|
||||
|| nhost > nuser || nuser > ndomain)
|
||||
{
|
||||
@@ -233,9 +237,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
: last + strlen (last) + 1 - buffer);
|
||||
|
||||
/* We have to make temporary copies. */
|
||||
- size_t hostlen = strlen (nhost ?: "") + 1;
|
||||
- size_t userlen = strlen (nuser ?: "") + 1;
|
||||
- size_t domainlen = strlen (ndomain ?: "") + 1;
|
||||
size_t needed = hostlen + userlen + domainlen;
|
||||
|
||||
if (buflen - req->key_len - bufused < needed)
|
||||
@@ -269,9 +270,12 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
}
|
||||
|
||||
char *wp = buffer + buffilled;
|
||||
- wp = stpcpy (wp, nhost) + 1;
|
||||
- wp = stpcpy (wp, nuser) + 1;
|
||||
- wp = stpcpy (wp, ndomain) + 1;
|
||||
+ wp = memmove (wp, nhost ?: "", hostlen);
|
||||
+ wp += hostlen;
|
||||
+ wp = memmove (wp, nuser ?: "", userlen);
|
||||
+ wp += userlen;
|
||||
+ wp = memmove (wp, ndomain ?: "", domainlen);
|
||||
+ wp += domainlen;
|
||||
buffilled = wp - buffer;
|
||||
++nentries;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
commit d41242129ba693cdbc8db85b846fcaccf9f0b7c4
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Thu Jan 2 10:03:12 2014 +0530
|
||||
|
||||
Fix infinite loop in nscd when netgroup is empty (bz #16365)
|
||||
|
||||
Currently, when a user looks up a netgroup that does not have any
|
||||
members, nscd goes into an infinite loop trying to find members in the
|
||||
group. This is because it does not handle cases when getnetgrent
|
||||
returns an NSS_STATUS_NOTFOUND (which is what it does on empty group).
|
||||
Fixed to handle this in the same way as NSS_STATUS_RETURN, similar to
|
||||
what getgrent does by itself.
|
||||
|
||||
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
|
||||
index baebdd7..50936ee 100644
|
||||
--- a/nscd/netgroupcache.c
|
||||
+++ b/nscd/netgroupcache.c
|
||||
@@ -180,9 +180,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
int e;
|
||||
status = getfct.f (&data, buffer + buffilled,
|
||||
buflen - buffilled, &e);
|
||||
- if (status == NSS_STATUS_RETURN)
|
||||
- /* This was the last one for this group. Look
|
||||
- at next group if available. */
|
||||
+ if (status == NSS_STATUS_RETURN
|
||||
+ || status == NSS_STATUS_NOTFOUND)
|
||||
+ /* This was either the last one for this group or the
|
||||
+ group was empty. Look at next group if available. */
|
||||
break;
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
{
|
||||
@@ -1,60 +0,0 @@
|
||||
commit dd3022d75e6fb8957843d6d84257a5d8457822d5
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Thu Mar 27 19:49:51 2014 +0530
|
||||
|
||||
Return NULL for wildcard values in getnetgrent from nscd (BZ #16759)
|
||||
|
||||
getnetgrent is supposed to return NULL for values that are wildcards
|
||||
in the (host, user, domain) triplet. This works correctly with nscd
|
||||
disabled, but with it enabled, it returns a blank ("") instead of a
|
||||
NULL. This is easily seen with the output of `getent netgroup foonet`
|
||||
for a netgroup foonet defined as follows in /etc/netgroup:
|
||||
|
||||
foonet (,foo,)
|
||||
|
||||
The output with nscd disabled is:
|
||||
|
||||
foonet ( ,foo,)
|
||||
|
||||
while with nscd enabled, it is:
|
||||
|
||||
foonet (,foo,)
|
||||
|
||||
The extra space with nscd disabled is due to the fact that `getent
|
||||
netgroup` adds it if the return value from getnetgrent is NULL for
|
||||
either host or user.
|
||||
|
||||
diff --git a/inet/getnetgrent_r.c b/inet/getnetgrent_r.c
|
||||
index 62cdfda..f6d064d 100644
|
||||
--- a/inet/getnetgrent_r.c
|
||||
+++ b/inet/getnetgrent_r.c
|
||||
@@ -235,6 +235,14 @@ endnetgrent (void)
|
||||
libc_hidden_proto (internal_getnetgrent_r)
|
||||
|
||||
|
||||
+static const char *
|
||||
+get_nonempty_val (const char *in)
|
||||
+{
|
||||
+ if (*in == '\0')
|
||||
+ return NULL;
|
||||
+ return in;
|
||||
+}
|
||||
+
|
||||
static enum nss_status
|
||||
nscd_getnetgrent (struct __netgrent *datap, char *buffer, size_t buflen,
|
||||
int *errnop)
|
||||
@@ -243,11 +251,11 @@ nscd_getnetgrent (struct __netgrent *datap, char *buffer, size_t buflen,
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
datap->type = triple_val;
|
||||
- datap->val.triple.host = datap->cursor;
|
||||
+ datap->val.triple.host = get_nonempty_val (datap->cursor);
|
||||
datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1;
|
||||
- datap->val.triple.user = datap->cursor;
|
||||
+ datap->val.triple.user = get_nonempty_val (datap->cursor);
|
||||
datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1;
|
||||
- datap->val.triple.domain = datap->cursor;
|
||||
+ datap->val.triple.domain = get_nonempty_val (datap->cursor);
|
||||
datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
@@ -1,34 +0,0 @@
|
||||
commit 58b930ae216bfa98cd60212b954b07b9963d6d04
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Wed Sep 10 21:51:50 2014 +0530
|
||||
|
||||
Return failure in getnetgrent only when all netgroups have been searched (#17363)
|
||||
|
||||
The netgroups lookup code fails when one of the groups in the search
|
||||
tree is empty. In such a case it only returns the leaves of the tree
|
||||
after the blank netgroup. This is because the line parser returns a
|
||||
NOTFOUND status when the netgroup exists but is empty. The
|
||||
__getnetgrent_internal implementation needs to be fixed to try
|
||||
remaining groups if the current group is entry. This patch implements
|
||||
this fix. Tested on x86_64.
|
||||
|
||||
[BZ #17363]
|
||||
* inet/getnetgrent_r.c (__internal_getnetgrent_r): Try next
|
||||
group if the current group is empty.
|
||||
|
||||
diff --git a/inet/getnetgrent_r.c b/inet/getnetgrent_r.c
|
||||
index f6d064d..e101537 100644
|
||||
--- a/inet/getnetgrent_r.c
|
||||
+++ b/inet/getnetgrent_r.c
|
||||
@@ -297,7 +297,10 @@ __internal_getnetgrent_r (char **hostp, char **userp, char **domainp,
|
||||
{
|
||||
status = (*fct) (datap, buffer, buflen, &errno);
|
||||
|
||||
- if (status == NSS_STATUS_RETURN)
|
||||
+ if (status == NSS_STATUS_RETURN
|
||||
+ /* The service returned a NOTFOUND, but there are more groups that we
|
||||
+ need to resolve before we give up. */
|
||||
+ || (status == NSS_STATUS_NOTFOUND && datap->needed_groups != NULL))
|
||||
{
|
||||
/* This was the last one for this group. Look at next group
|
||||
if available. */
|
||||
@@ -1,65 +0,0 @@
|
||||
commit c3ec475c5dd16499aa040908e11d382c3ded9692
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Mon May 26 11:40:08 2014 +0530
|
||||
|
||||
Use NSS_STATUS_TRYAGAIN to indicate insufficient buffer (BZ #16878)
|
||||
|
||||
The netgroups nss modules in the glibc tree use NSS_STATUS_UNAVAIL
|
||||
(with errno as ERANGE) when the supplied buffer does not have
|
||||
sufficient space for the result. This is wrong, because the canonical
|
||||
way to indicate insufficient buffer is to set the errno to ERANGE and
|
||||
the status to NSS_STATUS_TRYAGAIN, as is used by all other modules.
|
||||
|
||||
This fixes nscd behaviour when the nss_ldap module returns
|
||||
NSS_STATUS_TRYAGAIN to indicate that a netgroup entry is too long to
|
||||
fit into the supplied buffer.
|
||||
|
||||
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
|
||||
index b3d40e9..edab174 100644
|
||||
--- a/nscd/netgroupcache.c
|
||||
+++ b/nscd/netgroupcache.c
|
||||
@@ -197,11 +197,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
int e;
|
||||
status = getfct.f (&data, buffer + buffilled,
|
||||
buflen - buffilled - req->key_len, &e);
|
||||
- if (status == NSS_STATUS_RETURN
|
||||
- || status == NSS_STATUS_NOTFOUND)
|
||||
- /* This was either the last one for this group or the
|
||||
- group was empty. Look at next group if available. */
|
||||
- break;
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (data.type == triple_val)
|
||||
@@ -320,11 +315,18 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||
}
|
||||
}
|
||||
}
|
||||
- else if (status == NSS_STATUS_UNAVAIL && e == ERANGE)
|
||||
+ else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
|
||||
{
|
||||
buflen *= 2;
|
||||
buffer = xrealloc (buffer, buflen);
|
||||
}
|
||||
+ else if (status == NSS_STATUS_RETURN
|
||||
+ || status == NSS_STATUS_NOTFOUND
|
||||
+ || status == NSS_STATUS_UNAVAIL)
|
||||
+ /* This was either the last one for this group or the
|
||||
+ group was empty or the NSS module had an internal
|
||||
+ failure. Look at next group if available. */
|
||||
+ break;
|
||||
}
|
||||
|
||||
enum nss_status (*endfct) (struct __netgrent *);
|
||||
diff --git a/nss/nss_files/files-netgrp.c b/nss/nss_files/files-netgrp.c
|
||||
index 34eae4c..bc0b367 100644
|
||||
--- a/nss/nss_files/files-netgrp.c
|
||||
+++ b/nss/nss_files/files-netgrp.c
|
||||
@@ -252,7 +252,7 @@ _nss_netgroup_parseline (char **cursor, struct __netgrent *result,
|
||||
if (cp - host > buflen)
|
||||
{
|
||||
*errnop = ERANGE;
|
||||
- status = NSS_STATUS_UNAVAIL;
|
||||
+ status = NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1,142 +0,0 @@
|
||||
diff --git a/resolv/arpa/nameser.h b/resolv/arpa/nameser.h
|
||||
index fb8513b..372d5cd 100644
|
||||
--- a/resolv/arpa/nameser.h
|
||||
+++ b/resolv/arpa/nameser.h
|
||||
@@ -293,6 +293,9 @@ typedef enum __ns_type {
|
||||
ns_t_sink = 40, /*%< Kitchen sink (experimentatl) */
|
||||
ns_t_opt = 41, /*%< EDNS0 option (meta-RR) */
|
||||
ns_t_apl = 42, /*%< Address prefix list (RFC3123) */
|
||||
+ ns_t_rrsig = 46, /*%< DNSSEC RRset Signature (RFC4034) */
|
||||
+ ns_t_nsec = 47, /*%< DNSSEC Next-Secure Record (RFC4034)*/
|
||||
+ ns_t_dnskey = 48, /*%< DNSSEC key record (RFC4034) */
|
||||
ns_t_tkey = 249, /*%< Transaction key */
|
||||
ns_t_tsig = 250, /*%< Transaction signature. */
|
||||
ns_t_ixfr = 251, /*%< Incremental zone transfer. */
|
||||
diff --git a/resolv/arpa/nameser_compat.h b/resolv/arpa/nameser_compat.h
|
||||
index d59c9e4..284bff7 100644
|
||||
--- a/resolv/arpa/nameser_compat.h
|
||||
+++ b/resolv/arpa/nameser_compat.h
|
||||
@@ -164,6 +164,9 @@ typedef struct {
|
||||
#define T_NAPTR ns_t_naptr
|
||||
#define T_A6 ns_t_a6
|
||||
#define T_DNAME ns_t_dname
|
||||
+#define T_RRSIG ns_t_rrsig
|
||||
+#define T_NSEC ns_t_nsec
|
||||
+#define T_DNSKEY ns_t_dnskey
|
||||
#define T_TSIG ns_t_tsig
|
||||
#define T_IXFR ns_t_ixfr
|
||||
#define T_AXFR ns_t_axfr
|
||||
diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c
|
||||
index a861a84..ae55fac 100644
|
||||
--- a/resolv/gethnamaddr.c
|
||||
+++ b/resolv/gethnamaddr.c
|
||||
@@ -331,23 +331,36 @@ getanswer (const querybuf *answer, int anslen, const char *qname, int qtype)
|
||||
buflen -= n;
|
||||
continue;
|
||||
}
|
||||
- if ((type == T_SIG) || (type == T_KEY) || (type == T_NXT)) {
|
||||
- /* We don't support DNSSEC yet. For now, ignore
|
||||
- * the record and send a low priority message
|
||||
- * to syslog.
|
||||
- */
|
||||
- syslog(LOG_DEBUG|LOG_AUTH,
|
||||
+ if ((type == T_SIG) || (type == T_KEY) || (type == T_NXT)
|
||||
+ || (type == T_RRSIG) || (type == T_NSEC)
|
||||
+ || (type == T_DNSKEY)) {
|
||||
+ /* We don't support DNSSEC responses yet, but we do
|
||||
+ * allow setting the DO bit. If the DNS server sent us
|
||||
+ * these records without us asking for it, ignore the
|
||||
+ * record and send a low priority message to syslog.
|
||||
+ */
|
||||
+ if ((_res.options & RES_USE_DNSSEC) == 0) {
|
||||
+ syslog(LOG_DEBUG|LOG_AUTH,
|
||||
"gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
|
||||
- qname, p_class(C_IN), p_type(qtype),
|
||||
- p_type(type));
|
||||
+ qname, p_class(C_IN), p_type(qtype),
|
||||
+ p_type(type));
|
||||
+ }
|
||||
cp += n;
|
||||
continue;
|
||||
}
|
||||
if (type != qtype) {
|
||||
- syslog(LOG_NOTICE|LOG_AUTH,
|
||||
+ /* Skip logging if we received a DNAME when we have set
|
||||
+ * the DO bit. DNAME records are a convenient way to
|
||||
+ * set up DNSSEC records and such setups can make this
|
||||
+ * log message needlessly noisy.
|
||||
+ */
|
||||
+ if (!((_res.options & RES_USE_DNSSEC)
|
||||
+ && type == T_DNAME)) {
|
||||
+ syslog(LOG_NOTICE|LOG_AUTH,
|
||||
"gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
|
||||
- qname, p_class(C_IN), p_type(qtype),
|
||||
- p_type(type));
|
||||
+ qname, p_class(C_IN), p_type(qtype),
|
||||
+ p_type(type));
|
||||
+ }
|
||||
cp += n;
|
||||
continue; /* XXX - had_error++ ? */
|
||||
}
|
||||
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
|
||||
index f715ab0..510d388 100644
|
||||
--- a/resolv/nss_dns/dns-host.c
|
||||
+++ b/resolv/nss_dns/dns-host.c
|
||||
@@ -822,13 +822,20 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
}
|
||||
if (__builtin_expect (type == T_SIG, 0)
|
||||
|| __builtin_expect (type == T_KEY, 0)
|
||||
- || __builtin_expect (type == T_NXT, 0))
|
||||
+ || __builtin_expect (type == T_NXT, 0)
|
||||
+ || __builtin_expect (type == T_RRSIG, 0)
|
||||
+ || __builtin_expect (type == T_NSEC, 0)
|
||||
+ || __builtin_expect (type == T_DNSKEY, 0))
|
||||
{
|
||||
- /* We don't support DNSSEC yet. For now, ignore the record
|
||||
- and send a low priority message to syslog. */
|
||||
- syslog (LOG_DEBUG | LOG_AUTH,
|
||||
- "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
|
||||
- qname, p_class (C_IN), p_type(qtype), p_type (type));
|
||||
+ /* We don't support DNSSEC responses yet, but we do allow setting the
|
||||
+ DO bit. If the DNS server sent us these records without us asking
|
||||
+ for it, ignore the record and send a low priority message to
|
||||
+ syslog. */
|
||||
+ if ((_res.options & RES_USE_DNSSEC) == 0)
|
||||
+ syslog (LOG_DEBUG | LOG_AUTH,
|
||||
+ "gethostby*.getanswer: asked for \"%s %s %s\", "
|
||||
+ "got type \"%s\"",
|
||||
+ qname, p_class (C_IN), p_type(qtype), p_type (type));
|
||||
cp += n;
|
||||
continue;
|
||||
}
|
||||
@@ -837,9 +844,14 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
have_to_map = 1;
|
||||
else if (__builtin_expect (type != qtype, 0))
|
||||
{
|
||||
- syslog (LOG_NOTICE | LOG_AUTH,
|
||||
- "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
|
||||
- qname, p_class (C_IN), p_type (qtype), p_type (type));
|
||||
+ /* Skip logging if we received a DNAME when we have set the DO bit.
|
||||
+ DNAME records are a convenient way to set up DNSSEC records and
|
||||
+ such setups can make this log message needlessly noisy. */
|
||||
+ if (!((_res.options & RES_USE_DNSSEC) && type == T_DNAME))
|
||||
+ syslog (LOG_NOTICE | LOG_AUTH,
|
||||
+ "gethostby*.getanswer: asked for \"%s %s %s\", "
|
||||
+ "got type \"%s\"",
|
||||
+ qname, p_class (C_IN), p_type (qtype), p_type (type));
|
||||
cp += n;
|
||||
continue; /* XXX - had_error++ ? */
|
||||
}
|
||||
diff --git a/resolv/res_debug.c b/resolv/res_debug.c
|
||||
index 7843439..4a49629 100644
|
||||
--- a/resolv/res_debug.c
|
||||
+++ b/resolv/res_debug.c
|
||||
@@ -450,6 +450,8 @@ const struct res_sym __p_type_syms[] = {
|
||||
{ns_t_kx, "KX", "Key Exchange"},
|
||||
{ns_t_cert, "CERT", "Certificate"},
|
||||
{ns_t_any, "ANY", "\"any\""},
|
||||
+ /* TODO Add RRSIG, NSEC and DNSKEY once we actually do something with
|
||||
+ them. */
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
libresolv_hidden_data_def (__p_type_syms)
|
||||
@@ -1,40 +0,0 @@
|
||||
commit 3cb26316b45b23dc5cfecbafdc489b28c3a52029
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Thu Jan 29 10:30:09 2015 +0530
|
||||
|
||||
Initialize nscd stats data [BZ #17892]
|
||||
|
||||
The padding bytes in the statsdata struct are not initialized, due to
|
||||
which valgrind throws a warning:
|
||||
|
||||
==11384== Memcheck, a memory error detector
|
||||
==11384== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
|
||||
==11384== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
|
||||
==11384== Command: nscd -d
|
||||
==11384==
|
||||
Fri 25 Apr 2014 10:34:53 AM CEST - 11384: handle_request: request received (Version = 2) from PID 11396
|
||||
Fri 25 Apr 2014 10:34:53 AM CEST - 11384: GETSTAT
|
||||
==11384== Thread 6:
|
||||
==11384== Syscall param socketcall.sendto(msg) points to uninitialised byte(s)
|
||||
==11384== at 0x4E4ACDC: send (in /lib64/libpthread-2.12.so)
|
||||
==11384== by 0x11AF6B: send_stats (in /usr/sbin/nscd)
|
||||
==11384== by 0x112F75: nscd_run_worker (in /usr/sbin/nscd)
|
||||
==11384== by 0x4E439D0: start_thread (in /lib64/libpthread-2.12.so)
|
||||
==11384== by 0x599AB6C: clone (in /lib64/libc-2.12.so)
|
||||
==11384== Address 0x15708395 is on thread 6's stack
|
||||
|
||||
Fix the warning by initializing the structure.
|
||||
|
||||
diff --git a/nscd/nscd_stat.c b/nscd/nscd_stat.c
|
||||
index 0f1f3c0..7aaa21b 100644
|
||||
--- a/nscd/nscd_stat.c
|
||||
+++ b/nscd/nscd_stat.c
|
||||
@@ -94,6 +94,8 @@ send_stats (int fd, struct database_dyn dbs[lastdb])
|
||||
struct statdata data;
|
||||
int cnt;
|
||||
|
||||
+ memset (&data, 0, sizeof (data));
|
||||
+
|
||||
memcpy (data.version, compilation, sizeof (compilation));
|
||||
data.debug_level = debug_level;
|
||||
data.runtime = time (NULL) - start_time;
|
||||
@@ -1,159 +0,0 @@
|
||||
commit d6c33fda03457ca8ca87a562fa2681af16ca4ea5
|
||||
Author: Roland McGrath <roland@hack.frob.com>
|
||||
Date: Thu May 24 11:37:30 2012 -0700
|
||||
|
||||
Switch gettimeofday from INTUSE to libc_hidden_proto.
|
||||
|
||||
diff --git a/include/sys/time.h b/include/sys/time.h
|
||||
index d5de942..599e189 100644
|
||||
--- a/include/sys/time.h
|
||||
+++ b/include/sys/time.h
|
||||
@@ -4,9 +4,8 @@
|
||||
/* Now document the internal interfaces. */
|
||||
extern int __gettimeofday (struct timeval *__tv,
|
||||
struct timezone *__tz);
|
||||
-extern int __gettimeofday_internal (struct timeval *__tv,
|
||||
- struct timezone *__tz)
|
||||
- attribute_hidden;
|
||||
+libc_hidden_proto (__gettimeofday)
|
||||
+libc_hidden_proto (gettimeofday)
|
||||
extern int __settimeofday (__const struct timeval *__tv,
|
||||
__const struct timezone *__tz)
|
||||
attribute_hidden;
|
||||
@@ -22,8 +21,4 @@ extern int __utimes (const char *__file, const struct timeval __tvp[2])
|
||||
attribute_hidden;
|
||||
extern int __futimes (int fd, __const struct timeval tvp[2]) attribute_hidden;
|
||||
|
||||
-#ifndef NOT_IN_libc
|
||||
-# define __gettimeofday(tv, tz) INTUSE(__gettimeofday) (tv, tz)
|
||||
-#endif
|
||||
-
|
||||
#endif
|
||||
diff --git a/sysdeps/mach/gettimeofday.c b/sysdeps/mach/gettimeofday.c
|
||||
index 88dca8e..293a775 100644
|
||||
--- a/sysdeps/mach/gettimeofday.c
|
||||
+++ b/sysdeps/mach/gettimeofday.c
|
||||
@@ -20,8 +20,6 @@
|
||||
#include <sys/time.h>
|
||||
#include <mach.h>
|
||||
|
||||
-#undef __gettimeofday
|
||||
-
|
||||
/* Get the current time of day and timezone information,
|
||||
putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
|
||||
Returns 0 on success, -1 on errors. */
|
||||
@@ -42,6 +40,6 @@ __gettimeofday (tv, tz)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
-
|
||||
-INTDEF(__gettimeofday)
|
||||
+libc_hidden_def (__gettimeofday)
|
||||
weak_alias (__gettimeofday, gettimeofday)
|
||||
+libc_hidden_weak (gettimeofday)
|
||||
diff --git a/sysdeps/posix/gettimeofday.c b/sysdeps/posix/gettimeofday.c
|
||||
index 31b3dd3..1108ff0 100644
|
||||
--- a/sysdeps/posix/gettimeofday.c
|
||||
+++ b/sysdeps/posix/gettimeofday.c
|
||||
@@ -19,8 +19,6 @@
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
-#undef __gettimeofday
|
||||
-
|
||||
/* Get the current time of day and timezone information,
|
||||
putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
|
||||
Returns 0 on success, -1 on errors. */
|
||||
@@ -66,6 +64,6 @@ __gettimeofday (tv, tz)
|
||||
|
||||
return 0;
|
||||
}
|
||||
-
|
||||
-INTDEF(__gettimeofday)
|
||||
+libc_hidden_def (__gettimeofday)
|
||||
weak_alias (__gettimeofday, gettimeofday)
|
||||
+libc_hidden_weak (gettimeofday)
|
||||
diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list
|
||||
index 39c40ed..bd780f5 100644
|
||||
--- a/sysdeps/unix/common/syscalls.list
|
||||
+++ b/sysdeps/unix/common/syscalls.list
|
||||
@@ -5,7 +5,7 @@ getpid - getpid Ei: __getpid getpid
|
||||
fchown - fchown i:iii __fchown fchown
|
||||
ftruncate - ftruncate i:ii __ftruncate ftruncate
|
||||
getrusage - getrusage i:ip __getrusage getrusage
|
||||
-gettimeofday - gettimeofday i:PP __gettimeofday gettimeofday __gettimeofday_internal
|
||||
+gettimeofday - gettimeofday i:pP __gettimeofday gettimeofday
|
||||
settimeofday - settimeofday i:PP __settimeofday settimeofday
|
||||
setpgid - setpgrp i:ii __setpgid setpgid
|
||||
setregid - setregid i:ii __setregid setregid
|
||||
diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
|
||||
index b2ef2da..7376135 100644
|
||||
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
|
||||
@@ -35,5 +35,6 @@ __gettimeofday (tv, tz)
|
||||
}
|
||||
-
|
||||
-#endif
|
||||
-INTDEF (__gettimeofday)
|
||||
+libc_hidden_def (__gettimeofday)
|
||||
+
|
||||
+#endif
|
||||
weak_alias (__gettimeofday, gettimeofday)
|
||||
+libc_hidden_weak (gettimeofday)
|
||||
diff --git a/sysdeps/unix/sysv/linux/s390/gettimeofday.c b/sysdeps/unix/sysv/linux/s390/gettimeofday.c
|
||||
index 63faef8..efbf1e8 100644
|
||||
--- a/sysdeps/unix/sysv/linux/s390/gettimeofday.c
|
||||
+++ b/sysdeps/unix/sysv/linux/s390/gettimeofday.c
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <time.h>
|
||||
#include <hp-timing.h>
|
||||
|
||||
-#undef __gettimeofday
|
||||
#include <bits/libc-vdso.h>
|
||||
|
||||
/* Get the current time of day and timezone information,
|
||||
@@ -36,6 +35,6 @@ __gettimeofday (tv, tz)
|
||||
{
|
||||
return INLINE_VSYSCALL (gettimeofday, 2, CHECK_1 (tv), CHECK_1 (tz));
|
||||
}
|
||||
-
|
||||
-INTDEF (__gettimeofday)
|
||||
+libc_hidden_def (__gettimeofday)
|
||||
weak_alias (__gettimeofday, gettimeofday)
|
||||
+libc_hidden_weak (gettimeofday)
|
||||
diff --git a/time/gettimeofday.c b/time/gettimeofday.c
|
||||
index cfe6549..7eb770c 100644
|
||||
--- a/time/gettimeofday.c
|
||||
+++ b/time/gettimeofday.c
|
||||
@@ -18,8 +18,6 @@
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
-#undef __gettimeofday
|
||||
-
|
||||
/* Get the current time of day and timezone information,
|
||||
putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
|
||||
Returns 0 on success, -1 on errors. */
|
||||
@@ -31,8 +29,9 @@ __gettimeofday (tv, tz)
|
||||
__set_errno (ENOSYS);
|
||||
return -1;
|
||||
}
|
||||
-stub_warning (gettimeofday)
|
||||
-
|
||||
-INTDEF(__gettimeofday)
|
||||
+libc_hidden_def (__gettimeofday)
|
||||
weak_alias (__gettimeofday, gettimeofday)
|
||||
+libc_hidden_weak (gettimeofday)
|
||||
+
|
||||
+stub_warning (gettimeofday)
|
||||
#include <stub-tag.h>
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S 2014-07-28 14:40:24.640144825 +0530
|
||||
+++ b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S 2014-07-28 14:40:21.320120072 +0530
|
||||
@@ -45,5 +45,6 @@
|
||||
ret
|
||||
PSEUDO_END(__gettimeofday)
|
||||
|
||||
-strong_alias (__gettimeofday, __gettimeofday_internal)
|
||||
+libc_hidden_def (__gettimeofday)
|
||||
weak_alias (__gettimeofday, gettimeofday)
|
||||
+libc_hidden_weak (gettimeofday)
|
||||
@@ -1,47 +0,0 @@
|
||||
commit 736c304a1ab4cee36a2f3343f1698bc0abae4608
|
||||
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
|
||||
Date: Thu Jan 16 06:53:18 2014 -0600
|
||||
|
||||
PowerPC: Fix ftime gettimeofday internal call returning bogus data
|
||||
|
||||
This patches fixes BZ#16430 by setting a different symbol for internal
|
||||
GLIBC calls that points to ifunc resolvers. For PPC32, if the symbol
|
||||
is defined as hidden (which is the case for gettimeofday and time) the
|
||||
compiler will create local branches (symbol@local) and linker will not
|
||||
create PLT calls (required for IFUNC). This will leads to internal symbol
|
||||
calling the IFUNC resolver instead of the resolved symbol.
|
||||
For PPC64 this behavior does not occur because a call to a function in
|
||||
another translation unit might use a different toc pointer thus requiring
|
||||
a PLT call.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
|
||||
index 29a5e08..2085b68 100644
|
||||
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
|
||||
@@ -44,8 +44,24 @@ asm (".type __gettimeofday, %gnu_indirect_function");
|
||||
/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
|
||||
let us do it in C because it doesn't know we're defining __gettimeofday
|
||||
here in this file. */
|
||||
-asm (".globl __GI___gettimeofday\n"
|
||||
- "__GI___gettimeofday = __gettimeofday");
|
||||
+asm (".globl __GI___gettimeofday");
|
||||
+
|
||||
+/* __GI___gettimeofday is defined as hidden and for ppc32 it enables the
|
||||
+ compiler make a local call (symbol@local) for internal GLIBC usage. It
|
||||
+ means the PLT won't be used and the ifunc resolver will be called directly.
|
||||
+ For ppc64 a call to a function in another translation unit might use a
|
||||
+ different toc pointer thus disallowing direct branchess and making internal
|
||||
+ ifuncs calls safe. */
|
||||
+#ifdef __powerpc64__
|
||||
+asm ("__GI___gettimeofday = __gettimeofday");
|
||||
+#else
|
||||
+int
|
||||
+__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
|
||||
+{
|
||||
+ return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
|
||||
+}
|
||||
+asm ("__GI___gettimeofday = __gettimeofday_vsyscall");
|
||||
+#endif
|
||||
|
||||
#else
|
||||
|
||||
@@ -1,341 +0,0 @@
|
||||
commit 7cbcdb3699584db8913ca90f705d6337633ee10f
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Fri Oct 25 10:22:12 2013 +0530
|
||||
|
||||
Fix stack overflow due to large AF_INET6 requests
|
||||
|
||||
Resolves #16072 (CVE-2013-4458).
|
||||
|
||||
This patch fixes another stack overflow in getaddrinfo when it is
|
||||
called with AF_INET6. The AF_UNSPEC case was fixed as CVE-2013-1914,
|
||||
but the AF_INET6 case went undetected back then.
|
||||
|
||||
commit 91ce40854d0b7f865cf5024ef95a8026b76096f3
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Aug 16 09:38:52 2013 +0200
|
||||
|
||||
CVE-2013-4237, BZ #14699: Buffer overflow in readdir_r
|
||||
|
||||
* sysdeps/posix/dirstream.h (struct __dirstream): Add errcode
|
||||
member.
|
||||
* sysdeps/posix/opendir.c (__alloc_dir): Initialize errcode
|
||||
member.
|
||||
* sysdeps/posix/rewinddir.c (rewinddir): Reset errcode member.
|
||||
* sysdeps/posix/readdir_r.c (__READDIR_R): Enforce NAME_MAX limit.
|
||||
Return delayed error code. Remove GETDENTS_64BIT_ALIGNED
|
||||
conditional.
|
||||
* sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c: Do not define
|
||||
GETDENTS_64BIT_ALIGNED.
|
||||
* sysdeps/unix/sysv/linux/i386/readdir64_r.c: Likewise.
|
||||
* manual/filesys.texi (Reading/Closing Directory): Document
|
||||
ENAMETOOLONG return value of readdir_r. Recommend readdir more
|
||||
strongly.
|
||||
* manual/conf.texi (Limits for Files): Add portability note to
|
||||
NAME_MAX, PATH_MAX.
|
||||
(Pathconf): Add portability note for _PC_NAME_MAX, _PC_PATH_MAX.
|
||||
|
||||
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||
index e6ce4cf..8ff74b4 100644
|
||||
--- a/sysdeps/posix/getaddrinfo.c
|
||||
+++ b/sysdeps/posix/getaddrinfo.c
|
||||
@@ -197,7 +197,22 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
|
||||
&rc, &herrno, NULL, &localcanon)); \
|
||||
if (rc != ERANGE || herrno != NETDB_INTERNAL) \
|
||||
break; \
|
||||
- tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
|
||||
+ if (!malloc_tmpbuf && __libc_use_alloca (alloca_used + 2 * tmpbuflen)) \
|
||||
+ tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen, 2 * tmpbuflen, \
|
||||
+ alloca_used); \
|
||||
+ else \
|
||||
+ { \
|
||||
+ char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL, \
|
||||
+ 2 * tmpbuflen); \
|
||||
+ if (newp == NULL) \
|
||||
+ { \
|
||||
+ result = -EAI_MEMORY; \
|
||||
+ goto free_and_return; \
|
||||
+ } \
|
||||
+ tmpbuf = newp; \
|
||||
+ malloc_tmpbuf = true; \
|
||||
+ tmpbuflen = 2 * tmpbuflen; \
|
||||
+ } \
|
||||
} \
|
||||
if (status == NSS_STATUS_SUCCESS && rc == 0) \
|
||||
h = &th; \
|
||||
@@ -209,7 +224,8 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
|
||||
{ \
|
||||
__set_h_errno (herrno); \
|
||||
_res.options = old_res_options; \
|
||||
- return -EAI_SYSTEM; \
|
||||
+ result = -EAI_SYSTEM; \
|
||||
+ goto free_and_return; \
|
||||
} \
|
||||
if (herrno == TRY_AGAIN) \
|
||||
no_data = EAI_AGAIN; \
|
||||
|
||||
diff --git a/manual/conf.texi b/manual/conf.texi
|
||||
index 7eb8b36..c720063 100644
|
||||
--- a/manual/conf.texi
|
||||
+++ b/manual/conf.texi
|
||||
@@ -1149,6 +1149,9 @@ typed ahead as input. @xref{I/O Queues}.
|
||||
@comment POSIX.1
|
||||
@deftypevr Macro int NAME_MAX
|
||||
The uniform system limit (if any) for the length of a file name component.
|
||||
+
|
||||
+@strong{Portability Note:} On some systems, the GNU C Library defines
|
||||
+@code{NAME_MAX}, but does not actually enforce this limit.
|
||||
@end deftypevr
|
||||
|
||||
@comment limits.h
|
||||
@@ -1157,6 +1160,9 @@ including the terminating null character.
|
||||
@deftypevr Macro int PATH_MAX
|
||||
The uniform system limit (if any) for the length of an entire file name (that
|
||||
is, the argument given to system calls such as @code{open}).
|
||||
+
|
||||
+@strong{Portability Note:} The GNU C Library does not enforce this limit
|
||||
+even if @code{PATH_MAX} is defined.
|
||||
@end deftypevr
|
||||
|
||||
@cindex limits, pipe buffer size
|
||||
@@ -1476,6 +1482,9 @@ Inquire about the value of @code{POSIX_REC_MIN_XFER_SIZE}.
|
||||
Inquire about the value of @code{POSIX_REC_XFER_ALIGN}.
|
||||
@end table
|
||||
|
||||
+@strong{Portability Note:} On some systems, the GNU C Library does not
|
||||
+enforce @code{_PC_NAME_MAX} or @code{_PC_PATH_MAX} limits.
|
||||
+
|
||||
@node Utility Limits
|
||||
@section Utility Program Capacity Limits
|
||||
|
||||
diff --git a/manual/filesys.texi b/manual/filesys.texi
|
||||
index 1df9cf2..814c210 100644
|
||||
--- a/manual/filesys.texi
|
||||
+++ b/manual/filesys.texi
|
||||
@@ -444,9 +444,9 @@ symbols are declared in the header file @file{dirent.h}.
|
||||
@comment POSIX.1
|
||||
@deftypefun {struct dirent *} readdir (DIR *@var{dirstream})
|
||||
This function reads the next entry from the directory. It normally
|
||||
-returns a pointer to a structure containing information about the file.
|
||||
-This structure is statically allocated and can be rewritten by a
|
||||
-subsequent call.
|
||||
+returns a pointer to a structure containing information about the
|
||||
+file. This structure is associated with the @var{dirstream} handle
|
||||
+and can be rewritten by a subsequent call.
|
||||
|
||||
@strong{Portability Note:} On some systems @code{readdir} may not
|
||||
return entries for @file{.} and @file{..}, even though these are always
|
||||
@@ -461,19 +461,61 @@ conditions are defined for this function:
|
||||
The @var{dirstream} argument is not valid.
|
||||
@end table
|
||||
|
||||
-@code{readdir} is not thread safe. Multiple threads using
|
||||
-@code{readdir} on the same @var{dirstream} may overwrite the return
|
||||
-value. Use @code{readdir_r} when this is critical.
|
||||
+To distinguish between an end-of-directory condition or an error, you
|
||||
+must set @code{errno} to zero before calling @code{readdir}. To avoid
|
||||
+entering an infinite loop, you should stop reading from the directory
|
||||
+after the first error.
|
||||
+
|
||||
+In POSIX.1-2008, @code{readdir} is not thread-safe. In the GNU C Library
|
||||
+implementation, it is safe to call @code{readdir} concurrently on
|
||||
+different @var{dirstream}s, but multiple threads accessing the same
|
||||
+@var{dirstream} result in undefined behavior. @code{readdir_r} is a
|
||||
+fully thread-safe alternative, but suffers from poor portability (see
|
||||
+below). It is recommended that you use @code{readdir}, with external
|
||||
+locking if multiple threads access the same @var{dirstream}.
|
||||
@end deftypefun
|
||||
|
||||
@comment dirent.h
|
||||
@comment GNU
|
||||
@deftypefun int readdir_r (DIR *@var{dirstream}, struct dirent *@var{entry}, struct dirent **@var{result})
|
||||
-This function is the reentrant version of @code{readdir}. Like
|
||||
-@code{readdir} it returns the next entry from the directory. But to
|
||||
-prevent conflicts between simultaneously running threads the result is
|
||||
-not stored in statically allocated memory. Instead the argument
|
||||
-@var{entry} points to a place to store the result.
|
||||
+This function is a version of @code{readdir} which performs internal
|
||||
+locking. Like @code{readdir} it returns the next entry from the
|
||||
+directory. To prevent conflicts between simultaneously running
|
||||
+threads the result is stored inside the @var{entry} object.
|
||||
+
|
||||
+@strong{Portability Note:} It is recommended to use @code{readdir}
|
||||
+instead of @code{readdir_r} for the following reasons:
|
||||
+
|
||||
+@itemize @bullet
|
||||
+@item
|
||||
+On systems which do not define @code{NAME_MAX}, it may not be possible
|
||||
+to use @code{readdir_r} safely because the caller does not specify the
|
||||
+length of the buffer for the directory entry.
|
||||
+
|
||||
+@item
|
||||
+On some systems, @code{readdir_r} cannot read directory entries with
|
||||
+very long names. If such a name is encountered, the GNU C Library
|
||||
+implementation of @code{readdir_r} returns with an error code of
|
||||
+@code{ENAMETOOLONG} after the final directory entry has been read. On
|
||||
+other systems, @code{readdir_r} may return successfully, but the
|
||||
+@code{d_name} member may not be NUL-terminated or may be truncated.
|
||||
+
|
||||
+@item
|
||||
+POSIX-1.2008 does not guarantee that @code{readdir} is thread-safe,
|
||||
+even when access to the same @var{dirstream} is serialized. But in
|
||||
+current implementations (including the GNU C Library), it is safe to call
|
||||
+@code{readdir} concurrently on different @var{dirstream}s, so there is
|
||||
+no need to use @code{readdir_r} in most multi-threaded programs. In
|
||||
+the rare case that multiple threads need to read from the same
|
||||
+@var{dirstream}, it is still better to use @code{readdir} and external
|
||||
+synchronization.
|
||||
+
|
||||
+@item
|
||||
+It is expected that future versions of POSIX will obsolete
|
||||
+@code{readdir_r} and mandate the level of thread safety for
|
||||
+@code{readdir} which is provided by the GNU C Library and other
|
||||
+implementations today.
|
||||
+@end itemize
|
||||
|
||||
Normally @code{readdir_r} returns zero and sets @code{*@var{result}}
|
||||
to @var{entry}. If there are no more entries in the directory or an
|
||||
@@ -481,15 +523,6 @@ error is detected, @code{readdir_r} sets @code{*@var{result}} to a
|
||||
null pointer and returns a nonzero error code, also stored in
|
||||
@code{errno}, as described for @code{readdir}.
|
||||
|
||||
-@strong{Portability Note:} On some systems @code{readdir_r} may not
|
||||
-return a NUL terminated string for the file name, even when there is no
|
||||
-@code{d_reclen} field in @code{struct dirent} and the file
|
||||
-name is the maximum allowed size. Modern systems all have the
|
||||
-@code{d_reclen} field, and on old systems multi-threading is not
|
||||
-critical. In any case there is no such problem with the @code{readdir}
|
||||
-function, so that even on systems without the @code{d_reclen} member one
|
||||
-could use multiple threads by using external locking.
|
||||
-
|
||||
It is also important to look at the definition of the @code{struct
|
||||
dirent} type. Simply passing a pointer to an object of this type for
|
||||
the second parameter of @code{readdir_r} might not be enough. Some
|
||||
diff --git a/sysdeps/unix/dirstream.h b/sysdeps/unix/dirstream.h
|
||||
index a7a074d..8e8570d 100644
|
||||
--- a/sysdeps/unix/dirstream.h
|
||||
+++ b/sysdeps/unix/dirstream.h
|
||||
@@ -39,6 +39,8 @@ struct __dirstream
|
||||
|
||||
off_t filepos; /* Position of next entry to read. */
|
||||
|
||||
+ int errcode; /* Delayed error code. */
|
||||
+
|
||||
/* Directory block. */
|
||||
char data[0] __attribute__ ((aligned (__alignof__ (void*))));
|
||||
};
|
||||
diff --git a/sysdeps/unix/opendir.c b/sysdeps/unix/opendir.c
|
||||
index ddfc3a7..fc05b0f 100644
|
||||
--- a/sysdeps/unix/opendir.c
|
||||
+++ b/sysdeps/unix/opendir.c
|
||||
@@ -231,6 +231,7 @@ __alloc_dir (int fd, bool close_fd, int flags, const struct stat64 *statp)
|
||||
dirp->size = 0;
|
||||
dirp->offset = 0;
|
||||
dirp->filepos = 0;
|
||||
+ dirp->errcode = 0;
|
||||
|
||||
return dirp;
|
||||
}
|
||||
diff --git a/sysdeps/unix/readdir_r.c b/sysdeps/unix/readdir_r.c
|
||||
index b5a8e2e..8ed5c3f 100644
|
||||
--- a/sysdeps/unix/readdir_r.c
|
||||
+++ b/sysdeps/unix/readdir_r.c
|
||||
@@ -40,6 +40,7 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result)
|
||||
DIRENT_TYPE *dp;
|
||||
size_t reclen;
|
||||
const int saved_errno = errno;
|
||||
+ int ret;
|
||||
|
||||
__libc_lock_lock (dirp->lock);
|
||||
|
||||
@@ -70,10 +71,10 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result)
|
||||
bytes = 0;
|
||||
__set_errno (saved_errno);
|
||||
}
|
||||
+ if (bytes < 0)
|
||||
+ dirp->errcode = errno;
|
||||
|
||||
dp = NULL;
|
||||
- /* Reclen != 0 signals that an error occurred. */
|
||||
- reclen = bytes != 0;
|
||||
break;
|
||||
}
|
||||
dirp->size = (size_t) bytes;
|
||||
@@ -106,28 +107,46 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result)
|
||||
dirp->filepos += reclen;
|
||||
#endif
|
||||
|
||||
- /* Skip deleted files. */
|
||||
+#ifdef NAME_MAX
|
||||
+ if (reclen > offsetof (DIRENT_TYPE, d_name) + NAME_MAX + 1)
|
||||
+ {
|
||||
+ /* The record is very long. It could still fit into the
|
||||
+ caller-supplied buffer if we can skip padding at the
|
||||
+ end. */
|
||||
+ size_t namelen = _D_EXACT_NAMLEN (dp);
|
||||
+ if (namelen <= NAME_MAX)
|
||||
+ reclen = offsetof (DIRENT_TYPE, d_name) + namelen + 1;
|
||||
+ else
|
||||
+ {
|
||||
+ /* The name is too long. Ignore this file. */
|
||||
+ dirp->errcode = ENAMETOOLONG;
|
||||
+ dp->d_ino = 0;
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ /* Skip deleted and ignored files. */
|
||||
}
|
||||
while (dp->d_ino == 0);
|
||||
|
||||
if (dp != NULL)
|
||||
{
|
||||
-#ifdef GETDENTS_64BIT_ALIGNED
|
||||
- /* The d_reclen value might include padding which is not part of
|
||||
- the DIRENT_TYPE data structure. */
|
||||
- reclen = MIN (reclen, sizeof (DIRENT_TYPE));
|
||||
-#endif
|
||||
*result = memcpy (entry, dp, reclen);
|
||||
-#ifdef GETDENTS_64BIT_ALIGNED
|
||||
+#ifdef _DIRENT_HAVE_D_RECLEN
|
||||
entry->d_reclen = reclen;
|
||||
#endif
|
||||
+ ret = 0;
|
||||
}
|
||||
else
|
||||
- *result = NULL;
|
||||
+ {
|
||||
+ *result = NULL;
|
||||
+ ret = dirp->errcode;
|
||||
+ }
|
||||
|
||||
__libc_lock_unlock (dirp->lock);
|
||||
|
||||
- return dp != NULL ? 0 : reclen ? errno : 0;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
#ifdef __READDIR_R_ALIAS
|
||||
diff --git a/sysdeps/unix/rewinddir.c b/sysdeps/unix/rewinddir.c
|
||||
index 2935a8e..d4991ad 100644
|
||||
--- a/sysdeps/unix/rewinddir.c
|
||||
+++ b/sysdeps/unix/rewinddir.c
|
||||
@@ -33,5 +33,6 @@ rewinddir (dirp)
|
||||
dirp->filepos = 0;
|
||||
dirp->offset = 0;
|
||||
dirp->size = 0;
|
||||
+ dirp->errcode = 0;
|
||||
__libc_lock_unlock (dirp->lock);
|
||||
}
|
||||
diff --git a/sysdeps/unix/sysv/linux/i386/readdir64_r.c b/sysdeps/unix/sysv/linux/i386/readdir64_r.c
|
||||
index 8ebbcfd..a7d114e 100644
|
||||
--- a/sysdeps/unix/sysv/linux/i386/readdir64_r.c
|
||||
+++ b/sysdeps/unix/sysv/linux/i386/readdir64_r.c
|
||||
@@ -18,7 +18,6 @@
|
||||
#define __READDIR_R __readdir64_r
|
||||
#define __GETDENTS __getdents64
|
||||
#define DIRENT_TYPE struct dirent64
|
||||
-#define GETDENTS_64BIT_ALIGNED 1
|
||||
|
||||
#include <sysdeps/unix/readdir_r.c>
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#
|
||||
# In rhel-6.x the Makerules are not entirely as mature as they are
|
||||
# in glibc 2.21 (from which the example link-libc-args is taken from).
|
||||
# In rhel-6.x the applications are not built like their counterpart
|
||||
# real applications, and because of that compiling DSOs that use TLS
|
||||
# will fail with undefined references to __tls_get_addr which resides
|
||||
# in ld.so and is never included in the link. This patch enhances
|
||||
# only the build-module and build-module-asneeded targets to include
|
||||
# a more fully and correct link line as the compiler driver would use
|
||||
# when constructing an application or DSO. We do not adjust the link
|
||||
# lines used to build lib* targets.
|
||||
#
|
||||
diff -urN glibc-2.12-2-gc4ccff1.orig/Makerules glibc-2.12-2-gc4ccff1/Makerules
|
||||
--- glibc-2.12-2-gc4ccff1.orig/Makerules 2015-02-18 19:53:00.000000000 -0500
|
||||
+++ glibc-2.12-2-gc4ccff1/Makerules 2015-02-18 20:08:33.299000028 -0500
|
||||
@@ -443,6 +443,25 @@
|
||||
load-map-file = $(map-file:%=-Wl,--version-script=%)
|
||||
endif
|
||||
|
||||
+# Compiler arguments to use to link a shared object with libc and
|
||||
+# ld.so. This is intended to be as similar as possible to a default
|
||||
+# link with an installed libc.
|
||||
+link-libc-args = -Wl,--start-group \
|
||||
+ $(libc-for-link) \
|
||||
+ $(common-objpfx)libc_nonshared.a \
|
||||
+ $(as-needed) $(elf-objpfx)ld.so $(no-as-needed) \
|
||||
+ -Wl,--end-group
|
||||
+
|
||||
+# The corresponding shared libc to use. This may be modified for a
|
||||
+# particular target.
|
||||
+libc-for-link = $(common-objpfx)libc.so
|
||||
+
|
||||
+# The corresponding dependencies. As these are used in dependencies,
|
||||
+# not just commands, they cannot use target-specific variables so need
|
||||
+# to name both possible libc.so objects.
|
||||
+link-libc-deps = $(common-objpfx)libc.so $(common-objpfx)linkobj/libc.so \
|
||||
+ $(common-objpfx)libc_nonshared.a $(elf-objpfx)ld.so
|
||||
+
|
||||
# Pattern rule to build a shared object from an archive of PIC objects.
|
||||
# This must come after the installation rules so Make doesn't try to
|
||||
# build shared libraries in place from the installed *_pic.a files.
|
||||
@@ -557,12 +576,13 @@
|
||||
# not for shared objects
|
||||
define build-module
|
||||
$(build-module-helper) -o $@ -T $(common-objpfx)shlib.lds \
|
||||
- $(csu-objpfx)abi-note.o $(build-module-objlist)
|
||||
+ $(csu-objpfx)abi-note.o $(build-module-objlist) $(link-libc-args)
|
||||
endef
|
||||
define build-module-asneeded
|
||||
$(build-module-helper) -o $@ -T $(common-objpfx)shlib.lds \
|
||||
$(csu-objpfx)abi-note.o \
|
||||
- -Wl,--as-needed $(build-module-objlist) -Wl,--no-as-needed
|
||||
+ -Wl,--as-needed $(build-module-objlist) -Wl,--no-as-needed \
|
||||
+ $(link-libc-args)
|
||||
endef
|
||||
else
|
||||
ifneq (,$(findstring aix,$(config-os)))
|
||||
@@ -1,407 +0,0 @@
|
||||
#
|
||||
# Based on this upstream commit:
|
||||
#
|
||||
# commit d8dd00805b8f3a011735d7a407097fb1c408d867
|
||||
# Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
# Date: Fri Nov 28 07:54:07 2014 -0800
|
||||
#
|
||||
# Resize DTV if the current DTV isn't big enough
|
||||
#
|
||||
# This patch changes _dl_allocate_tls_init to resize DTV if the current DTV
|
||||
# isn't big enough. Tested on X86-64, x32 and ia32.
|
||||
#
|
||||
# [BZ #13862]
|
||||
# * elf/dl-tls.c: Include <atomic.h>.
|
||||
# (oom): Remove #ifdef SHARED/#endif.
|
||||
# (_dl_static_dtv, _dl_initial_dtv): Moved before ...
|
||||
# (_dl_resize_dtv): This. Extracted from _dl_update_slotinfo.
|
||||
# (_dl_allocate_tls_init): Resize DTV if the current DTV isn't
|
||||
# big enough.
|
||||
# (_dl_update_slotinfo): Call _dl_resize_dtv to resize DTV.
|
||||
# * nptl/Makefile (tests): Add tst-stack4.
|
||||
# (modules-names): Add tst-stack4mod.
|
||||
# ($(objpfx)tst-stack4): New.
|
||||
# (tst-stack4mod.sos): Likewise.
|
||||
# ($(objpfx)tst-stack4.out): Likewise.
|
||||
# ($(tst-stack4mod.sos)): Likewise.
|
||||
# (clean): Likewise.
|
||||
# * nptl/tst-stack4.c: New file.
|
||||
# * nptl/tst-stack4mod.c: Likewise.
|
||||
#
|
||||
diff -urN glibc-2.12-2-gc4ccff1/elf/dl-tls.c glibc-2.12-2-gc4ccff1.mod/elf/dl-tls.c
|
||||
--- glibc-2.12-2-gc4ccff1/elf/dl-tls.c 2015-02-18 14:15:28.078461873 -0500
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/elf/dl-tls.c 2015-02-18 14:38:37.630374771 -0500
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
+#include <atomic.h>
|
||||
|
||||
#include <tls.h>
|
||||
#include <dl-tls.h>
|
||||
@@ -35,14 +36,12 @@
|
||||
|
||||
|
||||
/* Out-of-memory handler. */
|
||||
-#ifdef SHARED
|
||||
static void
|
||||
__attribute__ ((__noreturn__))
|
||||
oom (void)
|
||||
{
|
||||
_dl_fatal_printf ("cannot allocate memory for thread-local data: ABORT\n");
|
||||
}
|
||||
-#endif
|
||||
|
||||
|
||||
size_t
|
||||
@@ -392,6 +391,52 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
+static dtv_t *
|
||||
+_dl_resize_dtv (dtv_t *dtv)
|
||||
+{
|
||||
+ /* Resize the dtv. */
|
||||
+ dtv_t *newp;
|
||||
+ /* Load GL(dl_tls_max_dtv_idx) atomically since it may be written to by
|
||||
+ other threads concurrently. -- We don't have the required atomic
|
||||
+ infrastructure to load dl_tls_max_dtv_idx atomically, but on all the
|
||||
+ architectures we care about it should load atomically. If this had
|
||||
+ an atomic_load_acquire we would still be missing the releases for
|
||||
+ the writes. */
|
||||
+ size_t newsize = GL(dl_tls_max_dtv_idx) + DTV_SURPLUS;
|
||||
+ size_t oldsize = dtv[-1].counter;
|
||||
+
|
||||
+#if SHARED
|
||||
+ if (dtv == GL(dl_initial_dtv))
|
||||
+ {
|
||||
+ /* This is the initial dtv that was either statically allocated in
|
||||
+ __libc_setup_tls or allocated during rtld startup using the
|
||||
+ dl-minimal.c malloc instead of the real malloc. We can't free
|
||||
+ it, we have to abandon the old storage. */
|
||||
+
|
||||
+ newp = malloc ((2 + newsize) * sizeof (dtv_t));
|
||||
+ if (newp == NULL)
|
||||
+ oom ();
|
||||
+ memcpy (newp, &dtv[-1], (2 + oldsize) * sizeof (dtv_t));
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
+ {
|
||||
+ newp = realloc (&dtv[-1],
|
||||
+ (2 + newsize) * sizeof (dtv_t));
|
||||
+ if (newp == NULL)
|
||||
+ oom ();
|
||||
+ }
|
||||
+
|
||||
+ newp[0].counter = newsize;
|
||||
+
|
||||
+ /* Clear the newly allocated part. */
|
||||
+ memset (newp + 2 + oldsize, '\0',
|
||||
+ (newsize - oldsize) * sizeof (dtv_t));
|
||||
+
|
||||
+ /* Return the generation counter. */
|
||||
+ return &newp[1];
|
||||
+}
|
||||
+
|
||||
|
||||
void *
|
||||
internal_function
|
||||
@@ -406,6 +451,16 @@
|
||||
size_t total = 0;
|
||||
size_t maxgen = 0;
|
||||
|
||||
+ /* Check if the current dtv is big enough. */
|
||||
+ if (dtv[-1].counter < GL(dl_tls_max_dtv_idx))
|
||||
+ {
|
||||
+ /* Resize the dtv. */
|
||||
+ dtv = _dl_resize_dtv (dtv);
|
||||
+
|
||||
+ /* Install this new dtv in the thread data structures. */
|
||||
+ INSTALL_DTV (result, &dtv[-1]);
|
||||
+ }
|
||||
+
|
||||
/* We have to prepare the dtv for all currently loaded modules using
|
||||
TLS. For those which are dynamically loaded we add the values
|
||||
indicating deferred allocation. */
|
||||
@@ -637,41 +692,10 @@
|
||||
assert (total + cnt == modid);
|
||||
if (dtv[-1].counter < modid)
|
||||
{
|
||||
- /* Reallocate the dtv. */
|
||||
- dtv_t *newp;
|
||||
- size_t newsize = GL(dl_tls_max_dtv_idx) + DTV_SURPLUS;
|
||||
- size_t oldsize = dtv[-1].counter;
|
||||
-
|
||||
- assert (map->l_tls_modid <= newsize);
|
||||
-
|
||||
- if (dtv == GL(dl_initial_dtv))
|
||||
- {
|
||||
- /* This is the initial dtv that was allocated
|
||||
- during rtld startup using the dl-minimal.c
|
||||
- malloc instead of the real malloc. We can't
|
||||
- free it, we have to abandon the old storage. */
|
||||
-
|
||||
- newp = malloc ((2 + newsize) * sizeof (dtv_t));
|
||||
- if (newp == NULL)
|
||||
- oom ();
|
||||
- memcpy (newp, &dtv[-1], (2 + oldsize) * sizeof (dtv_t));
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- newp = realloc (&dtv[-1],
|
||||
- (2 + newsize) * sizeof (dtv_t));
|
||||
- if (newp == NULL)
|
||||
- oom ();
|
||||
- }
|
||||
-
|
||||
- newp[0].counter = newsize;
|
||||
-
|
||||
- /* Clear the newly allocated part. */
|
||||
- memset (newp + 2 + oldsize, '\0',
|
||||
- (newsize - oldsize) * sizeof (dtv_t));
|
||||
+ /* Resize the dtv. */
|
||||
+ dtv = _dl_resize_dtv (dtv);
|
||||
|
||||
- /* Point dtv to the generation counter. */
|
||||
- dtv = &newp[1];
|
||||
+ assert (modid <= dtv[-1].counter);
|
||||
|
||||
/* Install this new dtv in the thread data
|
||||
structures. */
|
||||
diff -urN glibc-2.12-2-gc4ccff1/nptl/Makefile glibc-2.12-2-gc4ccff1.mod/nptl/Makefile
|
||||
--- glibc-2.12-2-gc4ccff1/nptl/Makefile 2015-02-18 14:15:28.073462028 -0500
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/nptl/Makefile 2015-02-18 14:15:49.817786667 -0500
|
||||
@@ -245,7 +245,7 @@
|
||||
tst-exec1 tst-exec2 tst-exec3 tst-exec4 \
|
||||
tst-exit1 tst-exit2 tst-exit3 \
|
||||
tst-stdio1 tst-stdio2 \
|
||||
- tst-stack1 tst-stack2 tst-stack3 \
|
||||
+ tst-stack1 tst-stack2 tst-stack3 tst-stack4 \
|
||||
tst-unload \
|
||||
tst-dlsym1 \
|
||||
tst-sysconf \
|
||||
@@ -304,7 +304,7 @@
|
||||
|
||||
modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
|
||||
tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \
|
||||
- tst-tls5modd tst-tls5mode tst-tls5modf \
|
||||
+ tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \
|
||||
tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod
|
||||
extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) tst-cleanup4aux.o
|
||||
test-extras += $(modules-names)
|
||||
@@ -459,6 +459,19 @@
|
||||
$(common-objpfx)malloc/mtrace $(objpfx)tst-stack3.mtrace > $@
|
||||
generated += tst-stack3-mem tst-stack3.mtrace
|
||||
|
||||
+$(objpfx)tst-stack4: $(libdl) $(shared-thread-library)
|
||||
+tst-stack4mod.sos=$(shell for i in 0 1 2 3 4 5 6 7 8 9 10 \
|
||||
+ 11 12 13 14 15 16 17 18 19; do \
|
||||
+ for j in 0 1 2 3 4 5 6 7 8 9 10 \
|
||||
+ 11 12 13 14 15 16 17 18 19; do \
|
||||
+ echo $(objpfx)tst-stack4mod-$$i-$$j.so; \
|
||||
+ done; done)
|
||||
+$(objpfx)tst-stack4.out: $(tst-stack4mod.sos)
|
||||
+$(tst-stack4mod.sos): $(objpfx)tst-stack4mod.so
|
||||
+ cp -f $< $@
|
||||
+clean:
|
||||
+ rm -f $(tst-stack4mod.sos)
|
||||
+
|
||||
$(objpfx)tst-cleanup4: $(objpfx)tst-cleanup4aux.o $(shared-thread-library)
|
||||
$(objpfx)tst-cleanupx4: $(objpfx)tst-cleanup4aux.o $(shared-thread-library)
|
||||
|
||||
diff -urN glibc-2.12-2-gc4ccff1/nptl/tst-stack4.c glibc-2.12-2-gc4ccff1.mod/nptl/tst-stack4.c
|
||||
--- glibc-2.12-2-gc4ccff1/nptl/tst-stack4.c 1969-12-31 19:00:00.000000000 -0500
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/nptl/tst-stack4.c 2015-02-18 14:15:49.817786667 -0500
|
||||
@@ -0,0 +1,159 @@
|
||||
+/* Test DTV size oveflow when pthread_create reuses old DTV and TLS is
|
||||
+ used by dlopened shared object.
|
||||
+ 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
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdint.h>
|
||||
+#include <dlfcn.h>
|
||||
+#include <assert.h>
|
||||
+#include <pthread.h>
|
||||
+
|
||||
+/* The choices of thread count, and file counts are arbitary.
|
||||
+ The point is simply to run enough threads that an exiting
|
||||
+ thread has it's stack reused by another thread at the same
|
||||
+ time as new libraries have been loaded. */
|
||||
+#define DSO_SHARED_FILES 20
|
||||
+#define DSO_OPEN_THREADS 20
|
||||
+#define DSO_EXEC_THREADS 2
|
||||
+
|
||||
+/* Used to make sure that only one thread is calling dlopen and dlclose
|
||||
+ at a time. */
|
||||
+pthread_mutex_t g_lock;
|
||||
+
|
||||
+typedef void (*function) (void);
|
||||
+
|
||||
+void *
|
||||
+dso_invoke(void *dso_fun)
|
||||
+{
|
||||
+ function *fun_vec = (function *) dso_fun;
|
||||
+ int dso;
|
||||
+
|
||||
+ for (dso = 0; dso < DSO_SHARED_FILES; dso++)
|
||||
+ (*fun_vec[dso]) ();
|
||||
+
|
||||
+ pthread_exit (NULL);
|
||||
+}
|
||||
+
|
||||
+void *
|
||||
+dso_process (void * p)
|
||||
+{
|
||||
+ void *handle[DSO_SHARED_FILES];
|
||||
+ function fun_vec[DSO_SHARED_FILES];
|
||||
+ char dso_path[DSO_SHARED_FILES][100];
|
||||
+ int dso;
|
||||
+ uintptr_t t = (uintptr_t) p;
|
||||
+
|
||||
+ /* Open DSOs and get a function. */
|
||||
+ for (dso = 0; dso < DSO_SHARED_FILES; dso++)
|
||||
+ {
|
||||
+ sprintf (dso_path[dso], "tst-stack4mod-%i-%i.so", t, dso);
|
||||
+
|
||||
+ pthread_mutex_lock (&g_lock);
|
||||
+
|
||||
+ handle[dso] = dlopen (dso_path[dso], RTLD_NOW);
|
||||
+ assert (handle[dso]);
|
||||
+
|
||||
+ fun_vec[dso] = (function) dlsym (handle[dso], "function");
|
||||
+ assert (fun_vec[dso]);
|
||||
+
|
||||
+ pthread_mutex_unlock (&g_lock);
|
||||
+ }
|
||||
+
|
||||
+ /* Spawn workers. */
|
||||
+ pthread_t thread[DSO_EXEC_THREADS];
|
||||
+ int i, ret;
|
||||
+ uintptr_t result = 0;
|
||||
+ for (i = 0; i < DSO_EXEC_THREADS; i++)
|
||||
+ {
|
||||
+ pthread_mutex_lock (&g_lock);
|
||||
+ ret = pthread_create (&thread[i], NULL, dso_invoke, (void *) fun_vec);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ printf ("pthread_create failed: %d\n", ret);
|
||||
+ result = 1;
|
||||
+ }
|
||||
+ pthread_mutex_unlock (&g_lock);
|
||||
+ }
|
||||
+
|
||||
+ if (!result)
|
||||
+ for (i = 0; i < DSO_EXEC_THREADS; i++)
|
||||
+ {
|
||||
+ ret = pthread_join (thread[i], NULL);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ printf ("pthread_join failed: %d\n", ret);
|
||||
+ result = 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Close all DSOs. */
|
||||
+ for (dso = 0; dso < DSO_SHARED_FILES; dso++)
|
||||
+ {
|
||||
+ pthread_mutex_lock (&g_lock);
|
||||
+ dlclose (handle[dso]);
|
||||
+ pthread_mutex_unlock (&g_lock);
|
||||
+ }
|
||||
+
|
||||
+ /* Exit. */
|
||||
+ pthread_exit ((void *) result);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ pthread_t thread[DSO_OPEN_THREADS];
|
||||
+ int i,j;
|
||||
+ int ret;
|
||||
+ int result = 0;
|
||||
+
|
||||
+ pthread_mutex_init (&g_lock, NULL);
|
||||
+
|
||||
+ /* 100 is arbitrary here and is known to trigger PR 13862. */
|
||||
+ for (j = 0; j < 100; j++)
|
||||
+ {
|
||||
+ for (i = 0; i < DSO_OPEN_THREADS; i++)
|
||||
+ {
|
||||
+ ret = pthread_create (&thread[i], NULL, dso_process,
|
||||
+ (void *) (uintptr_t) i);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ printf ("pthread_create failed: %d\n", ret);
|
||||
+ result = 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (result)
|
||||
+ break;
|
||||
+
|
||||
+ for (i = 0; i < DSO_OPEN_THREADS; i++)
|
||||
+ {
|
||||
+ ret = pthread_join (thread[i], NULL);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ printf ("pthread_join failed: %d\n", ret);
|
||||
+ result = 1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#define TIMEOUT 100
|
||||
+#include "../test-skeleton.c"
|
||||
diff -urN glibc-2.12-2-gc4ccff1/nptl/tst-stack4mod.c glibc-2.12-2-gc4ccff1.mod/nptl/tst-stack4mod.c
|
||||
--- glibc-2.12-2-gc4ccff1/nptl/tst-stack4mod.c 1969-12-31 19:00:00.000000000 -0500
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/nptl/tst-stack4mod.c 2015-02-18 14:15:49.817786667 -0500
|
||||
@@ -0,0 +1,28 @@
|
||||
+/* This tests DTV usage with TLS in dlopened shared object.
|
||||
+ 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
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* 256 is arbitrary here and is known to trigger PR 13862. */
|
||||
+__thread int var[256] attribute_hidden = {0};
|
||||
+
|
||||
+void
|
||||
+function (void)
|
||||
+{
|
||||
+ int i;
|
||||
+ for (i = 0; i < sizeof (var) / sizeof (int); i++)
|
||||
+ var[i] = i;
|
||||
+}
|
||||
@@ -1,47 +0,0 @@
|
||||
#
|
||||
# Derived from this upstream commit:
|
||||
#
|
||||
# commit 58a1335e76a553e1cf4edeebc27f16fc9b53d6e6
|
||||
# Author: Petr Baudis <pasky@ucw.cz>
|
||||
# Date: Thu Mar 14 01:16:53 2013 +0100
|
||||
#
|
||||
# Fix __times() handling of EFAULT when buf is NULL
|
||||
#
|
||||
# 2013-03-14 Petr Baudis <pasky@ucw.cz>
|
||||
#
|
||||
# * sysdeps/unix/sysv/linux/times.c (__times): On EFAULT, test
|
||||
# for non-NULL pointer before the memory validity test. Pointed
|
||||
# out by Holger Brunck <holger.brunck@keymile.com>.
|
||||
#
|
||||
diff --git a/sysdeps/unix/sysv/linux/times.c b/sysdeps/unix/sysv/linux/times.c
|
||||
index f3b5f01..e59bb4e 100644
|
||||
--- a/sysdeps/unix/sysv/linux/times.c
|
||||
+++ b/sysdeps/unix/sysv/linux/times.c
|
||||
@@ -26,13 +26,14 @@ __times (struct tms *buf)
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
clock_t ret = INTERNAL_SYSCALL (times, err, 1, buf);
|
||||
if (INTERNAL_SYSCALL_ERROR_P (ret, err)
|
||||
- && __builtin_expect (INTERNAL_SYSCALL_ERRNO (ret, err) == EFAULT, 0))
|
||||
+ && __builtin_expect (INTERNAL_SYSCALL_ERRNO (ret, err) == EFAULT, 0)
|
||||
+ && buf)
|
||||
{
|
||||
/* This might be an error or not. For architectures which have
|
||||
no separate return value and error indicators we cannot
|
||||
distinguish a return value of -1 from an error. Do it the
|
||||
- hard way. We crash applications which pass in an invalid BUF
|
||||
- pointer. */
|
||||
+ hard way. We crash applications which pass in an invalid
|
||||
+ non-NULL BUF pointer. Linux allows BUF to be NULL. */
|
||||
#define touch(v) \
|
||||
do { \
|
||||
clock_t temp = v; \
|
||||
@@ -44,7 +45,8 @@ __times (struct tms *buf)
|
||||
touch (buf->tms_cutime);
|
||||
touch (buf->tms_cstime);
|
||||
|
||||
- /* If we come here the memory is valid and the kernel did not
|
||||
+ /* If we come here the memory is valid (or BUF is NULL, which is
|
||||
+ * a valid condition for the kernel syscall) and the kernel did not
|
||||
return an EFAULT error. Return the value given by the kernel. */
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
commit a11892631d92f594c690d0d50a642b0d1aba58b8
|
||||
Author: Ondřej Bílka <neleai@seznam.cz>
|
||||
Date: Wed May 7 14:08:57 2014 +0200
|
||||
|
||||
Fix typo in nscd/selinux.c
|
||||
|
||||
diff --git a/nscd/selinux.c b/nscd/selinux.c
|
||||
index 9a8a5a8..eaed6dd 100644
|
||||
--- a/nscd/selinux.c
|
||||
+++ b/nscd/selinux.c
|
||||
@@ -372,7 +372,7 @@ nscd_request_avc_has_perm (int fd, request_type req)
|
||||
/* Get the security class for nscd. If this fails we will likely be
|
||||
unable to do anything unless avc_deny_unknown is 0. */
|
||||
sc_nscd = string_to_security_class ("nscd");
|
||||
- if (perm == 0 && avc_deny_unknown == 1)
|
||||
+ if (sc_nscd == 0 && avc_deny_unknown == 1)
|
||||
dbg_log (_("Error getting security class for nscd."));
|
||||
|
||||
/* Convert permission to AVC bits. */
|
||||
@@ -1,199 +0,0 @@
|
||||
2014-08-21 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
[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
|
||||
|
||||
@@ -1,625 +0,0 @@
|
||||
commit 585367266923156ac6fb789939a923641ba5aaf4
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed May 28 14:05:03 2014 +0200
|
||||
|
||||
manual: Update the locale documentation
|
||||
|
||||
commit 4e8f95a0df7c2300b830ec12c0ae1e161bc8a8a3
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
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 <fweimer@redhat.com>
|
||||
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 <assert.h>
|
||||
+#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -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
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <locale.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+/* 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
|
||||
@@ -1,45 +0,0 @@
|
||||
commit e35c53e397e7abbd41fedacdedcfa5af7b5c2c52
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Tue Jul 8 16:40:24 2014 +0530
|
||||
|
||||
Check value at resplen2 if it is not NULL
|
||||
|
||||
There was a typo in the previous patch due to which resplen2 was
|
||||
checked for non-zero instead of the value at resplen2. Fix that and
|
||||
improve the condition by checking resplen2 for non-NULL (instead of
|
||||
answerp2) and also adding the check in a third place.
|
||||
|
||||
diff --git a/resolv/res_query.c b/resolv/res_query.c
|
||||
index 4e6612c..e4ee2a6 100644
|
||||
--- a/resolv/res_query.c
|
||||
+++ b/resolv/res_query.c
|
||||
@@ -384,7 +384,7 @@ __libc_res_nsearch(res_state statp,
|
||||
answerp2, nanswerp2, resplen2);
|
||||
if (ret > 0 || trailing_dot
|
||||
/* If the second response is valid then we use that. */
|
||||
- || (ret == 0 && answerp2 != NULL && resplen2 > 0))
|
||||
+ || (ret == 0 && resplen2 != NULL && *resplen2 > 0))
|
||||
return (ret);
|
||||
saved_herrno = h_errno;
|
||||
tried_as_is++;
|
||||
@@ -424,8 +424,8 @@ __libc_res_nsearch(res_state statp,
|
||||
answer, anslen, answerp,
|
||||
answerp2, nanswerp2,
|
||||
resplen2);
|
||||
- if (ret > 0 || (ret == 0 && answerp2 != NULL
|
||||
- && resplen2 > 0))
|
||||
+ if (ret > 0 || (ret == 0 && resplen2 != NULL
|
||||
+ && *resplen2 > 0))
|
||||
return (ret);
|
||||
|
||||
if (answerp && *answerp != answer) {
|
||||
@@ -494,7 +494,8 @@ __libc_res_nsearch(res_state statp,
|
||||
ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
|
||||
answer, anslen, answerp,
|
||||
answerp2, nanswerp2, resplen2);
|
||||
- if (ret > 0)
|
||||
+ if (ret > 0 || (ret == 0 && resplen2 != NULL
|
||||
+ && *resplen2 > 0))
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#
|
||||
# Based on the following commit:
|
||||
#
|
||||
# commit f9d2d03254a58d92635a311a42253eeed5a40a47
|
||||
# Author: Andreas Schwab <schwab@suse.de>
|
||||
# Date: Mon May 26 18:01:31 2014 +0200
|
||||
#
|
||||
# Fix invalid file descriptor reuse while sending DNS query (BZ #15946)
|
||||
#
|
||||
# 2014-06-03 Andreas Schwab <schwab@suse.de>
|
||||
#
|
||||
# [BZ #15946]
|
||||
# * resolv/res_send.c (send_dg): Reload file descriptor after
|
||||
# calling reopen.
|
||||
#
|
||||
diff --git a/resolv/res_send.c b/resolv/res_send.c
|
||||
index 3273d55..af42b8a 100644
|
||||
--- a/resolv/res_send.c
|
||||
+++ b/resolv/res_send.c
|
||||
@@ -1410,6 +1410,7 @@ send_dg(res_state statp,
|
||||
retval = reopen (statp, terrno, ns);
|
||||
if (retval <= 0)
|
||||
return retval;
|
||||
+ pfd[0].fd = EXT(statp).nssocks[ns];
|
||||
}
|
||||
}
|
||||
goto wait;
|
||||
@@ -1,58 +0,0 @@
|
||||
#
|
||||
# Based on this commit:
|
||||
#
|
||||
# commit 62058ce612ed3459501b4c4332e268edfe977f59
|
||||
# Author: Carlos O'Donell <carlos@redhat.com>
|
||||
# Date: Mon Sep 29 13:14:21 2014 -0400
|
||||
#
|
||||
# Correctly size profiling reloc table (bug 17411)
|
||||
#
|
||||
# During auditing or profiling modes the dynamic loader
|
||||
# builds a cache of the relocated PLT entries in order
|
||||
# to reuse them when called again through the same PLT
|
||||
# entry. This way the PLT entry is never completed and
|
||||
# the call into the resolver always results in profiling
|
||||
# or auditing code running.
|
||||
#
|
||||
# The problem is that the PLT relocation cache size
|
||||
# is not computed correctly. The size of the cache
|
||||
# should be "Size of a relocation result structure"
|
||||
# x "Number of PLT-related relocations". Instead the
|
||||
# code erroneously computes "Size of a relocation
|
||||
# result" x "Number of bytes worth of PLT-related
|
||||
# relocations". I can only assume this was a mistake
|
||||
# in the understanding of the value of DT_PLTRELSZ
|
||||
# which is the number of bytes of PLT-related relocs.
|
||||
# We do have a DT_RELACOUNT entry, which is a count
|
||||
# for dynamic relative relocs, but we have no
|
||||
# DT_PLTRELCOUNT and thus we need to compute it.
|
||||
#
|
||||
# This patch corrects the computation of the size of the
|
||||
# relocation table used by the glibc profiling code.
|
||||
#
|
||||
# For more details see:
|
||||
# https://sourceware.org/ml/libc-alpha/2014-09/msg00513.html
|
||||
#
|
||||
# [BZ #17411]
|
||||
# * elf/dl-reloc.c (_dl_relocate_object): Allocate correct amount for
|
||||
# l_reloc_result.
|
||||
#
|
||||
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
|
||||
index d2c6dac..97a7119 100644
|
||||
--- a/elf/dl-reloc.c
|
||||
+++ b/elf/dl-reloc.c
|
||||
@@ -279,8 +279,12 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||
l->l_name);
|
||||
}
|
||||
|
||||
- l->l_reloc_result = calloc (sizeof (l->l_reloc_result[0]),
|
||||
- l->l_info[DT_PLTRELSZ]->d_un.d_val);
|
||||
+ size_t sizeofrel = l->l_info[DT_PLTREL]->d_un.d_val == DT_RELA
|
||||
+ ? sizeof (ElfW(Rela))
|
||||
+ : sizeof (ElfW(Rel));
|
||||
+ size_t relcount = l->l_info[DT_PLTRELSZ]->d_un.d_val / sizeofrel;
|
||||
+ l->l_reloc_result = calloc (sizeof (l->l_reloc_result[0]), relcount);
|
||||
+
|
||||
if (l->l_reloc_result == NULL)
|
||||
{
|
||||
errstring = N_("\
|
||||
@@ -1,333 +0,0 @@
|
||||
#
|
||||
# This is a special patch for rhel-6 to fix recursive dlopen.
|
||||
# It is likely the upstream patch will always be too risky for
|
||||
# rhel-6 and will involve reorganizing the way in which recursive
|
||||
# dlopen is allowed to operate and how the _r_debug and stap
|
||||
# points are used by gdb for the recursive case.
|
||||
#
|
||||
# This fix changes the internal API to duplicate the ldconfig
|
||||
# cache data. This means that at any point the cache can be
|
||||
# unmapped without any consequences. The caller is responsible
|
||||
# fore freeing the returned string.
|
||||
#
|
||||
# A regression test is added to verify the assertion for _r_debug
|
||||
# is no longer triggered due to the recursive dlopen. The test to
|
||||
# verify the fix in _dl_load_cache_lookup is not automated and
|
||||
# has to be run by hand.
|
||||
#
|
||||
diff -urN glibc-2.12-2-gc4ccff1/elf/dl-cache.c glibc-2.12-2-gc4ccff1.mod/elf/dl-cache.c
|
||||
--- glibc-2.12-2-gc4ccff1/elf/dl-cache.c 2010-05-04 07:27:23.000000000 -0400
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/elf/dl-cache.c 2014-12-10 21:54:08.801985045 -0500
|
||||
@@ -175,9 +175,12 @@
|
||||
|
||||
|
||||
/* Look up NAME in ld.so.cache and return the file name stored there,
|
||||
- or null if none is found. */
|
||||
-
|
||||
-const char *
|
||||
+ or null if none is found.
|
||||
+ The caller is responsible for freeing the returned string. The ld.so.cache
|
||||
+ may be unmapped at any time by a completing recursive dlopen and
|
||||
+ this function must take care that it does not return references to
|
||||
+ any data in the mapping. */
|
||||
+char *
|
||||
internal_function
|
||||
_dl_load_cache_lookup (const char *name)
|
||||
{
|
||||
@@ -290,7 +293,17 @@
|
||||
&& best != NULL)
|
||||
_dl_debug_printf (" trying file=%s\n", best);
|
||||
|
||||
- return best;
|
||||
+ if (best == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* The double copy is *required* since malloc may be interposed
|
||||
+ and call dlopen itself whose completion would unmap the data
|
||||
+ we are accessing. Therefore we must make the copy of the
|
||||
+ mapping data without using malloc. */
|
||||
+ char *temp;
|
||||
+ temp = alloca (strlen (best) + 1);
|
||||
+ strcpy (temp, best);
|
||||
+ return strdup (temp);
|
||||
}
|
||||
|
||||
#ifndef MAP_COPY
|
||||
diff -urN glibc-2.12-2-gc4ccff1/elf/dl-load.c glibc-2.12-2-gc4ccff1.mod/elf/dl-load.c
|
||||
--- glibc-2.12-2-gc4ccff1/elf/dl-load.c 2014-12-10 11:03:17.966048404 -0500
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/elf/dl-load.c 2014-12-10 21:47:29.319387538 -0500
|
||||
@@ -2126,7 +2126,7 @@
|
||||
{
|
||||
/* Check the list of libraries in the file /etc/ld.so.cache,
|
||||
for compatibility with Linux's ldconfig program. */
|
||||
- const char *cached = _dl_load_cache_lookup (name);
|
||||
+ char *cached = _dl_load_cache_lookup (name);
|
||||
|
||||
if (cached != NULL)
|
||||
{
|
||||
@@ -2156,6 +2156,7 @@
|
||||
if (memcmp (cached, dirp, system_dirs_len[cnt]) == 0)
|
||||
{
|
||||
/* The prefix matches. Don't use the entry. */
|
||||
+ free (cached);
|
||||
cached = NULL;
|
||||
break;
|
||||
}
|
||||
@@ -2172,14 +2173,9 @@
|
||||
&fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
|
||||
LA_SER_CONFIG, &found_other_class, false);
|
||||
if (__builtin_expect (fd != -1, 1))
|
||||
- {
|
||||
- realname = local_strdup (cached);
|
||||
- if (realname == NULL)
|
||||
- {
|
||||
- __close (fd);
|
||||
- fd = -1;
|
||||
- }
|
||||
- }
|
||||
+ realname = cached;
|
||||
+ else
|
||||
+ free (cached);
|
||||
}
|
||||
}
|
||||
}
|
||||
diff -urN glibc-2.12-2-gc4ccff1/elf/dl-open.c glibc-2.12-2-gc4ccff1.mod/elf/dl-open.c
|
||||
--- glibc-2.12-2-gc4ccff1/elf/dl-open.c 2014-12-10 11:03:18.083048497 -0500
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/elf/dl-open.c 2014-12-10 20:34:16.017503638 -0500
|
||||
@@ -220,7 +220,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
- assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT);
|
||||
+ /* One might be tempted to assert that we are RT_CONSISTENT at this point, but that
|
||||
+ may not be true if this is a recursive call to dlopen.
|
||||
+ TODO: Fix all of the debug state so we end up at RT_CONSISTENT only when the last
|
||||
+ recursive dlopen completes. */
|
||||
+ _dl_debug_initialize (0, args->nsid);
|
||||
|
||||
/* Load the named object. */
|
||||
struct link_map *new;
|
||||
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/generic/ldsodefs.h glibc-2.12-2-gc4ccff1.mod/sysdeps/generic/ldsodefs.h
|
||||
--- glibc-2.12-2-gc4ccff1/sysdeps/generic/ldsodefs.h 2014-12-10 11:03:17.944048387 -0500
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/generic/ldsodefs.h 2014-12-10 21:46:14.071344018 -0500
|
||||
@@ -996,8 +996,8 @@
|
||||
internal_function;
|
||||
|
||||
/* Look up NAME in ld.so.cache and return the file name stored there,
|
||||
- or null if none is found. */
|
||||
-extern const char *_dl_load_cache_lookup (const char *name)
|
||||
+ or null if none is found. Caller must free returned string. */
|
||||
+extern char *_dl_load_cache_lookup (const char *name)
|
||||
internal_function;
|
||||
|
||||
/* If the system does not support MAP_COPY we cannot leave the file open
|
||||
diff -urN glibc-2.12-2-gc4ccff1/dlfcn/Makefile glibc-2.12-2-gc4ccff1.mod/dlfcn/Makefile
|
||||
--- glibc-2.12-2-gc4ccff1/dlfcn/Makefile 2010-05-04 07:27:23.000000000 -0400
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/dlfcn/Makefile 2014-12-11 16:58:55.719803063 -0500
|
||||
@@ -42,12 +42,12 @@
|
||||
ifeq (yes,$(build-shared))
|
||||
tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \
|
||||
bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \
|
||||
- bug-atexit3 tstatexit
|
||||
+ bug-atexit3 tstatexit tst-rec-dlopen
|
||||
endif
|
||||
modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \
|
||||
defaultmod2 errmsg1mod modatexit modcxaatexit \
|
||||
bug-dlsym1-lib1 bug-dlsym1-lib2 bug-atexit1-lib \
|
||||
- bug-atexit2-lib bug-atexit3-lib
|
||||
+ bug-atexit2-lib bug-atexit3-lib moddummy1 moddummy2
|
||||
|
||||
failtestmod.so-no-z-defs = yes
|
||||
glreflib2.so-no-z-defs = yes
|
||||
@@ -142,6 +142,8 @@
|
||||
$(objpfx)bug-atexit3-lib.so: $(common-objpfx)libc.so \
|
||||
$(common-objpfx)libc_nonshared.a
|
||||
|
||||
+LDLIBS-tst-rec-dlopen = -ldl
|
||||
+$(objpfx)tst-rec-dlopen: $(libdl)
|
||||
|
||||
# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
|
||||
# This ensures they will load libc.so for needed symbols if loaded by
|
||||
diff -urN glibc-2.12-2-gc4ccff1/dlfcn/moddummy1.c glibc-2.12-2-gc4ccff1.mod/dlfcn/moddummy1.c
|
||||
--- glibc-2.12-2-gc4ccff1/dlfcn/moddummy1.c 1969-12-31 19:00:00.000000000 -0500
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/dlfcn/moddummy1.c 2014-12-11 16:57:54.108797285 -0500
|
||||
@@ -0,0 +1,13 @@
|
||||
+/* Provide a dummy DSO for tst-recursive-dlopen to use. */
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+int called_dummy1;
|
||||
+
|
||||
+void
|
||||
+dummy1 (void)
|
||||
+{
|
||||
+ printf ("Called dummy1()\n");
|
||||
+ called_dummy1++;
|
||||
+}
|
||||
+
|
||||
diff -urN glibc-2.12-2-gc4ccff1/dlfcn/moddummy2.c glibc-2.12-2-gc4ccff1.mod/dlfcn/moddummy2.c
|
||||
--- glibc-2.12-2-gc4ccff1/dlfcn/moddummy2.c 1969-12-31 19:00:00.000000000 -0500
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/dlfcn/moddummy2.c 2014-12-11 16:57:54.108797285 -0500
|
||||
@@ -0,0 +1,13 @@
|
||||
+/* Provide a dummy DSO for tst-recursive-dlopen to use. */
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+int called_dummy2;
|
||||
+
|
||||
+void
|
||||
+dummy2 (void)
|
||||
+{
|
||||
+ printf ("Called dummy2()\n");
|
||||
+ called_dummy2++;
|
||||
+}
|
||||
+
|
||||
diff -urN glibc-2.12-2-gc4ccff1/dlfcn/tst-rec-dlopen.c glibc-2.12-2-gc4ccff1.mod/dlfcn/tst-rec-dlopen.c
|
||||
--- glibc-2.12-2-gc4ccff1/dlfcn/tst-rec-dlopen.c 1969-12-31 19:00:00.000000000 -0500
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/dlfcn/tst-rec-dlopen.c 2014-12-11 20:53:28.617848774 -0500
|
||||
@@ -0,0 +1,145 @@
|
||||
+/* Test recursive dlopen using malloc hooks.
|
||||
+ Copyright (C) 1998-2014 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
|
||||
+
|
||||
+ 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 <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <malloc.h>
|
||||
+#include <dlfcn.h>
|
||||
+
|
||||
+#define DSO "moddummy1.so"
|
||||
+#define FUNC "dummy1"
|
||||
+
|
||||
+#define DSO1 "moddummy2.so"
|
||||
+#define FUNC1 "dummy2"
|
||||
+
|
||||
+/* Prevent the compiler from moving the assignment to called_func
|
||||
+ before (*func)() since the compiler doesn't know we might abort
|
||||
+ or catch a SIGSEGV signal and it may move the store. */
|
||||
+volatile int called_func;
|
||||
+
|
||||
+/* Prototype for my hook. */
|
||||
+void *custom_malloc_hook (size_t, const void *);
|
||||
+
|
||||
+/* Pointer to old malloc hooks. */
|
||||
+void *(*old_malloc_hook) (size_t, const void *);
|
||||
+
|
||||
+/* Call function func_name in DSO dso_name via dlopen. */
|
||||
+void
|
||||
+call_func (const char *dso_name, const char *func_name)
|
||||
+{
|
||||
+ int ret;
|
||||
+ void *dso;
|
||||
+ void (*func) (void);
|
||||
+ char *err;
|
||||
+
|
||||
+ /* Open the DSO. */
|
||||
+ dso = dlopen (dso_name, RTLD_NOW|RTLD_GLOBAL);
|
||||
+ if (dso == NULL)
|
||||
+ {
|
||||
+ err = dlerror ();
|
||||
+ fprintf (stderr, "%s\n", err);
|
||||
+ exit (1);
|
||||
+ }
|
||||
+ /* Clear any errors. */
|
||||
+ dlerror ();
|
||||
+
|
||||
+ /* Lookup func. */
|
||||
+ *(void **) (&func) = dlsym (dso, func_name);
|
||||
+ if (func == NULL)
|
||||
+ {
|
||||
+ err = dlerror ();
|
||||
+ if (err != NULL)
|
||||
+ {
|
||||
+ fprintf (stderr, "%s\n", err);
|
||||
+ exit (1);
|
||||
+ }
|
||||
+ }
|
||||
+ /* Call func. */
|
||||
+ (*func) ();
|
||||
+ called_func = 1;
|
||||
+
|
||||
+ /* Close the library and look for errors too. */
|
||||
+ ret = dlclose (dso);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ err = dlerror ();
|
||||
+ fprintf (stderr, "%s\n", err);
|
||||
+ exit (1);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
+/* Empty hook that does nothing. */
|
||||
+void *
|
||||
+custom_malloc_hook (size_t size, const void *caller)
|
||||
+{
|
||||
+ void *result;
|
||||
+ /* Restore old hooks. */
|
||||
+ __malloc_hook = old_malloc_hook;
|
||||
+ /* First call a function in another library via dlopen. */
|
||||
+ call_func (DSO1, FUNC1);
|
||||
+ /* Called recursively. */
|
||||
+ result = malloc (size);
|
||||
+ /* Restore new hooks. */
|
||||
+ __malloc_hook = custom_malloc_hook;
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ /* Save old hook. */
|
||||
+ old_malloc_hook = __malloc_hook;
|
||||
+ /* Install new hook. */
|
||||
+ __malloc_hook = custom_malloc_hook;
|
||||
+
|
||||
+ /* Bug 17702 fixes two things:
|
||||
+ * A recursive dlopen unmapping the ld.so.cache.
|
||||
+ * An assertion that _r_debug is RT_CONSISTENT at entry to dlopen.
|
||||
+ We can only test the latter. Testing the former requires modifying
|
||||
+ ld.so.conf to cache the dummy libraries, then running ldconfig,
|
||||
+ then run the test. If you do all of that (and glibc's test
|
||||
+ infrastructure doesn't support that yet) then the test will
|
||||
+ SEGFAULT without the fix. If you don't do that, then the test
|
||||
+ will abort because of the assert described in detail below. */
|
||||
+ call_func (DSO, FUNC);
|
||||
+
|
||||
+ /* Restore old hook. */
|
||||
+ __malloc_hook = old_malloc_hook;
|
||||
+
|
||||
+ /* The function dummy2() is called by the malloc hook. Check to
|
||||
+ see that it was called. This ensures the second recursive
|
||||
+ dlopen happened and we called the function in that library.
|
||||
+
|
||||
+ Before the fix you either get a SIGSEGV when accessing mmap'd
|
||||
+ ld.so.cache data or an assertion failure about _r_debug not
|
||||
+ beint RT_CONSISTENT. We don't test for the SIGSEGV since it
|
||||
+ would require finding moddummy1 or moddummy2 in the cache and
|
||||
+ we don't have any infrastructure to test that, but the _r_debug
|
||||
+ assertion triggers. */
|
||||
+ if (called_func > 0)
|
||||
+ printf ("PASS: Function call_func() called more than once.\n");
|
||||
+ else
|
||||
+ printf ("FAIL: Function call_func() not called.\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#include "../test-skeleton.c"
|
||||
@@ -1,15 +0,0 @@
|
||||
diff --git a/sunrpc/svc.c b/sunrpc/svc.c
|
||||
index ccf0902..30c3a93 100644
|
||||
--- a/sunrpc/svc.c
|
||||
+++ b/sunrpc/svc.c
|
||||
@@ -97,8 +97,8 @@ xprt_register (SVCXPRT *xprt)
|
||||
|
||||
if (xports == NULL)
|
||||
{
|
||||
- xports = (SVCXPRT **) malloc (_rpc_dtablesize () * sizeof (SVCXPRT *));
|
||||
- if (xports == NULL) /* Don<6F>t add handle */
|
||||
+ xports = (SVCXPRT **) calloc (_rpc_dtablesize (), sizeof (SVCXPRT *));
|
||||
+ if (xports == NULL) /* Don't add handle */
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
#
|
||||
# commit a39208bd7fb76c1b01c127b4c61f9bfd915bfe7c
|
||||
# Author: Carlos O'Donell <carlos@redhat.com>
|
||||
# Date: Wed Nov 19 11:44:12 2014 -0500
|
||||
#
|
||||
# CVE-2014-7817: wordexp fails to honour WRDE_NOCMD.
|
||||
#
|
||||
# The function wordexp() fails to properly handle the WRDE_NOCMD
|
||||
# flag when processing arithmetic inputs in the form of "$((... ``))"
|
||||
# where "..." can be anything valid. The backticks in the arithmetic
|
||||
# epxression are evaluated by in a shell even if WRDE_NOCMD forbade
|
||||
# command substitution. This allows an attacker to attempt to pass
|
||||
# dangerous commands via constructs of the above form, and bypass
|
||||
# the WRDE_NOCMD flag. This patch fixes this by checking for WRDE_NOCMD
|
||||
# in exec_comm(), the only place that can execute a shell. All other
|
||||
# checks for WRDE_NOCMD are superfluous and removed.
|
||||
#
|
||||
# We expand the testsuite and add 3 new regression tests of roughly
|
||||
# the same form but with a couple of nested levels.
|
||||
#
|
||||
# On top of the 3 new tests we add fork validation to the WRDE_NOCMD
|
||||
# testing. If any forks are detected during the execution of a wordexp()
|
||||
# call with WRDE_NOCMD, the test is marked as failed. This is slightly
|
||||
# heuristic since vfork might be used in the future, but it provides a
|
||||
# higher level of assurance that no shells were executed as part of
|
||||
# command substitution with WRDE_NOCMD in effect. In addition it doesn't
|
||||
# require libpthread or libdl, instead we use the public implementation
|
||||
# namespace function __register_atfork (already part of the public ABI
|
||||
# for libpthread).
|
||||
#
|
||||
# Tested on x86_64 with no regressions.
|
||||
#
|
||||
diff --git a/posix/wordexp-test.c b/posix/wordexp-test.c
|
||||
index 4957006..bdd65e4 100644
|
||||
--- a/posix/wordexp-test.c
|
||||
+++ b/posix/wordexp-test.c
|
||||
@@ -27,6 +27,25 @@
|
||||
|
||||
#define IFS " \n\t"
|
||||
|
||||
+extern void *__dso_handle __attribute__ ((__weak__, __visibility__ ("hidden")));
|
||||
+extern int __register_atfork (void (*) (void), void (*) (void), void (*) (void), void *);
|
||||
+
|
||||
+static int __app_register_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void))
|
||||
+{
|
||||
+ return __register_atfork (prepare, parent, child,
|
||||
+ &__dso_handle == NULL ? NULL : __dso_handle);
|
||||
+}
|
||||
+
|
||||
+/* Number of forks seen. */
|
||||
+static int registered_forks;
|
||||
+
|
||||
+/* For each fork increment the fork count. */
|
||||
+static void
|
||||
+register_fork (void)
|
||||
+{
|
||||
+ registered_forks++;
|
||||
+}
|
||||
+
|
||||
struct test_case_struct
|
||||
{
|
||||
int retval;
|
||||
@@ -206,6 +225,12 @@ struct test_case_struct
|
||||
{ WRDE_SYNTAX, NULL, "$((2+))", 0, 0, { NULL, }, IFS },
|
||||
{ WRDE_SYNTAX, NULL, "`", 0, 0, { NULL, }, IFS },
|
||||
{ WRDE_SYNTAX, NULL, "$((010+4+))", 0, 0, { NULL }, IFS },
|
||||
+ /* Test for CVE-2014-7817. We test 3 combinations of command
|
||||
+ substitution inside an arithmetic expression to make sure that
|
||||
+ no commands are executed and error is returned. */
|
||||
+ { WRDE_CMDSUB, NULL, "$((`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS },
|
||||
+ { WRDE_CMDSUB, NULL, "$((1+`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS },
|
||||
+ { WRDE_CMDSUB, NULL, "$((1+$((`echo 1`))))", WRDE_NOCMD, 0, { NULL, }, IFS },
|
||||
|
||||
{ -1, NULL, NULL, 0, 0, { NULL, }, IFS },
|
||||
};
|
||||
@@ -258,6 +283,15 @@ main (int argc, char *argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ /* If we are not allowed to do command substitution, we install
|
||||
+ fork handlers to verify that no forks happened. No forks should
|
||||
+ happen at all if command substitution is disabled. */
|
||||
+ if (__app_register_atfork (register_fork, NULL, NULL) != 0)
|
||||
+ {
|
||||
+ printf ("Failed to register fork handler.\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
for (test = 0; test_case[test].retval != -1; test++)
|
||||
if (testit (&test_case[test]))
|
||||
++fail;
|
||||
@@ -367,6 +401,9 @@ testit (struct test_case_struct *tc)
|
||||
|
||||
printf ("Test %d (%s): ", ++tests, tc->words);
|
||||
|
||||
+ if (tc->flags & WRDE_NOCMD)
|
||||
+ registered_forks = 0;
|
||||
+
|
||||
if (tc->flags & WRDE_APPEND)
|
||||
{
|
||||
/* initial wordexp() call, to be appended to */
|
||||
@@ -378,6 +415,13 @@ testit (struct test_case_struct *tc)
|
||||
}
|
||||
retval = wordexp (tc->words, &we, tc->flags);
|
||||
|
||||
+ if ((tc->flags & WRDE_NOCMD)
|
||||
+ && (registered_forks > 0))
|
||||
+ {
|
||||
+ printf ("FAILED fork called for WRDE_NOCMD\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
if (tc->flags & WRDE_DOOFFS)
|
||||
start_offs = sav_we.we_offs;
|
||||
|
||||
diff --git a/posix/wordexp.c b/posix/wordexp.c
|
||||
index b6b65dd..26f3a26 100644
|
||||
--- a/posix/wordexp.c
|
||||
+++ b/posix/wordexp.c
|
||||
@@ -893,6 +893,10 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
|
||||
pid_t pid;
|
||||
int noexec = 0;
|
||||
|
||||
+ /* Do nothing if command substitution should not succeed. */
|
||||
+ if (flags & WRDE_NOCMD)
|
||||
+ return WRDE_CMDSUB;
|
||||
+
|
||||
/* Don't fork() unless necessary */
|
||||
if (!comm || !*comm)
|
||||
return 0;
|
||||
@@ -2082,9 +2086,6 @@ parse_dollars (char **word, size_t *word_length, size_t *max_length,
|
||||
}
|
||||
}
|
||||
|
||||
- if (flags & WRDE_NOCMD)
|
||||
- return WRDE_CMDSUB;
|
||||
-
|
||||
(*offset) += 2;
|
||||
return parse_comm (word, word_length, max_length, words, offset, flags,
|
||||
quoted? NULL : pwordexp, ifs, ifs_white);
|
||||
@@ -2196,9 +2197,6 @@ parse_dquote (char **word, size_t *word_length, size_t *max_length,
|
||||
break;
|
||||
|
||||
case '`':
|
||||
- if (flags & WRDE_NOCMD)
|
||||
- return WRDE_CMDSUB;
|
||||
-
|
||||
++(*offset);
|
||||
error = parse_backtick (word, word_length, max_length, words,
|
||||
offset, flags, NULL, NULL, NULL);
|
||||
@@ -2357,12 +2355,6 @@ wordexp (const char *words, wordexp_t *pwordexp, int flags)
|
||||
break;
|
||||
|
||||
case '`':
|
||||
- if (flags & WRDE_NOCMD)
|
||||
- {
|
||||
- error = WRDE_CMDSUB;
|
||||
- goto do_error;
|
||||
- }
|
||||
-
|
||||
++words_offset;
|
||||
error = parse_backtick (&word, &word_length, &max_length, words,
|
||||
&words_offset, flags, pwordexp, ifs,
|
||||
@@ -1,154 +0,0 @@
|
||||
commit 41488498b6d9440ee66ab033808cce8323bba7ac
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed Sep 3 19:45:43 2014 +0200
|
||||
|
||||
CVE-2014-6040: Crashes on invalid input in IBM gconv modules [BZ #17325]
|
||||
|
||||
These changes are based on the fix for BZ #14134 in commit
|
||||
6e230d11837f3ae7b375ea69d7905f0d18eb79e5.
|
||||
|
||||
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
|
||||
index 0a410a1..b6327d6 100644
|
||||
--- a/iconvdata/Makefile
|
||||
+++ b/iconvdata/Makefile
|
||||
@@ -297,6 +297,7 @@ $(objpfx)tst-iconv7.out: $(objpfx)gconv-modules \
|
||||
$(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
|
||||
$(addprefix $(objpfx),$(modules.so)) \
|
||||
$(common-objdir)/iconv/iconv_prog TESTS
|
||||
+ iconv_modules="$(modules)" \
|
||||
$(SHELL) -e $< $(common-objdir) > $@
|
||||
|
||||
$(objpfx)tst-tables.out: tst-tables.sh $(objpfx)gconv-modules \
|
||||
diff --git a/iconvdata/ibm1364.c b/iconvdata/ibm1364.c
|
||||
index 0b5484f..cf80993 100644
|
||||
--- a/iconvdata/ibm1364.c
|
||||
+++ b/iconvdata/ibm1364.c
|
||||
@@ -221,7 +221,8 @@ enum
|
||||
++rp2; \
|
||||
\
|
||||
uint32_t res; \
|
||||
- if (__builtin_expect (ch < rp2->start, 0) \
|
||||
+ if (__builtin_expect (rp2->start == 0xffff, 0) \
|
||||
+ || __builtin_expect (ch < rp2->start, 0) \
|
||||
|| (res = DB_TO_UCS4[ch + rp2->idx], \
|
||||
__builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \
|
||||
{ \
|
||||
diff --git a/iconvdata/ibm932.c b/iconvdata/ibm932.c
|
||||
index f5dca59..aa69d65 100644
|
||||
--- a/iconvdata/ibm932.c
|
||||
+++ b/iconvdata/ibm932.c
|
||||
@@ -74,11 +74,12 @@
|
||||
} \
|
||||
\
|
||||
ch = (ch * 0x100) + inptr[1]; \
|
||||
+ /* ch was less than 0xfd. */ \
|
||||
+ assert (ch < 0xfd00); \
|
||||
while (ch > rp2->end) \
|
||||
++rp2; \
|
||||
\
|
||||
- if (__builtin_expect (rp2 == NULL, 0) \
|
||||
- || __builtin_expect (ch < rp2->start, 0) \
|
||||
+ if (__builtin_expect (ch < rp2->start, 0) \
|
||||
|| (res = __ibm932db_to_ucs4[ch + rp2->idx], \
|
||||
__builtin_expect (res, '\1') == 0 && ch !=0)) \
|
||||
{ \
|
||||
diff --git a/iconvdata/ibm933.c b/iconvdata/ibm933.c
|
||||
index f46dfb5..461fb5e 100644
|
||||
--- a/iconvdata/ibm933.c
|
||||
+++ b/iconvdata/ibm933.c
|
||||
@@ -162,7 +162,7 @@ enum
|
||||
while (ch > rp2->end) \
|
||||
++rp2; \
|
||||
\
|
||||
- if (__builtin_expect (rp2 == NULL, 0) \
|
||||
+ if (__builtin_expect (rp2->start == 0xffff, 0) \
|
||||
|| __builtin_expect (ch < rp2->start, 0) \
|
||||
|| (res = __ibm933db_to_ucs4[ch + rp2->idx], \
|
||||
__builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \
|
||||
diff --git a/iconvdata/ibm935.c b/iconvdata/ibm935.c
|
||||
index a8e4e6c..132d816 100644
|
||||
--- a/iconvdata/ibm935.c
|
||||
+++ b/iconvdata/ibm935.c
|
||||
@@ -162,7 +162,7 @@ enum
|
||||
while (ch > rp2->end) \
|
||||
++rp2; \
|
||||
\
|
||||
- if (__builtin_expect (rp2 == NULL, 0) \
|
||||
+ if (__builtin_expect (rp2->start == 0xffff, 0) \
|
||||
|| __builtin_expect (ch < rp2->start, 0) \
|
||||
|| (res = __ibm935db_to_ucs4[ch + rp2->idx], \
|
||||
__builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \
|
||||
diff --git a/iconvdata/ibm937.c b/iconvdata/ibm937.c
|
||||
index 239be61..69b154d 100644
|
||||
--- a/iconvdata/ibm937.c
|
||||
+++ b/iconvdata/ibm937.c
|
||||
@@ -162,7 +162,7 @@ enum
|
||||
while (ch > rp2->end) \
|
||||
++rp2; \
|
||||
\
|
||||
- if (__builtin_expect (rp2 == NULL, 0) \
|
||||
+ if (__builtin_expect (rp2->start == 0xffff, 0) \
|
||||
|| __builtin_expect (ch < rp2->start, 0) \
|
||||
|| (res = __ibm937db_to_ucs4[ch + rp2->idx], \
|
||||
__builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \
|
||||
diff --git a/iconvdata/ibm939.c b/iconvdata/ibm939.c
|
||||
index 5d0db36..9936e2c 100644
|
||||
--- a/iconvdata/ibm939.c
|
||||
+++ b/iconvdata/ibm939.c
|
||||
@@ -162,7 +162,7 @@ enum
|
||||
while (ch > rp2->end) \
|
||||
++rp2; \
|
||||
\
|
||||
- if (__builtin_expect (rp2 == NULL, 0) \
|
||||
+ if (__builtin_expect (rp2->start == 0xffff, 0) \
|
||||
|| __builtin_expect (ch < rp2->start, 0) \
|
||||
|| (res = __ibm939db_to_ucs4[ch + rp2->idx], \
|
||||
__builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \
|
||||
diff --git a/iconvdata/ibm943.c b/iconvdata/ibm943.c
|
||||
index be0c14f..c5d5742 100644
|
||||
--- a/iconvdata/ibm943.c
|
||||
+++ b/iconvdata/ibm943.c
|
||||
@@ -75,11 +75,12 @@
|
||||
} \
|
||||
\
|
||||
ch = (ch * 0x100) + inptr[1]; \
|
||||
+ /* ch was less than 0xfd. */ \
|
||||
+ assert (ch < 0xfd00); \
|
||||
while (ch > rp2->end) \
|
||||
++rp2; \
|
||||
\
|
||||
- if (__builtin_expect (rp2 == NULL, 0) \
|
||||
- || __builtin_expect (ch < rp2->start, 0) \
|
||||
+ if (__builtin_expect (ch < rp2->start, 0) \
|
||||
|| (res = __ibm943db_to_ucs4[ch + rp2->idx], \
|
||||
__builtin_expect (res, '\1') == 0 && ch !=0)) \
|
||||
{ \
|
||||
diff --git a/iconvdata/run-iconv-test.sh b/iconvdata/run-iconv-test.sh
|
||||
index c98c929..5dfb69f 100755
|
||||
--- a/iconvdata/run-iconv-test.sh
|
||||
+++ b/iconvdata/run-iconv-test.sh
|
||||
@@ -184,6 +184,24 @@ while read utf8 from filename; do
|
||||
|
||||
done < TESTS2
|
||||
|
||||
+# Check for crashes in decoders.
|
||||
+printf '\016\377\377\377\377\377\377\377' > $temp1
|
||||
+for from in $iconv_modules ; do
|
||||
+ echo $ac_n "test decoder $from $ac_c"
|
||||
+ PROG=`eval echo $ICONV`
|
||||
+ if $PROG < $temp1 >/dev/null 2>&1 ; then
|
||||
+ : # fall through
|
||||
+ else
|
||||
+ status=$?
|
||||
+ if test $status -gt 1 ; then
|
||||
+ echo "/FAILED"
|
||||
+ failed=1
|
||||
+ continue
|
||||
+ fi
|
||||
+ fi
|
||||
+ echo "OK"
|
||||
+done
|
||||
+
|
||||
exit $failed
|
||||
# Local Variables:
|
||||
# mode:shell-script
|
||||
@@ -1,22 +0,0 @@
|
||||
commit 7d81e8d6db95c112c297930a8f2f9617c305529a
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Dec 23 16:16:32 2014 +0100
|
||||
|
||||
iconvdata/run-iconv-test.sh: Actually test iconv modules
|
||||
|
||||
Arjun Shankar noticed that this test case was not testing anything
|
||||
because iconv was invoked without the required arguments.
|
||||
|
||||
diff --git a/iconvdata/run-iconv-test.sh b/iconvdata/run-iconv-test.sh
|
||||
index 5dfb69f..1d0bf52 100755
|
||||
--- a/iconvdata/run-iconv-test.sh
|
||||
+++ b/iconvdata/run-iconv-test.sh
|
||||
@@ -189,7 +189,7 @@ printf '\016\377\377\377\377\377\377\377' > $temp1
|
||||
for from in $iconv_modules ; do
|
||||
echo $ac_n "test decoder $from $ac_c"
|
||||
PROG=`eval echo $ICONV`
|
||||
- if $PROG < $temp1 >/dev/null 2>&1 ; then
|
||||
+ if $PROG -f $from -t UTF8 < $temp1 >/dev/null 2>&1 ; then
|
||||
: # fall through
|
||||
else
|
||||
status=$?
|
||||
@@ -1,223 +0,0 @@
|
||||
commit d5dd6189d506068ed11c8bfa1e1e9bffde04decd
|
||||
Author: Andreas Schwab <schwab@suse.de>
|
||||
Date: Mon Jan 21 17:41:28 2013 +0100
|
||||
|
||||
Fix parsing of numeric hosts in gethostbyname_r
|
||||
|
||||
diff --git a/nss/Makefile b/nss/Makefile
|
||||
index 449a258..553eafa 100644
|
||||
--- a/nss/Makefile
|
||||
+++ b/nss/Makefile
|
||||
@@ -37,7 +37,7 @@ install-bin := getent makedb
|
||||
others := getent
|
||||
install-bin := getent
|
||||
|
||||
-tests = test-netdb tst-nss-test1
|
||||
+tests = test-netdb tst-nss-test1 test-digits-dots
|
||||
xtests = bug-erange
|
||||
|
||||
include ../Makeconfig
|
||||
diff --git a/nss/digits_dots.c b/nss/digits_dots.c
|
||||
index 2b86295..e007ef4 100644
|
||||
--- a/nss/digits_dots.c
|
||||
+++ b/nss/digits_dots.c
|
||||
@@ -46,7 +46,10 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
|
||||
{
|
||||
if (h_errnop)
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
- *result = NULL;
|
||||
+ if (buffer_size == NULL)
|
||||
+ *status = NSS_STATUS_TRYAGAIN;
|
||||
+ else
|
||||
+ *result = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -83,14 +86,16 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
|
||||
}
|
||||
|
||||
size_needed = (sizeof (*host_addr)
|
||||
- + sizeof (*h_addr_ptrs) + strlen (name) + 1);
|
||||
+ + sizeof (*h_addr_ptrs)
|
||||
+ + sizeof (*h_alias_ptr) + strlen (name) + 1);
|
||||
|
||||
if (buffer_size == NULL)
|
||||
{
|
||||
if (buflen < size_needed)
|
||||
{
|
||||
+ *status = NSS_STATUS_TRYAGAIN;
|
||||
if (h_errnop != NULL)
|
||||
- *h_errnop = TRY_AGAIN;
|
||||
+ *h_errnop = NETDB_INTERNAL;
|
||||
__set_errno (ERANGE);
|
||||
goto done;
|
||||
}
|
||||
@@ -109,7 +114,7 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
|
||||
*buffer_size = 0;
|
||||
__set_errno (save);
|
||||
if (h_errnop != NULL)
|
||||
- *h_errnop = TRY_AGAIN;
|
||||
+ *h_errnop = NETDB_INTERNAL;
|
||||
*result = NULL;
|
||||
goto done;
|
||||
}
|
||||
@@ -149,7 +154,9 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
|
||||
if (! ok)
|
||||
{
|
||||
*h_errnop = HOST_NOT_FOUND;
|
||||
- if (buffer_size)
|
||||
+ if (buffer_size == NULL)
|
||||
+ *status = NSS_STATUS_NOTFOUND;
|
||||
+ else
|
||||
*result = NULL;
|
||||
goto done;
|
||||
}
|
||||
@@ -190,7 +197,7 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
|
||||
if (buffer_size == NULL)
|
||||
*status = NSS_STATUS_SUCCESS;
|
||||
else
|
||||
- *result = resbuf;
|
||||
+ *result = resbuf;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -201,15 +208,6 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
|
||||
|
||||
if ((isxdigit (name[0]) && strchr (name, ':') != NULL) || name[0] == ':')
|
||||
{
|
||||
- const char *cp;
|
||||
- char *hostname;
|
||||
- typedef unsigned char host_addr_t[16];
|
||||
- host_addr_t *host_addr;
|
||||
- typedef char *host_addr_list_t[2];
|
||||
- host_addr_list_t *h_addr_ptrs;
|
||||
- size_t size_needed;
|
||||
- int addr_size;
|
||||
-
|
||||
switch (af)
|
||||
{
|
||||
default:
|
||||
@@ -225,7 +223,10 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
|
||||
/* This is not possible. We cannot represent an IPv6 address
|
||||
in an `struct in_addr' variable. */
|
||||
*h_errnop = HOST_NOT_FOUND;
|
||||
- *result = NULL;
|
||||
+ if (buffer_size == NULL)
|
||||
+ *status = NSS_STATUS_NOTFOUND;
|
||||
+ else
|
||||
+ *result = NULL;
|
||||
goto done;
|
||||
|
||||
case AF_INET6:
|
||||
@@ -233,42 +234,6 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
|
||||
break;
|
||||
}
|
||||
|
||||
- size_needed = (sizeof (*host_addr)
|
||||
- + sizeof (*h_addr_ptrs) + strlen (name) + 1);
|
||||
-
|
||||
- if (buffer_size == NULL && buflen < size_needed)
|
||||
- {
|
||||
- if (h_errnop != NULL)
|
||||
- *h_errnop = TRY_AGAIN;
|
||||
- __set_errno (ERANGE);
|
||||
- goto done;
|
||||
- }
|
||||
- else if (buffer_size != NULL && *buffer_size < size_needed)
|
||||
- {
|
||||
- char *new_buf;
|
||||
- *buffer_size = size_needed;
|
||||
- new_buf = realloc (*buffer, *buffer_size);
|
||||
-
|
||||
- if (new_buf == NULL)
|
||||
- {
|
||||
- save = errno;
|
||||
- free (*buffer);
|
||||
- __set_errno (save);
|
||||
- *buffer = NULL;
|
||||
- *buffer_size = 0;
|
||||
- *result = NULL;
|
||||
- goto done;
|
||||
- }
|
||||
- *buffer = new_buf;
|
||||
- }
|
||||
-
|
||||
- memset (*buffer, '\0', size_needed);
|
||||
-
|
||||
- host_addr = (host_addr_t *) *buffer;
|
||||
- h_addr_ptrs = (host_addr_list_t *)
|
||||
- ((char *) host_addr + sizeof (*host_addr));
|
||||
- hostname = (char *) h_addr_ptrs + sizeof (*h_addr_ptrs);
|
||||
-
|
||||
for (cp = name;; ++cp)
|
||||
{
|
||||
if (!*cp)
|
||||
@@ -281,7 +246,9 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
|
||||
if (inet_pton (AF_INET6, name, host_addr) <= 0)
|
||||
{
|
||||
*h_errnop = HOST_NOT_FOUND;
|
||||
- if (buffer_size)
|
||||
+ if (buffer_size == NULL)
|
||||
+ *status = NSS_STATUS_NOTFOUND;
|
||||
+ else
|
||||
*result = NULL;
|
||||
goto done;
|
||||
}
|
||||
diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c
|
||||
index 1067744..44d00f4 100644
|
||||
--- a/nss/getXXbyYY_r.c
|
||||
+++ b/nss/getXXbyYY_r.c
|
||||
@@ -179,6 +179,9 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
|
||||
case -1:
|
||||
return errno;
|
||||
case 1:
|
||||
+#ifdef NEED_H_ERRNO
|
||||
+ any_service = true;
|
||||
+#endif
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
diff --git a/nss/test-digits-dots.c b/nss/test-digits-dots.c
|
||||
new file mode 100644
|
||||
index 0000000..1efa344
|
||||
--- /dev/null
|
||||
+++ b/nss/test-digits-dots.c
|
||||
@@ -0,0 +1,38 @@
|
||||
+/* 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/>. */
|
||||
+
|
||||
+/* Testcase for BZ #15014 */
|
||||
+
|
||||
+#include <stdlib.h>
|
||||
+#include <netdb.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ char buf[32];
|
||||
+ struct hostent *result = NULL;
|
||||
+ struct hostent ret;
|
||||
+ int h_err = 0;
|
||||
+ int err;
|
||||
+
|
||||
+ err = gethostbyname_r ("1.2.3.4", &ret, buf, sizeof (buf), &result, &h_err);
|
||||
+ return err == ERANGE && h_err == NETDB_INTERNAL ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#include "../test-skeleton.c"
|
||||
@@ -1,481 +0,0 @@
|
||||
#
|
||||
# Based on AVX-512 support for glibc, but heavaily modified for rhel-6.7.
|
||||
# Without assembler support we drop all of the configure checks and simply
|
||||
# output using .byte directives the minimal AVX512 instructsion required
|
||||
# by the loader. Likewise testing is also impossible, so instead we use
|
||||
# the Intel emulator running in `-skx` (Skylake Xeon) emulation mode and
|
||||
# verify that a pre-built set of tests passes.
|
||||
#
|
||||
# commit 6986b98a18490e76b16911d1c6b1ba013598d40d
|
||||
# Author: Ulrich Drepper <drepper@gmail.com>
|
||||
# Date: Wed Jul 20 14:20:00 2011 -0400
|
||||
#
|
||||
# Force :a_x86_64_ymm to be 16-byte aligned
|
||||
#
|
||||
# commit aa4de9cea5c07d43caeaca9722c2d417e9a2919c
|
||||
# Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
# Date: Fri Mar 14 08:51:25 2014 -0700
|
||||
#
|
||||
# Check AVX-512 assembler support first
|
||||
#
|
||||
# It checks AVX-512 assembler support first and sets libc_cv_cc_avx512 to
|
||||
# $libc_cv_asm_avx512, instead of yes. GCC won't support AVX-512 if
|
||||
# assembler doesn't support it.
|
||||
#
|
||||
# * sysdeps/x86_64/configure.ac: Check AVX-512 assembler support
|
||||
# first. Disable AVX-512 GCC support if assembler doesn't support
|
||||
# it.
|
||||
# * sysdeps/x86_64/configure: Regenerated.
|
||||
#
|
||||
# commit 2d63a517e4084ec80403cd9f278690fa8b676cc4
|
||||
# Author: Igor Zamyatin <igor.zamyatin@intel.com>
|
||||
# Date: Thu Mar 13 11:10:22 2014 -0700
|
||||
#
|
||||
# Save and restore AVX-512 zmm registers to x86-64 ld.so
|
||||
#
|
||||
# AVX-512 ISA adds 512-bit zmm registers. This patch updates
|
||||
# _dl_runtime_profile to pass zmm registers to run-time audit. It also
|
||||
# changes _dl_x86_64_save_sse and _dl_x86_64_restore_sse to upport zmm
|
||||
# registers, which are called when only when RTLD_PREPARE_FOREIGN_CALL
|
||||
# is used. Its performance impact is minimum.
|
||||
#
|
||||
# * config.h.in (HAVE_AVX512_SUPPORT): New #undef.
|
||||
# (HAVE_AVX512_ASM_SUPPORT): Likewise.
|
||||
# * sysdeps/x86_64/bits/link.h (La_x86_64_zmm): New.
|
||||
# (La_x86_64_vector): Add zmm.
|
||||
# * sysdeps/x86_64/Makefile (tests): Add tst-audit10.
|
||||
# (modules-names): Add tst-auditmod10a and tst-auditmod10b.
|
||||
# ($(objpfx)tst-audit10): New target.
|
||||
# ($(objpfx)tst-audit10.out): Likewise.
|
||||
# (tst-audit10-ENV): New.
|
||||
# (AVX512-CFLAGS): Likewise.
|
||||
# (CFLAGS-tst-audit10.c): Likewise.
|
||||
# (CFLAGS-tst-auditmod10a.c): Likewise.
|
||||
# (CFLAGS-tst-auditmod10b.c): Likewise.
|
||||
# * sysdeps/x86_64/configure.ac: Set config-cflags-avx512,
|
||||
# HAVE_AVX512_SUPPORT and HAVE_AVX512_ASM_SUPPORT.
|
||||
# * sysdeps/x86_64/configure: Regenerated.
|
||||
# * sysdeps/x86_64/dl-trampoline.S (_dl_runtime_profile): Add
|
||||
# AVX-512 zmm register support.
|
||||
# (_dl_x86_64_save_sse): Likewise.
|
||||
# (_dl_x86_64_restore_sse): Likewise.
|
||||
# * sysdeps/x86_64/dl-trampoline.h: Updated to support different
|
||||
# size vector registers.
|
||||
# * sysdeps/x86_64/link-defines.sym (YMM_SIZE): New.
|
||||
# (ZMM_SIZE): Likewise.
|
||||
# * sysdeps/x86_64/tst-audit10.c: New file.
|
||||
# * sysdeps/x86_64/tst-auditmod10a.c: Likewise.
|
||||
# * sysdeps/x86_64/tst-auditmod10b.c: Likewise.
|
||||
#
|
||||
# In addition adds:
|
||||
# https://sourceware.org/ml/libc-alpha/2014-09/msg00228.html
|
||||
# To extend zmm register checking.
|
||||
#
|
||||
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/x86_64/bits/link.h glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/bits/link.h
|
||||
--- glibc-2.12-2-gc4ccff1/sysdeps/x86_64/bits/link.h 2010-05-04 07:27:23.000000000 -0400
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/bits/link.h 2015-03-03 23:03:25.041829238 -0500
|
||||
@@ -65,7 +65,10 @@
|
||||
/* Registers for entry into PLT on x86-64. */
|
||||
# if __GNUC_PREREQ (4,0)
|
||||
typedef float La_x86_64_xmm __attribute__ ((__vector_size__ (16)));
|
||||
-typedef float La_x86_64_ymm __attribute__ ((__vector_size__ (32)));
|
||||
+typedef float La_x86_64_ymm __attribute__ ((__vector_size__ (32),
|
||||
+ __aligned__ (16)));
|
||||
+typedef double La_x86_64_zmm __attribute__ ((__vector_size__ (64),
|
||||
+ __aligned__ (16)));
|
||||
# else
|
||||
typedef float La_x86_64_xmm __attribute__ ((__mode__ (__V4SF__)));
|
||||
# endif
|
||||
@@ -74,9 +77,10 @@
|
||||
{
|
||||
# if __GNUC_PREREQ (4,0)
|
||||
La_x86_64_ymm ymm[2];
|
||||
+ La_x86_64_zmm zmm[1];
|
||||
# endif
|
||||
La_x86_64_xmm xmm[4];
|
||||
-} La_x86_64_vector __attribute__ ((aligned(16)));
|
||||
+} La_x86_64_vector __attribute__ ((__aligned__(16)));
|
||||
|
||||
typedef struct La_x86_64_regs
|
||||
{
|
||||
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/x86_64/dl-trampoline.h glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/dl-trampoline.h
|
||||
--- glibc-2.12-2-gc4ccff1/sysdeps/x86_64/dl-trampoline.h 2015-03-03 23:03:05.109457627 -0500
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/dl-trampoline.h 2015-03-03 23:06:58.434101818 -0500
|
||||
@@ -20,14 +20,26 @@
|
||||
|
||||
#ifdef RESTORE_AVX
|
||||
/* This is to support AVX audit modules. */
|
||||
- vmovdqu %ymm0, (LR_VECTOR_OFFSET)(%rsp)
|
||||
- vmovdqu %ymm1, (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp)
|
||||
- vmovdqu %ymm2, (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp)
|
||||
- vmovdqu %ymm3, (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp)
|
||||
- vmovdqu %ymm4, (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp)
|
||||
- vmovdqu %ymm5, (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp)
|
||||
- vmovdqu %ymm6, (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp)
|
||||
- vmovdqu %ymm7, (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp)
|
||||
+# if HAVE_NO_AVX512_ASM_SUPPORT
|
||||
+ /* Restore AVX-512 registers. Use .byte becaues we lack assembler support. */
|
||||
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x44,0x24,0x03 # vmovdqu64 %zmm0,0xc0(%rsp)
|
||||
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x4c,0x24,0x04 # vmovdqu64 %zmm1,0x100(%rsp)
|
||||
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x54,0x24,0x05 # vmovdqu64 %zmm2,0x140(%rsp)
|
||||
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x5c,0x24,0x06 # vmovdqu64 %zmm3,0x180(%rsp)
|
||||
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x64,0x24,0x07 # vmovdqu64 %zmm4,0x1c0(%rsp)
|
||||
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x6c,0x24,0x08 # vmovdqu64 %zmm5,0x200(%rsp)
|
||||
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x74,0x24,0x09 # vmovdqu64 %zmm6,0x240(%rsp)
|
||||
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x7c,0x24,0x0a # vmovdqu64 %zmm7,0x280(%rsp)
|
||||
+# else
|
||||
+ VMOV %VEC(0), (LR_VECTOR_OFFSET)(%rsp)
|
||||
+ VMOV %VEC(1), (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp)
|
||||
+ VMOV %VEC(2), (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp)
|
||||
+ VMOV %VEC(3), (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp)
|
||||
+ VMOV %VEC(4), (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp)
|
||||
+ VMOV %VEC(5), (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp)
|
||||
+ VMOV %VEC(6), (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp)
|
||||
+ VMOV %VEC(7), (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp)
|
||||
+# endif
|
||||
|
||||
/* Save xmm0-xmm7 registers to detect if any of them are
|
||||
changed by audit module. */
|
||||
@@ -73,7 +85,11 @@
|
||||
je 2f
|
||||
vmovdqa %xmm0, (LR_VECTOR_OFFSET)(%rsp)
|
||||
jmp 1f
|
||||
-2: vmovdqu (LR_VECTOR_OFFSET)(%rsp), %ymm0
|
||||
+# if HAVE_NO_AVX512_ASM_SUPPORT
|
||||
+2: .byte 0x62,0xf1,0xfe,0x48,0x6f,0x44,0x24,0x03 # vmovdqu64 0xc0(%rsp),%zmm0
|
||||
+# else
|
||||
+2: VMOV (LR_VECTOR_OFFSET)(%rsp), %VEC(0)
|
||||
+# endif
|
||||
vmovdqa %xmm0, (LR_XMM_OFFSET)(%rsp)
|
||||
|
||||
1: vpcmpeqq (LR_SIZE + XMM_SIZE)(%rsp), %xmm1, %xmm8
|
||||
@@ -82,7 +98,11 @@
|
||||
je 2f
|
||||
vmovdqa %xmm1, (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp)
|
||||
jmp 1f
|
||||
-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp), %ymm1
|
||||
+# if HAVE_NO_AVX512_ASM_SUPPORT
|
||||
+2: .byte 0x62,0xf1,0xfe,0x48,0x6f,0x4c,0x24,0x04 # vmovdqu64 0x100(%rsp),%zmm1
|
||||
+# else
|
||||
+2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp), %VEC(1)
|
||||
+# endif
|
||||
vmovdqa %xmm1, (LR_XMM_OFFSET + XMM_SIZE)(%rsp)
|
||||
|
||||
1: vpcmpeqq (LR_SIZE + XMM_SIZE*2)(%rsp), %xmm2, %xmm8
|
||||
@@ -91,7 +111,11 @@
|
||||
je 2f
|
||||
vmovdqa %xmm2, (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp)
|
||||
jmp 1f
|
||||
-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp), %ymm2
|
||||
+# if HAVE_NO_AVX512_ASM_SUPPORT
|
||||
+2: .byte 0x62,0xf1,0xfe,0x48,0x6f,0x54,0x24,0x05 # vmovdqu64 0x140(%rsp),%zmm2
|
||||
+# else
|
||||
+2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp), %VEC(2)
|
||||
+# endif
|
||||
vmovdqa %xmm2, (LR_XMM_OFFSET + XMM_SIZE*2)(%rsp)
|
||||
|
||||
1: vpcmpeqq (LR_SIZE + XMM_SIZE*3)(%rsp), %xmm3, %xmm8
|
||||
@@ -100,7 +124,11 @@
|
||||
je 2f
|
||||
vmovdqa %xmm3, (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp)
|
||||
jmp 1f
|
||||
-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp), %ymm3
|
||||
+# if HAVE_NO_AVX512_ASM_SUPPORT
|
||||
+2: .byte 0x62,0xf1,0xfe,0x48,0x6f,0x5c,0x24,0x06 # vmovdqu64 0x180(%rsp),%zmm3
|
||||
+# else
|
||||
+2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp), %VEC(3)
|
||||
+# endif
|
||||
vmovdqa %xmm3, (LR_XMM_OFFSET + XMM_SIZE*3)(%rsp)
|
||||
|
||||
1: vpcmpeqq (LR_SIZE + XMM_SIZE*4)(%rsp), %xmm4, %xmm8
|
||||
@@ -109,7 +137,11 @@
|
||||
je 2f
|
||||
vmovdqa %xmm4, (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp)
|
||||
jmp 1f
|
||||
-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp), %ymm4
|
||||
+# if HAVE_NO_AVX512_ASM_SUPPORT
|
||||
+2: .byte 0x62,0xf1,0xfe,0x48,0x6f,0x64,0x24,0x07 # vmovdqu64 0x1c0(%rsp),%zmm4
|
||||
+# else
|
||||
+2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp), %VEC(4)
|
||||
+# endif
|
||||
vmovdqa %xmm4, (LR_XMM_OFFSET + XMM_SIZE*4)(%rsp)
|
||||
|
||||
1: vpcmpeqq (LR_SIZE + XMM_SIZE*5)(%rsp), %xmm5, %xmm8
|
||||
@@ -118,7 +150,11 @@
|
||||
je 2f
|
||||
vmovdqa %xmm5, (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp)
|
||||
jmp 1f
|
||||
-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp), %ymm5
|
||||
+# if HAVE_NO_AVX512_ASM_SUPPORT
|
||||
+2: .byte 0x62,0xf1,0xfe,0x48,0x6f,0x6c,0x24,0x08 # vmovdqu64 0x200(%rsp),%zmm5
|
||||
+# else
|
||||
+2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp), %VEC(5)
|
||||
+# endif
|
||||
vmovdqa %xmm5, (LR_XMM_OFFSET + XMM_SIZE*5)(%rsp)
|
||||
|
||||
1: vpcmpeqq (LR_SIZE + XMM_SIZE*6)(%rsp), %xmm6, %xmm8
|
||||
@@ -127,7 +163,11 @@
|
||||
je 2f
|
||||
vmovdqa %xmm6, (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp)
|
||||
jmp 1f
|
||||
-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp), %ymm6
|
||||
+# if HAVE_NO_AVX512_ASM_SUPPORT
|
||||
+2: .byte 0x62,0xf1,0xfe,0x48,0x6f,0x74,0x24,0x09 # vmovdqu64 0x240(%rsp),%zmm6
|
||||
+# else
|
||||
+2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp), %VEC(6)
|
||||
+# endif
|
||||
vmovdqa %xmm6, (LR_XMM_OFFSET + XMM_SIZE*6)(%rsp)
|
||||
|
||||
1: vpcmpeqq (LR_SIZE + XMM_SIZE*7)(%rsp), %xmm7, %xmm8
|
||||
@@ -136,7 +176,11 @@
|
||||
je 2f
|
||||
vmovdqa %xmm7, (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp)
|
||||
jmp 1f
|
||||
-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp), %ymm7
|
||||
+# if HAVE_NO_AVX512_ASM_SUPPORT
|
||||
+2: .byte 0x62,0xf1,0xfe,0x48,0x6f,0x7c,0x24,0x0a # vmovdqu64 0x280(%rsp),%zmm7
|
||||
+# else
|
||||
+2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp), %VEC(7)
|
||||
+# endif
|
||||
vmovdqa %xmm7, (LR_XMM_OFFSET + XMM_SIZE*7)(%rsp)
|
||||
|
||||
1:
|
||||
@@ -214,8 +258,13 @@
|
||||
|
||||
#ifdef RESTORE_AVX
|
||||
/* This is to support AVX audit modules. */
|
||||
- vmovdqu %ymm0, LRV_VECTOR0_OFFSET(%rcx)
|
||||
- vmovdqu %ymm1, LRV_VECTOR1_OFFSET(%rcx)
|
||||
+# if HAVE_NO_AVX512_ASM_SUPPORT
|
||||
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x81,0x50,0x00,0x00,0x00 # vmovdqu64 %zmm0,0x50(%rcx)
|
||||
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x89,0x90,0x00,0x00,0x00 # vmovdqu64 %zmm1,0x90(%rcx)
|
||||
+# else
|
||||
+ VMOV %VEC(0), LRV_VECTOR0_OFFSET(%rcx)
|
||||
+ VMOV %VEC(1), LRV_VECTOR1_OFFSET(%rcx)
|
||||
+# endif
|
||||
|
||||
/* Save xmm0/xmm1 registers to detect if they are changed
|
||||
by audit module. */
|
||||
@@ -244,13 +293,21 @@
|
||||
vpmovmskb %xmm2, %esi
|
||||
cmpl $0xffff, %esi
|
||||
jne 1f
|
||||
- vmovdqu LRV_VECTOR0_OFFSET(%rsp), %ymm0
|
||||
+# if HAVE_NO_AVX512_ASM_SUPPORT
|
||||
+ .byte 0x62,0xf1,0xfe,0x48,0x6f,0x84,0x24,0x50,0x00,0x00,0x00 # vmovdqu64 0x50(%rsp),%zmm0
|
||||
+# else
|
||||
+ VMOV LRV_VECTOR0_OFFSET(%rsp), %VEC(0)
|
||||
+# endif
|
||||
|
||||
1: vpcmpeqq (LRV_SIZE + XMM_SIZE)(%rsp), %xmm1, %xmm2
|
||||
vpmovmskb %xmm2, %esi
|
||||
cmpl $0xffff, %esi
|
||||
jne 1f
|
||||
- vmovdqu LRV_VECTOR1_OFFSET(%rsp), %ymm1
|
||||
+# if HAVE_NO_AVX512_ASM_SUPPORT
|
||||
+ .byte 0x62,0xf1,0xfe,0x48,0x6f,0x8c,0x24,0x90,0x00,0x00,0x00 # vmovdqu64 0x90(%rsp),%zmm1
|
||||
+# else
|
||||
+ VMOV LRV_VECTOR1_OFFSET(%rsp), %VEC(1)
|
||||
+# endif
|
||||
|
||||
1:
|
||||
#endif
|
||||
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/x86_64/dl-trampoline.S glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/dl-trampoline.S
|
||||
--- glibc-2.12-2-gc4ccff1/sysdeps/x86_64/dl-trampoline.S 2015-03-03 23:03:05.108457659 -0500
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/dl-trampoline.S 2015-03-03 23:07:31.799049953 -0500
|
||||
@@ -134,7 +134,7 @@
|
||||
.previous
|
||||
|
||||
cmpl $0, L(have_avx)(%rip)
|
||||
- jne 1f
|
||||
+ jne L(defined)
|
||||
movq %rbx, %r11 # Save rbx
|
||||
movl $1, %eax
|
||||
cpuid
|
||||
@@ -143,18 +143,51 @@
|
||||
// AVX and XSAVE supported?
|
||||
andl $((1 << 28) | (1 << 27)), %ecx
|
||||
cmpl $((1 << 28) | (1 << 27)), %ecx
|
||||
- jne 2f
|
||||
+ jne 10f
|
||||
+ // AVX512 supported in processor?
|
||||
+ movq %rbx, %r11 # Save rbx
|
||||
+ xorl %ecx, %ecx
|
||||
+ mov $0x7, %eax
|
||||
+ cpuid
|
||||
+ andl $(1 << 16), %ebx
|
||||
xorl %ecx, %ecx
|
||||
// Get XFEATURE_ENABLED_MASK
|
||||
xgetbv
|
||||
- andl $0x6, %eax
|
||||
-2: subl $0x5, %eax
|
||||
+ test %ebx, %ebx
|
||||
+ movq %r11, %rbx # Restore rbx
|
||||
+ je 20f
|
||||
+ // Verify that XCR0[7:5] = '111b' and
|
||||
+ // XCR0[2:1] = '11b' which means
|
||||
+ // that zmm state is enabled
|
||||
+ andl $0xe6, %eax
|
||||
+ cmpl $0xe6, %eax
|
||||
+ jne 20f
|
||||
+ movl %eax, L(have_avx)(%rip)
|
||||
+L(avx512):
|
||||
+# define RESTORE_AVX
|
||||
+# define HAVE_NO_AVX512_ASM_SUPPORT 1
|
||||
+# define VMOV vmovdqu64
|
||||
+# define VEC(i) zmm##i
|
||||
+# define MORE_CODE
|
||||
+# include "dl-trampoline.h"
|
||||
+# undef VMOV
|
||||
+# undef VEC
|
||||
+# undef RESTORE_AVX
|
||||
+# undef HAVE_NO_AVX512_ASM_SUPPORT
|
||||
+20: andl $0x6, %eax
|
||||
+10: subl $0x5, %eax
|
||||
movl %eax, L(have_avx)(%rip)
|
||||
cmpl $0, %eax
|
||||
|
||||
-1: js L(no_avx)
|
||||
+L(defined):
|
||||
+ js L(no_avx)
|
||||
+ cmpl $0xe6, L(have_avx)(%rip)
|
||||
+ je L(avx512)
|
||||
+
|
||||
|
||||
# define RESTORE_AVX
|
||||
+# define VMOV vmovdqu
|
||||
+# define VEC(i) ymm##i
|
||||
# define MORE_CODE
|
||||
# include "dl-trampoline.h"
|
||||
|
||||
@@ -178,7 +211,7 @@
|
||||
_dl_x86_64_save_sse:
|
||||
# ifdef HAVE_AVX_SUPPORT
|
||||
cmpl $0, L(have_avx)(%rip)
|
||||
- jne 1f
|
||||
+ jne L(defined_5)
|
||||
movq %rbx, %r11 # Save rbx
|
||||
movl $1, %eax
|
||||
cpuid
|
||||
@@ -187,21 +220,37 @@
|
||||
// AVX and XSAVE supported?
|
||||
andl $((1 << 28) | (1 << 27)), %ecx
|
||||
cmpl $((1 << 28) | (1 << 27)), %ecx
|
||||
- jne 2f
|
||||
+ jne 1f
|
||||
+ // AVX512 supported in a processor?
|
||||
+ movq %rbx, %r11 # Save rbx
|
||||
+ xorl %ecx,%ecx
|
||||
+ mov $0x7,%eax
|
||||
+ cpuid
|
||||
+ andl $(1 << 16), %ebx
|
||||
xorl %ecx, %ecx
|
||||
// Get XFEATURE_ENABLED_MASK
|
||||
xgetbv
|
||||
- andl $0x6, %eax
|
||||
- cmpl $0x6, %eax
|
||||
- // Nonzero if SSE and AVX state saving is enabled.
|
||||
- sete %al
|
||||
-2: leal -1(%eax,%eax), %eax
|
||||
+ test %ebx, %ebx
|
||||
+ movq %r11, %rbx # Restore rbx
|
||||
+ je 2f
|
||||
+ // Verify that XCR0[7:5] = '111b' and
|
||||
+ // XCR0[2:1] = '11b' which means
|
||||
+ // that zmm state is enabled
|
||||
+ andl $0xe6, %eax
|
||||
movl %eax, L(have_avx)(%rip)
|
||||
- cmpl $0, %eax
|
||||
+ cmpl $0xe6, %eax
|
||||
+ je L(avx512_5)
|
||||
|
||||
-1: js L(no_avx5)
|
||||
+2: andl $0x6, %eax
|
||||
+1: subl $0x5, %eax
|
||||
+ movl %eax, L(have_avx)(%rip)
|
||||
+ cmpl $0, %eax
|
||||
|
||||
-# define YMM_SIZE 32
|
||||
+L(defined_5):
|
||||
+ js L(no_avx5)
|
||||
+ cmpl $0xe6, L(have_avx)(%rip)
|
||||
+ je L(avx512_5)
|
||||
+
|
||||
vmovdqa %ymm0, %fs:RTLD_SAVESPACE_SSE+0*YMM_SIZE
|
||||
vmovdqa %ymm1, %fs:RTLD_SAVESPACE_SSE+1*YMM_SIZE
|
||||
vmovdqa %ymm2, %fs:RTLD_SAVESPACE_SSE+2*YMM_SIZE
|
||||
@@ -211,6 +260,26 @@
|
||||
vmovdqa %ymm6, %fs:RTLD_SAVESPACE_SSE+6*YMM_SIZE
|
||||
vmovdqa %ymm7, %fs:RTLD_SAVESPACE_SSE+7*YMM_SIZE
|
||||
ret
|
||||
+L(avx512_5):
|
||||
+# Original instructions:
|
||||
+# vmovdqu64 %zmm0, %fs:RTLD_SAVESPACE_SSE+0*ZMM_SIZE
|
||||
+# vmovdqu64 %zmm1, %fs:RTLD_SAVESPACE_SSE+1*ZMM_SIZE
|
||||
+# vmovdqu64 %zmm2, %fs:RTLD_SAVESPACE_SSE+2*ZMM_SIZE
|
||||
+# vmovdqu64 %zmm3, %fs:RTLD_SAVESPACE_SSE+3*ZMM_SIZE
|
||||
+# vmovdqu64 %zmm4, %fs:RTLD_SAVESPACE_SSE+4*ZMM_SIZE
|
||||
+# vmovdqu64 %zmm5, %fs:RTLD_SAVESPACE_SSE+5*ZMM_SIZE
|
||||
+# vmovdqu64 %zmm6, %fs:RTLD_SAVESPACE_SSE+6*ZMM_SIZE
|
||||
+# vmovdqu64 %zmm7, %fs:RTLD_SAVESPACE_SSE+7*ZMM_SIZE
|
||||
+# Assembled instructions:
|
||||
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x7f,0x04,0x25,0x80,0x00,0x00,0x00 # vmovdqu64 %zmm0,%fs:0x80
|
||||
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x7f,0x0c,0x25,0xc0,0x00,0x00,0x00 # vmovdqu64 %zmm1,%fs:0xc0
|
||||
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x7f,0x14,0x25,0x00,0x01,0x00,0x00 # vmovdqu64 %zmm2,%fs:0x100
|
||||
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x7f,0x1c,0x25,0x40,0x01,0x00,0x00 # vmovdqu64 %zmm3,%fs:0x140
|
||||
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x7f,0x24,0x25,0x80,0x01,0x00,0x00 # vmovdqu64 %zmm4,%fs:0x180
|
||||
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x7f,0x2c,0x25,0xc0,0x01,0x00,0x00 # vmovdqu64 %zmm5,%fs:0x1c0
|
||||
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x7f,0x34,0x25,0x00,0x02,0x00,0x00 # vmovdqu64 %zmm6,%fs:0x200
|
||||
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x7f,0x3c,0x25,0x40,0x02,0x00,0x00 # vmovdqu64 %zmm7,%fs:0x240
|
||||
+ ret
|
||||
L(no_avx5):
|
||||
# endif
|
||||
movdqa %xmm0, %fs:RTLD_SAVESPACE_SSE+0*XMM_SIZE
|
||||
@@ -234,6 +303,8 @@
|
||||
# ifdef HAVE_AVX_SUPPORT
|
||||
cmpl $0, L(have_avx)(%rip)
|
||||
js L(no_avx6)
|
||||
+ cmpl $0xe6, L(have_avx)(%rip)
|
||||
+ je L(avx512_6)
|
||||
|
||||
vmovdqa %fs:RTLD_SAVESPACE_SSE+0*YMM_SIZE, %ymm0
|
||||
vmovdqa %fs:RTLD_SAVESPACE_SSE+1*YMM_SIZE, %ymm1
|
||||
@@ -244,6 +315,26 @@
|
||||
vmovdqa %fs:RTLD_SAVESPACE_SSE+6*YMM_SIZE, %ymm6
|
||||
vmovdqa %fs:RTLD_SAVESPACE_SSE+7*YMM_SIZE, %ymm7
|
||||
ret
|
||||
+L(avx512_6):
|
||||
+# Original instructions:
|
||||
+# vmovdqu64 %fs:RTLD_SAVESPACE_SSE+0*ZMM_SIZE, %zmm0
|
||||
+# vmovdqu64 %fs:RTLD_SAVESPACE_SSE+1*ZMM_SIZE, %zmm1
|
||||
+# vmovdqu64 %fs:RTLD_SAVESPACE_SSE+2*ZMM_SIZE, %zmm2
|
||||
+# vmovdqu64 %fs:RTLD_SAVESPACE_SSE+3*ZMM_SIZE, %zmm3
|
||||
+# vmovdqu64 %fs:RTLD_SAVESPACE_SSE+4*ZMM_SIZE, %zmm4
|
||||
+# vmovdqu64 %fs:RTLD_SAVESPACE_SSE+5*ZMM_SIZE, %zmm5
|
||||
+# vmovdqu64 %fs:RTLD_SAVESPACE_SSE+6*ZMM_SIZE, %zmm6
|
||||
+# vmovdqu64 %fs:RTLD_SAVESPACE_SSE+7*ZMM_SIZE, %zmm7
|
||||
+# Assembled instructions:
|
||||
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x6f,0x04,0x25,0x80,0x00,0x00,0x00 # vmovdqu64 %fs:0x80,%zmm0
|
||||
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x6f,0x0c,0x25,0xc0,0x00,0x00,0x00 # vmovdqu64 %fs:0xc0,%zmm1
|
||||
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x6f,0x14,0x25,0x00,0x01,0x00,0x00 # vmovdqu64 %fs:0x100,%zmm2
|
||||
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x6f,0x1c,0x25,0x40,0x01,0x00,0x00 # vmovdqu64 %fs:0x140,%zmm3
|
||||
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x6f,0x24,0x25,0x80,0x01,0x00,0x00 # vmovdqu64 %fs:0x180,%zmm4
|
||||
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x6f,0x2c,0x25,0xc0,0x01,0x00,0x00 # vmovdqu64 %fs:0x1c0,%zmm5
|
||||
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x6f,0x34,0x25,0x00,0x02,0x00,0x00 # vmovdqu64 %fs:0x200,%zmm6
|
||||
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x6f,0x3c,0x25,0x40,0x02,0x00,0x00 # vmovdqu64 %fs:0x240,%zmm7
|
||||
+ ret
|
||||
L(no_avx6):
|
||||
# endif
|
||||
movdqa %fs:RTLD_SAVESPACE_SSE+0*XMM_SIZE, %xmm0
|
||||
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/x86_64/link-defines.sym glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/link-defines.sym
|
||||
--- glibc-2.12-2-gc4ccff1/sysdeps/x86_64/link-defines.sym 2010-05-04 07:27:23.000000000 -0400
|
||||
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/link-defines.sym 2015-03-03 23:03:25.042829206 -0500
|
||||
@@ -4,6 +4,8 @@
|
||||
--
|
||||
VECTOR_SIZE sizeof (La_x86_64_vector)
|
||||
XMM_SIZE sizeof (La_x86_64_xmm)
|
||||
+YMM_SIZE sizeof (La_x86_64_ymm)
|
||||
+ZMM_SIZE sizeof (La_x86_64_zmm)
|
||||
|
||||
LR_SIZE sizeof (struct La_x86_64_regs)
|
||||
LR_RDX_OFFSET offsetof (struct La_x86_64_regs, lr_rdx)
|
||||
@@ -1,12 +0,0 @@
|
||||
diff -pruN glibc-2.12-2-gc4ccff1/malloc/malloc.c glibc-2.12-2-gc4ccff1.new/malloc/malloc.c
|
||||
--- glibc-2.12-2-gc4ccff1/malloc/malloc.c 2015-04-10 12:02:54.011106386 +0530
|
||||
+++ glibc-2.12-2-gc4ccff1.new/malloc/malloc.c 2015-04-10 12:02:35.867958292 +0530
|
||||
@@ -5850,7 +5850,7 @@ _int_valloc(av, bytes) mstate av; size_t
|
||||
#endif
|
||||
{
|
||||
/* Ensure initialization/consolidation */
|
||||
- if (have_fastchunks(av)) malloc_consolidate(av);
|
||||
+ if (av && have_fastchunks(av)) malloc_consolidate(av);
|
||||
return _int_memalign(av, mp_.pagesize, bytes);
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
@@ -, +, @@
|
||||
resolv/nss_dns/dns-host.c:getanswer_r.
|
||||
---
|
||||
resolv/nss_dns/dns-host.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
--- a/resolv/nss_dns/dns-host.c
|
||||
+++ a/resolv/nss_dns/dns-host.c
|
||||
@@ -615,7 +615,8 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
int have_to_map = 0;
|
||||
uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
|
||||
buffer += pad;
|
||||
- if (__builtin_expect (buflen < sizeof (struct host_data) + pad, 0))
|
||||
+ buflen = buflen > pad ? buflen - pad : 0;
|
||||
+ if (__builtin_expect (buflen < sizeof (struct host_data), 0))
|
||||
{
|
||||
/* The buffer is too small. */
|
||||
too_small:
|
||||
--
|
||||
@@ -1,65 +0,0 @@
|
||||
#
|
||||
# Author: Carlos O'Donell
|
||||
# Upstream status: Needs to go upstream (2015-05-07)
|
||||
#
|
||||
diff --git a/inet/rcmd.c b/inet/rcmd.c
|
||||
index acacaa0..9f2443b 100644
|
||||
--- a/inet/rcmd.c
|
||||
+++ b/inet/rcmd.c
|
||||
@@ -803,29 +803,38 @@ __validuser2_sa(hostf, ra, ralen, luser, ruser, rhost)
|
||||
*p = '\0'; /* <nul> terminate username (+host?) */
|
||||
|
||||
/* buf -> host(?) ; user -> username(?) */
|
||||
+ if (*buf == '\0')
|
||||
+ break;
|
||||
+ if (*user == '\0')
|
||||
+ user = luser;
|
||||
+
|
||||
+ /* First check the user part. This is an optimization, since
|
||||
+ one should always check the host first in order to detect
|
||||
+ negative host checks (which we check for later). */
|
||||
+ ucheck = __icheckuser (user, ruser);
|
||||
+
|
||||
+ /* Either we found the user, or we didn't and this is a
|
||||
+ negative host check. We must do the negative host lookup
|
||||
+ in order to preserve the semantics of stopping on this line
|
||||
+ before processing others. */
|
||||
+ if (ucheck != 0 || *buf == '-') {
|
||||
+
|
||||
+ /* Next check host part */
|
||||
+ hcheck = __checkhost_sa (ra, ralen, buf, rhost);
|
||||
+
|
||||
+ /* Negative '-host user(?)' match? */
|
||||
+ if (hcheck < 0)
|
||||
+ break;
|
||||
|
||||
- /* First check host part */
|
||||
- hcheck = __checkhost_sa (ra, ralen, buf, rhost);
|
||||
-
|
||||
- if (hcheck < 0)
|
||||
- break;
|
||||
-
|
||||
- if (hcheck) {
|
||||
- /* Then check user part */
|
||||
- if (! (*user))
|
||||
- user = luser;
|
||||
-
|
||||
- ucheck = __icheckuser (user, ruser);
|
||||
-
|
||||
- /* Positive 'host user' match? */
|
||||
- if (ucheck > 0) {
|
||||
+ /* Positive 'host user' match? */
|
||||
+ if (hcheck > 0 && ucheck > 0) {
|
||||
retval = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
- /* Negative 'host -user' match? */
|
||||
- if (ucheck < 0)
|
||||
- break;
|
||||
+ /* Negative 'host -user' match? */
|
||||
+ if (hcheck > 0 && ucheck < 0)
|
||||
+ break;
|
||||
|
||||
/* Neither, go on looking for match */
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
diff -pruN glibc-2.12-2-gc4ccff1/malloc/malloc.c glibc-2.12-2-gc4ccff1.new/malloc/malloc.c
|
||||
--- glibc-2.12-2-gc4ccff1/malloc/malloc.c 2015-07-28 22:28:22.517107147 +0530
|
||||
+++ glibc-2.12-2-gc4ccff1.new/malloc/malloc.c 2015-07-28 22:24:59.541394493 +0530
|
||||
@@ -4087,8 +4087,9 @@ public_cALLOc(size_t n, size_t elem_size
|
||||
/* Maybe the failure is due to running out of mmapped areas. */
|
||||
if(av != &main_arena) {
|
||||
(void)mutex_unlock(&av->mutex);
|
||||
- (void)mutex_lock(&main_arena.mutex);
|
||||
- mem = _int_malloc(&main_arena, sz);
|
||||
+ av = &main_arena;
|
||||
+ (void)mutex_lock(&av->mutex);
|
||||
+ mem = _int_malloc(av, sz);
|
||||
} else {
|
||||
#if USE_ARENAS
|
||||
/* ... or sbrk() has failed and there is still a chance to mmap() */
|
||||
@@ -1,138 +0,0 @@
|
||||
commit fdc0f374bcd2d0513569aa8d600f960e43e8af1d
|
||||
Author: Ulrich Drepper <drepper@redhat.com>
|
||||
Date: Sun Oct 24 22:37:00 2010 -0400
|
||||
|
||||
Fix perturbing in malloc on free.
|
||||
|
||||
commit e8349efd466cfedc0aa98be61d88ca8795c9e565
|
||||
Author: Ondřej Bílka <neleai@seznam.cz>
|
||||
Date: Mon Dec 9 17:25:19 2013 +0100
|
||||
|
||||
Simplify perturb_byte logic.
|
||||
|
||||
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||
index 4821deb..ac8c3f6 100644
|
||||
--- a/malloc/malloc.c
|
||||
+++ b/malloc/malloc.c
|
||||
@@ -1870,8 +1870,20 @@ static int check_action = DEFAULT_CHECK_ACTION;
|
||||
|
||||
static int perturb_byte;
|
||||
|
||||
-#define alloc_perturb(p, n) memset (p, (perturb_byte ^ 0xff) & 0xff, n)
|
||||
-#define free_perturb(p, n) memset (p, perturb_byte & 0xff, n)
|
||||
+static inline void
|
||||
+alloc_perturb (char *p, size_t n)
|
||||
+{
|
||||
+ if (__glibc_unlikely (perturb_byte))
|
||||
+ memset (p, perturb_byte ^ 0xff, n);
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+free_perturb (char *p, size_t n)
|
||||
+{
|
||||
+ if (__glibc_unlikely (perturb_byte))
|
||||
+ memset (p, perturb_byte, n);
|
||||
+}
|
||||
+
|
||||
|
||||
|
||||
/* ------------------- Support for multiple arenas -------------------- */
|
||||
@@ -3287,8 +3299,7 @@ _int_malloc(mstate av, size_t bytes)
|
||||
#endif
|
||||
check_remalloced_chunk(av, victim, nb);
|
||||
void *p = chunk2mem(victim);
|
||||
- if (__builtin_expect (perturb_byte, 0))
|
||||
- alloc_perturb (p, bytes);
|
||||
+ alloc_perturb (p, bytes);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
@@ -3323,8 +3334,7 @@ _int_malloc(mstate av, size_t bytes)
|
||||
victim->size |= NON_MAIN_ARENA;
|
||||
check_malloced_chunk(av, victim, nb);
|
||||
void *p = chunk2mem(victim);
|
||||
- if (__builtin_expect (perturb_byte, 0))
|
||||
- alloc_perturb (p, bytes);
|
||||
+ alloc_perturb (p, bytes);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
@@ -3403,8 +3413,7 @@ _int_malloc(mstate av, size_t bytes)
|
||||
|
||||
check_malloced_chunk(av, victim, nb);
|
||||
void *p = chunk2mem(victim);
|
||||
- if (__builtin_expect (perturb_byte, 0))
|
||||
- alloc_perturb (p, bytes);
|
||||
+ alloc_perturb (p, bytes);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -3420,8 +3429,7 @@ _int_malloc(mstate av, size_t bytes)
|
||||
victim->size |= NON_MAIN_ARENA;
|
||||
check_malloced_chunk(av, victim, nb);
|
||||
void *p = chunk2mem(victim);
|
||||
- if (__builtin_expect (perturb_byte, 0))
|
||||
- alloc_perturb (p, bytes);
|
||||
+ alloc_perturb (p, bytes);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -3545,8 +3553,7 @@ _int_malloc(mstate av, size_t bytes)
|
||||
}
|
||||
check_malloced_chunk(av, victim, nb);
|
||||
void *p = chunk2mem(victim);
|
||||
- if (__builtin_expect (perturb_byte, 0))
|
||||
- alloc_perturb (p, bytes);
|
||||
+ alloc_perturb (p, bytes);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
@@ -3649,8 +3656,7 @@ _int_malloc(mstate av, size_t bytes)
|
||||
}
|
||||
check_malloced_chunk(av, victim, nb);
|
||||
void *p = chunk2mem(victim);
|
||||
- if (__builtin_expect (perturb_byte, 0))
|
||||
- alloc_perturb (p, bytes);
|
||||
+ alloc_perturb (p, bytes);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
@@ -3684,8 +3690,7 @@ _int_malloc(mstate av, size_t bytes)
|
||||
|
||||
check_malloced_chunk(av, victim, nb);
|
||||
void *p = chunk2mem(victim);
|
||||
- if (__builtin_expect (perturb_byte, 0))
|
||||
- alloc_perturb (p, bytes);
|
||||
+ alloc_perturb (p, bytes);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -3705,7 +3710,7 @@ _int_malloc(mstate av, size_t bytes)
|
||||
*/
|
||||
else {
|
||||
void *p = sYSMALLOc(nb, av);
|
||||
- if (p != NULL && __builtin_expect (perturb_byte, 0))
|
||||
+ if (p != NULL)
|
||||
alloc_perturb (p, bytes);
|
||||
return p;
|
||||
}
|
||||
@@ -3798,8 +3803,7 @@ _int_free(mstate av, mchunkptr p, int have_lock)
|
||||
#endif
|
||||
}
|
||||
|
||||
- if (__builtin_expect (perturb_byte, 0))
|
||||
- free_perturb (chunk2mem(p), size - SIZE_SZ);
|
||||
+ free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
|
||||
|
||||
set_fastchunks(av);
|
||||
unsigned int idx = fastbin_index(size);
|
||||
@@ -3881,8 +3885,7 @@ _int_free(mstate av, mchunkptr p, int have_lock)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
- if (__builtin_expect (perturb_byte, 0))
|
||||
- free_perturb (chunk2mem(p), size - SIZE_SZ);
|
||||
+ free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
|
||||
|
||||
/* consolidate backward */
|
||||
if (!prev_inuse(p)) {
|
||||
@@ -1,45 +0,0 @@
|
||||
commit 55765a349a96482207fbf927d3666a51878f973b
|
||||
Author: Josef Bacik <josef@toxicpanda.com>
|
||||
Date: Wed Aug 19 14:06:56 2015 +0530
|
||||
|
||||
Don't fall back to mmap if the original arena is not corrupt
|
||||
|
||||
The new logic to find an uncontended non-corrupt arena misses a case
|
||||
where the current arena is contended, but is not corrupt. In the
|
||||
degenerate case, this is the only arena. In both cases, the logic
|
||||
falls back to using mmap despite there being an available arena.
|
||||
|
||||
Attached patch by Josef Bacik makes sure that all arenas are indeed
|
||||
corrupt before falling back to malloc. Verified on x86_64.
|
||||
|
||||
* malloc/arena.c (reused_arena): return NULL only if all
|
||||
arenas are corrupt.
|
||||
|
||||
diff --git a/malloc/arena.c b/malloc/arena.c
|
||||
index 21ecc5a1..0424273 100644
|
||||
--- a/malloc/arena.c
|
||||
+++ b/malloc/arena.c
|
||||
@@ -823,16 +823,21 @@ reused_arena (mstate avoid_arena)
|
||||
|
||||
/* Make sure that the arena we get is not corrupted. */
|
||||
mstate begin = result;
|
||||
+ bool looped = false;
|
||||
+
|
||||
while (arena_is_corrupt (result))
|
||||
{
|
||||
result = result->next;
|
||||
if (result == begin)
|
||||
- break;
|
||||
+ {
|
||||
+ looped = true;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* We could not find any arena that was either not corrupted or not the one
|
||||
we wanted to avoid. */
|
||||
- if (result == begin)
|
||||
+ if (looped)
|
||||
return NULL;
|
||||
|
||||
/* No arena available without contention. Wait for the next in line. */
|
||||
@@ -1,56 +0,0 @@
|
||||
diff -pruN glibc-2.12-2-gc4ccff1/malloc/malloc.c glibc-2.12-2-gc4ccff1.v2/malloc/malloc.c
|
||||
--- glibc-2.12-2-gc4ccff1/malloc/malloc.c 2015-07-24 19:29:37.679907396 +0530
|
||||
+++ glibc-2.12-2-gc4ccff1.v2/malloc/malloc.c 2015-07-24 18:59:59.928055174 +0530
|
||||
@@ -3737,8 +3737,7 @@ public_mALLOc(size_t bytes)
|
||||
mstate prev = ar_ptr->next ? ar_ptr : 0;
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
ar_ptr = arena_get2(prev, bytes, true);
|
||||
- if(ar_ptr)
|
||||
- victim = _int_malloc(ar_ptr, bytes);
|
||||
+ victim = _int_malloc(ar_ptr, bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -3968,8 +3967,7 @@ public_mEMALIGn(size_t alignment, size_t
|
||||
mstate prev = ar_ptr->next ? ar_ptr : 0;
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
ar_ptr = arena_get2(prev, bytes, true);
|
||||
- if(ar_ptr)
|
||||
- p = _int_memalign(ar_ptr, alignment, bytes);
|
||||
+ p = _int_memalign(ar_ptr, alignment, bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -4024,8 +4022,7 @@ public_vALLOc(size_t bytes)
|
||||
mstate prev = ar_ptr->next ? ar_ptr : 0;
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
ar_ptr = arena_get2(prev, bytes, true);
|
||||
- if(ar_ptr)
|
||||
- p = _int_memalign(ar_ptr, pagesz, bytes);
|
||||
+ p = _int_memalign(ar_ptr, pagesz, bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -4080,8 +4077,7 @@ public_pVALLOc(size_t bytes)
|
||||
mstate prev = ar_ptr->next ? ar_ptr : 0;
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
ar_ptr = arena_get2(prev, bytes + 2*pagesz + MINSIZE, true);
|
||||
- if(ar_ptr)
|
||||
- p = _int_memalign(ar_ptr, pagesz, rounded_bytes);
|
||||
+ p = _int_memalign(ar_ptr, pagesz, rounded_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -4180,11 +4176,9 @@ public_cALLOc(size_t n, size_t elem_size
|
||||
mstate prev = av->next ? av : 0;
|
||||
(void)mutex_unlock(&av->mutex);
|
||||
av = arena_get2(prev, sz, true);
|
||||
- if(av)
|
||||
- mem = _int_malloc(av, sz);
|
||||
+ mem = _int_malloc(av, sz);
|
||||
#endif
|
||||
}
|
||||
- if (mem == 0) return 0;
|
||||
}
|
||||
|
||||
if (av != NULL)
|
||||
@@ -1,12 +0,0 @@
|
||||
diff -pruN glibc-2.12-2-gc4ccff1/malloc/malloc.c glibc-2.12-2-gc4ccff1.new/malloc/malloc.c
|
||||
--- glibc-2.12-2-gc4ccff1/malloc/malloc.c 2015-08-19 23:13:52.826205930 +0530
|
||||
+++ glibc-2.12-2-gc4ccff1.new/malloc/malloc.c 2015-08-19 23:13:40.021049289 +0530
|
||||
@@ -5867,7 +5867,7 @@ _int_pvalloc(av, bytes) mstate av, size_
|
||||
size_t pagesz;
|
||||
|
||||
/* Ensure initialization/consolidation */
|
||||
- if (have_fastchunks(av)) malloc_consolidate(av);
|
||||
+ if (av && have_fastchunks(av)) malloc_consolidate(av);
|
||||
pagesz = mp_.pagesize;
|
||||
return _int_memalign(av, pagesz, (bytes + pagesz - 1) & ~(pagesz - 1));
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
commit 5c44738353ecaa1c81efca063ee8b55e092d7a43
|
||||
Author: Alexandre Oliva <aoliva@redhat.com>
|
||||
Date: Wed Sep 5 15:43:04 2012 -0300
|
||||
|
||||
Don't change no_dyn_threshold on mallopt failure
|
||||
|
||||
* malloc/malloc.c (__libc_mallopt) <M_MMAP_THRESHOLD>: Do not
|
||||
change internal state upon failure.
|
||||
|
||||
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||
index bd562df..c69e281 100644
|
||||
--- a/malloc/malloc.c
|
||||
+++ b/malloc/malloc.c
|
||||
@@ -4769,8 +4769,10 @@ int __libc_mallopt(int param_number, int value)
|
||||
res = 0;
|
||||
else
|
||||
#endif
|
||||
- mp_.mmap_threshold = value;
|
||||
- mp_.no_dyn_threshold = 1;
|
||||
+ {
|
||||
+ mp_.mmap_threshold = value;
|
||||
+ mp_.no_dyn_threshold = 1;
|
||||
+ }
|
||||
break;
|
||||
|
||||
case M_MMAP_MAX:
|
||||
@@ -1,41 +0,0 @@
|
||||
Description: Allow loading more libraries with static TLS.
|
||||
Author: Carlos O'Donell <codonell@redhat.com>
|
||||
Origin: PATCH
|
||||
Bug-RHEL: #1291270 (rhel-6.7.z), #1198802 (rhel-6.8), #1202952 (rhel-7.2)
|
||||
Bug-Fedora: #1124987 (F21)
|
||||
Bug-Upstream: #17090, #17620, #17621, #17628 (2.22)
|
||||
Upstream status: not-needed
|
||||
#
|
||||
# The correct fix for this is already upstream and involves
|
||||
# changing the heuristics for DTV slot increases. In RHEL6
|
||||
# we take the conservative approach and provide a larger
|
||||
# slot surplus. This matches what was done in Fedora 21 before
|
||||
# we had the upstream fix: f8aeae347377f3dfa8cbadde057adf1827fb1d44.
|
||||
# In RHEL7 we have the upstream fix. This is fixed upstream as of
|
||||
# glibc 2.22.
|
||||
#
|
||||
Index: glibc-2.12-2-gc4ccff1/sysdeps/generic/ldsodefs.h
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/generic/ldsodefs.h
|
||||
+++ glibc-2.12-2-gc4ccff1/sysdeps/generic/ldsodefs.h
|
||||
@@ -496,8 +496,18 @@ struct rtld_global
|
||||
have to iterate beyond the first element in the slotinfo list. */
|
||||
#define TLS_SLOTINFO_SURPLUS (62)
|
||||
|
||||
-/* Number of additional slots in the dtv allocated. */
|
||||
-#define DTV_SURPLUS (14)
|
||||
+/* Number of additional allocated dtv slots. This was initially
|
||||
+ 14, but problems with python, MESA, and X11's uses of static TLS meant
|
||||
+ that most distributions were very close to this limit when they loaded
|
||||
+ dynamically interpreted languages that used graphics. The simplest
|
||||
+ solution was to roughly double the number of slots. The actual static
|
||||
+ image space usage was relatively small, for example in MESA you
|
||||
+ had only two dispatch pointers for a total of 16 bytes. If we hit up
|
||||
+ against this limit again we should start a campaign with the
|
||||
+ distributions to coordinate the usage of static TLS. Any user of this
|
||||
+ resource is effectively coordinating a global resource since this
|
||||
+ surplus is allocated for each thread at startup. */
|
||||
+#define DTV_SURPLUS (32)
|
||||
|
||||
/* Initial dtv of the main thread, not allocated with normal malloc. */
|
||||
EXTERN void *_dl_initial_dtv;
|
||||
@@ -1,465 +0,0 @@
|
||||
Sourceware bug 16574
|
||||
|
||||
commit d668061994a7486a3ba9c7d5e7882d85a2883707
|
||||
Author: Andreas Schwab <schwab@suse.de>
|
||||
Date: Thu Feb 13 11:01:57 2014 +0100
|
||||
|
||||
Fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer
|
||||
|
||||
commit ab7ac0f2cf8731fe4c3f3aea6088a7c0127b5725
|
||||
Author: Ondřej Bílka <neleai@seznam.cz>
|
||||
Date: Sun Feb 16 12:59:23 2014 +0100
|
||||
|
||||
Deduplicate resolv/nss_dns/dns-host.c
|
||||
|
||||
In resolv/nss_dns/dns-host.c one of code path duplicated code after
|
||||
that. We merge these paths.
|
||||
|
||||
commit ab09bf616ad527b249aca5f2a4956fd526f0712f
|
||||
Author: Andreas Schwab <schwab@suse.de>
|
||||
Date: Tue Feb 18 10:57:25 2014 +0100
|
||||
|
||||
Properly fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer
|
||||
|
||||
Instead of trying to guess whether the second buffer needs to be freed
|
||||
set a flag at the place it is allocated
|
||||
|
||||
Index: glibc-2.12-2-gc4ccff1/include/resolv.h
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/include/resolv.h
|
||||
+++ glibc-2.12-2-gc4ccff1/include/resolv.h
|
||||
@@ -58,11 +58,11 @@ libc_hidden_proto (__res_randomid)
|
||||
libc_hidden_proto (__res_state)
|
||||
|
||||
int __libc_res_nquery (res_state, const char *, int, int, u_char *, int,
|
||||
- u_char **, u_char **, int *, int *);
|
||||
+ u_char **, u_char **, int *, int *, int *);
|
||||
int __libc_res_nsearch (res_state, const char *, int, int, u_char *, int,
|
||||
- u_char **, u_char **, int *, int *);
|
||||
+ u_char **, u_char **, int *, int *, int *);
|
||||
int __libc_res_nsend (res_state, const u_char *, int, const u_char *, int,
|
||||
- u_char *, int, u_char **, u_char **, int *, int *)
|
||||
+ u_char *, int, u_char **, u_char **, int *, int *, int *)
|
||||
attribute_hidden;
|
||||
|
||||
libresolv_hidden_proto (_sethtent)
|
||||
Index: glibc-2.12-2-gc4ccff1/resolv/gethnamaddr.c
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/resolv/gethnamaddr.c
|
||||
+++ glibc-2.12-2-gc4ccff1/resolv/gethnamaddr.c
|
||||
@@ -634,7 +634,7 @@ gethostbyname2(name, af)
|
||||
buf.buf = origbuf = (querybuf *) alloca (1024);
|
||||
|
||||
if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024,
|
||||
- &buf.ptr, NULL, NULL, NULL)) < 0) {
|
||||
+ &buf.ptr, NULL, NULL, NULL, NULL)) < 0) {
|
||||
if (buf.buf != origbuf)
|
||||
free (buf.buf);
|
||||
Dprintf("res_nsearch failed (%d)\n", n);
|
||||
@@ -729,12 +729,12 @@ gethostbyaddr(addr, len, af)
|
||||
buf.buf = orig_buf = (querybuf *) alloca (1024);
|
||||
|
||||
n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024,
|
||||
- &buf.ptr, NULL, NULL, NULL);
|
||||
+ &buf.ptr, NULL, NULL, NULL, NULL);
|
||||
if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) {
|
||||
strcpy(qp, "ip6.int");
|
||||
n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf,
|
||||
buf.buf != orig_buf ? MAXPACKET : 1024,
|
||||
- &buf.ptr, NULL, NULL, NULL);
|
||||
+ &buf.ptr, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
if (n < 0) {
|
||||
if (buf.buf != orig_buf)
|
||||
Index: glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-canon.c
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/resolv/nss_dns/dns-canon.c
|
||||
+++ glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-canon.c
|
||||
@@ -62,7 +62,7 @@ _nss_dns_getcanonname_r (const char *nam
|
||||
{
|
||||
int r = __libc_res_nquery (&_res, name, ns_c_in, qtypes[i],
|
||||
buf, sizeof (buf), &ansp.ptr, NULL, NULL,
|
||||
- NULL);
|
||||
+ NULL, NULL);
|
||||
if (r > 0)
|
||||
{
|
||||
/* We need to decode the response. Just one question record.
|
||||
Index: glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-host.c
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/resolv/nss_dns/dns-host.c
|
||||
+++ glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-host.c
|
||||
@@ -191,7 +191,7 @@ _nss_dns_gethostbyname3_r (const char *n
|
||||
host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
|
||||
|
||||
n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf,
|
||||
- 1024, &host_buffer.ptr, NULL, NULL, NULL);
|
||||
+ 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
|
||||
if (n < 0)
|
||||
{
|
||||
switch (errno)
|
||||
@@ -221,7 +221,7 @@ _nss_dns_gethostbyname3_r (const char *n
|
||||
n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf,
|
||||
host_buffer.buf != orig_host_buffer
|
||||
? MAXPACKET : 1024, &host_buffer.ptr,
|
||||
- NULL, NULL, NULL);
|
||||
+ NULL, NULL, NULL, NULL);
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
@@ -304,13 +304,20 @@ _nss_dns_gethostbyname4_r (const char *n
|
||||
u_char *ans2p = NULL;
|
||||
int nans2p = 0;
|
||||
int resplen2 = 0;
|
||||
+ int ans2p_malloced = 0;
|
||||
|
||||
int olderr = errno;
|
||||
enum nss_status status;
|
||||
int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
|
||||
host_buffer.buf->buf, 2048, &host_buffer.ptr,
|
||||
- &ans2p, &nans2p, &resplen2);
|
||||
- if (n < 0)
|
||||
+ &ans2p, &nans2p, &resplen2, &ans2p_malloced);
|
||||
+ if (n >= 0)
|
||||
+ {
|
||||
+ status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
|
||||
+ resplen2, name, pat, buffer, buflen,
|
||||
+ errnop, herrnop, ttlp);
|
||||
+ }
|
||||
+ else
|
||||
{
|
||||
if (errno == ESRCH)
|
||||
{
|
||||
@@ -325,16 +332,11 @@ _nss_dns_gethostbyname4_r (const char *n
|
||||
*errnop = EAGAIN;
|
||||
else
|
||||
__set_errno (olderr);
|
||||
-
|
||||
- if (host_buffer.buf != orig_host_buffer)
|
||||
- free (host_buffer.buf);
|
||||
-
|
||||
- return status;
|
||||
}
|
||||
|
||||
- status = gaih_getanswer(host_buffer.buf, n, (const querybuf *) ans2p,
|
||||
- resplen2, name, pat, buffer, buflen,
|
||||
- errnop, herrnop, ttlp);
|
||||
+ /* Check whether ans2p was separately allocated. */
|
||||
+ if (ans2p_malloced)
|
||||
+ free (ans2p);
|
||||
|
||||
if (host_buffer.buf != orig_host_buffer)
|
||||
free (host_buffer.buf);
|
||||
@@ -444,7 +446,7 @@ _nss_dns_gethostbyaddr2_r (const void *a
|
||||
strcpy (qp, "].ip6.arpa");
|
||||
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR,
|
||||
host_buffer.buf->buf, 1024, &host_buffer.ptr,
|
||||
- NULL, NULL, NULL);
|
||||
+ NULL, NULL, NULL, NULL);
|
||||
if (n >= 0)
|
||||
goto got_it_already;
|
||||
}
|
||||
@@ -465,14 +467,14 @@ _nss_dns_gethostbyaddr2_r (const void *a
|
||||
}
|
||||
|
||||
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
|
||||
- 1024, &host_buffer.ptr, NULL, NULL, NULL);
|
||||
+ 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
|
||||
if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0)
|
||||
{
|
||||
strcpy (qp, "ip6.int");
|
||||
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
|
||||
host_buffer.buf != orig_host_buffer
|
||||
? MAXPACKET : 1024, &host_buffer.ptr,
|
||||
- NULL, NULL, NULL);
|
||||
+ NULL, NULL, NULL, NULL);
|
||||
}
|
||||
if (n < 0)
|
||||
{
|
||||
Index: glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-network.c
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/resolv/nss_dns/dns-network.c
|
||||
+++ glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-network.c
|
||||
@@ -130,7 +130,7 @@ _nss_dns_getnetbyname_r (const char *nam
|
||||
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
|
||||
|
||||
anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
|
||||
- 1024, &net_buffer.ptr, NULL, NULL, NULL);
|
||||
+ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
|
||||
if (anslen < 0)
|
||||
{
|
||||
/* Nothing found. */
|
||||
@@ -206,7 +206,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, i
|
||||
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
|
||||
|
||||
anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
|
||||
- 1024, &net_buffer.ptr, NULL, NULL, NULL);
|
||||
+ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
|
||||
if (anslen < 0)
|
||||
{
|
||||
/* Nothing found. */
|
||||
Index: glibc-2.12-2-gc4ccff1/resolv/res_query.c
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/resolv/res_query.c
|
||||
+++ glibc-2.12-2-gc4ccff1/resolv/res_query.c
|
||||
@@ -98,7 +98,7 @@ static int
|
||||
__libc_res_nquerydomain(res_state statp, const char *name, const char *domain,
|
||||
int class, int type, u_char *answer, int anslen,
|
||||
u_char **answerp, u_char **answerp2, int *nanswerp2,
|
||||
- int *resplen2);
|
||||
+ int *resplen2, int *answerp2_malloced);
|
||||
|
||||
/*
|
||||
* Formulate a normal query, send, and await answer.
|
||||
@@ -119,7 +119,8 @@ __libc_res_nquery(res_state statp,
|
||||
u_char **answerp, /* if buffer needs to be enlarged */
|
||||
u_char **answerp2,
|
||||
int *nanswerp2,
|
||||
- int *resplen2)
|
||||
+ int *resplen2,
|
||||
+ int *answerp2_malloced)
|
||||
{
|
||||
HEADER *hp = (HEADER *) answer;
|
||||
HEADER *hp2;
|
||||
@@ -224,7 +225,8 @@ __libc_res_nquery(res_state statp,
|
||||
}
|
||||
assert (answerp == NULL || (void *) *answerp == (void *) answer);
|
||||
n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer,
|
||||
- anslen, answerp, answerp2, nanswerp2, resplen2);
|
||||
+ anslen, answerp, answerp2, nanswerp2, resplen2,
|
||||
+ answerp2_malloced);
|
||||
if (use_malloc)
|
||||
free (buf);
|
||||
if (n < 0) {
|
||||
@@ -316,7 +318,7 @@ res_nquery(res_state statp,
|
||||
int anslen) /* size of answer buffer */
|
||||
{
|
||||
return __libc_res_nquery(statp, name, class, type, answer, anslen,
|
||||
- NULL, NULL, NULL, NULL);
|
||||
+ NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
libresolv_hidden_def (res_nquery)
|
||||
|
||||
@@ -335,7 +337,8 @@ __libc_res_nsearch(res_state statp,
|
||||
u_char **answerp,
|
||||
u_char **answerp2,
|
||||
int *nanswerp2,
|
||||
- int *resplen2)
|
||||
+ int *resplen2,
|
||||
+ int *answerp2_malloced)
|
||||
{
|
||||
const char *cp, * const *domain;
|
||||
HEADER *hp = (HEADER *) answer;
|
||||
@@ -359,7 +362,7 @@ __libc_res_nsearch(res_state statp,
|
||||
if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL)
|
||||
return (__libc_res_nquery(statp, cp, class, type, answer,
|
||||
anslen, answerp, answerp2,
|
||||
- nanswerp2, resplen2));
|
||||
+ nanswerp2, resplen2, answerp2_malloced));
|
||||
|
||||
#ifdef DEBUG
|
||||
if (statp->options & RES_DEBUG)
|
||||
@@ -376,7 +379,8 @@ __libc_res_nsearch(res_state statp,
|
||||
if (dots >= statp->ndots || trailing_dot) {
|
||||
ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
|
||||
answer, anslen, answerp,
|
||||
- answerp2, nanswerp2, resplen2);
|
||||
+ answerp2, nanswerp2, resplen2,
|
||||
+ answerp2_malloced);
|
||||
if (ret > 0 || trailing_dot
|
||||
/* If the second response is valid then we use that. */
|
||||
|| (ret == 0 && resplen2 != NULL && *resplen2 > 0))
|
||||
@@ -387,12 +391,12 @@ __libc_res_nsearch(res_state statp,
|
||||
answer = *answerp;
|
||||
anslen = MAXPACKET;
|
||||
}
|
||||
- if (answerp2
|
||||
- && (*answerp2 < answer || *answerp2 >= answer + anslen))
|
||||
+ if (answerp2 && *answerp2_malloced)
|
||||
{
|
||||
free (*answerp2);
|
||||
*nanswerp2 = 0;
|
||||
*answerp2 = NULL;
|
||||
+ *answerp2_malloced = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,7 +422,7 @@ __libc_res_nsearch(res_state statp,
|
||||
class, type,
|
||||
answer, anslen, answerp,
|
||||
answerp2, nanswerp2,
|
||||
- resplen2);
|
||||
+ resplen2, answerp2_malloced);
|
||||
if (ret > 0 || (ret == 0 && resplen2 != NULL
|
||||
&& *resplen2 > 0))
|
||||
return (ret);
|
||||
@@ -427,13 +431,12 @@ __libc_res_nsearch(res_state statp,
|
||||
answer = *answerp;
|
||||
anslen = MAXPACKET;
|
||||
}
|
||||
- if (answerp2
|
||||
- && (*answerp2 < answer
|
||||
- || *answerp2 >= answer + anslen))
|
||||
+ if (answerp2 && *answerp2_malloced)
|
||||
{
|
||||
free (*answerp2);
|
||||
*nanswerp2 = 0;
|
||||
*answerp2 = NULL;
|
||||
+ *answerp2_malloced = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -489,7 +492,8 @@ __libc_res_nsearch(res_state statp,
|
||||
if (dots && !(tried_as_is || root_on_list)) {
|
||||
ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
|
||||
answer, anslen, answerp,
|
||||
- answerp2, nanswerp2, resplen2);
|
||||
+ answerp2, nanswerp2, resplen2,
|
||||
+ answerp2_malloced);
|
||||
if (ret > 0 || (ret == 0 && resplen2 != NULL
|
||||
&& *resplen2 > 0))
|
||||
return (ret);
|
||||
@@ -502,11 +506,12 @@ __libc_res_nsearch(res_state statp,
|
||||
* else send back meaningless H_ERRNO, that being the one from
|
||||
* the last DNSRCH we did.
|
||||
*/
|
||||
- if (answerp2 && (*answerp2 < answer || *answerp2 >= answer + anslen))
|
||||
+ if (answerp2 && *answerp2_malloced)
|
||||
{
|
||||
free (*answerp2);
|
||||
- *nanswerp2 = NULL;
|
||||
+ *nanswerp2 = 0;
|
||||
*answerp2 = NULL;
|
||||
+ *answerp2_malloced = 0;
|
||||
}
|
||||
if (saved_herrno != -1)
|
||||
RES_SET_H_ERRNO(statp, saved_herrno);
|
||||
@@ -526,7 +531,7 @@ res_nsearch(res_state statp,
|
||||
int anslen) /* size of answer */
|
||||
{
|
||||
return __libc_res_nsearch(statp, name, class, type, answer,
|
||||
- anslen, NULL, NULL, NULL, NULL);
|
||||
+ anslen, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
libresolv_hidden_def (res_nsearch)
|
||||
|
||||
@@ -544,7 +549,8 @@ __libc_res_nquerydomain(res_state statp,
|
||||
u_char **answerp,
|
||||
u_char **answerp2,
|
||||
int *nanswerp2,
|
||||
- int *resplen2)
|
||||
+ int *resplen2,
|
||||
+ int *answerp2_malloced)
|
||||
{
|
||||
char nbuf[MAXDNAME];
|
||||
const char *longname = nbuf;
|
||||
@@ -582,7 +588,7 @@ __libc_res_nquerydomain(res_state statp,
|
||||
}
|
||||
return (__libc_res_nquery(statp, longname, class, type, answer,
|
||||
anslen, answerp, answerp2, nanswerp2,
|
||||
- resplen2));
|
||||
+ resplen2, answerp2_malloced));
|
||||
}
|
||||
|
||||
int
|
||||
@@ -594,7 +600,8 @@ res_nquerydomain(res_state statp,
|
||||
int anslen) /* size of answer */
|
||||
{
|
||||
return __libc_res_nquerydomain(statp, name, domain, class, type,
|
||||
- answer, anslen, NULL, NULL, NULL, NULL);
|
||||
+ answer, anslen, NULL, NULL, NULL, NULL,
|
||||
+ NULL);
|
||||
}
|
||||
libresolv_hidden_def (res_nquerydomain)
|
||||
|
||||
Index: glibc-2.12-2-gc4ccff1/resolv/res_send.c
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/resolv/res_send.c
|
||||
+++ glibc-2.12-2-gc4ccff1/resolv/res_send.c
|
||||
@@ -203,12 +203,12 @@ evNowTime(struct timespec *res) {
|
||||
static int send_vc(res_state, const u_char *, int,
|
||||
const u_char *, int,
|
||||
u_char **, int *, int *, int, u_char **,
|
||||
- u_char **, int *, int *);
|
||||
+ u_char **, int *, int *, int *);
|
||||
static int send_dg(res_state, const u_char *, int,
|
||||
const u_char *, int,
|
||||
u_char **, int *, int *, int,
|
||||
int *, int *, u_char **,
|
||||
- u_char **, int *, int *);
|
||||
+ u_char **, int *, int *, int *);
|
||||
#ifdef DEBUG
|
||||
static void Aerror(const res_state, FILE *, const char *, int,
|
||||
const struct sockaddr *);
|
||||
@@ -360,7 +360,7 @@ int
|
||||
__libc_res_nsend(res_state statp, const u_char *buf, int buflen,
|
||||
const u_char *buf2, int buflen2,
|
||||
u_char *ans, int anssiz, u_char **ansp, u_char **ansp2,
|
||||
- int *nansp2, int *resplen2)
|
||||
+ int *nansp2, int *resplen2, int *ansp2_malloced)
|
||||
{
|
||||
int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
|
||||
|
||||
@@ -565,7 +565,8 @@ __libc_res_nsend(res_state statp, const
|
||||
try = statp->retry;
|
||||
n = send_vc(statp, buf, buflen, buf2, buflen2,
|
||||
&ans, &anssiz, &terrno,
|
||||
- ns, ansp, ansp2, nansp2, resplen2);
|
||||
+ ns, ansp, ansp2, nansp2, resplen2,
|
||||
+ ansp2_malloced);
|
||||
if (n < 0)
|
||||
return (-1);
|
||||
if (n == 0 && (buf2 == NULL || *resplen2 == 0))
|
||||
@@ -575,7 +576,7 @@ __libc_res_nsend(res_state statp, const
|
||||
n = send_dg(statp, buf, buflen, buf2, buflen2,
|
||||
&ans, &anssiz, &terrno,
|
||||
ns, &v_circuit, &gotsomewhere, ansp,
|
||||
- ansp2, nansp2, resplen2);
|
||||
+ ansp2, nansp2, resplen2, ansp2_malloced);
|
||||
if (n < 0)
|
||||
return (-1);
|
||||
if (n == 0 && (buf2 == NULL || *resplen2 == 0))
|
||||
@@ -665,7 +666,7 @@ res_nsend(res_state statp,
|
||||
const u_char *buf, int buflen, u_char *ans, int anssiz)
|
||||
{
|
||||
return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz,
|
||||
- NULL, NULL, NULL, NULL);
|
||||
+ NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
libresolv_hidden_def (res_nsend)
|
||||
|
||||
@@ -747,7 +748,7 @@ send_vc(res_state statp,
|
||||
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
|
||||
u_char **ansp, int *anssizp,
|
||||
int *terrno, int ns, u_char **anscp, u_char **ansp2, int *anssizp2,
|
||||
- int *resplen2)
|
||||
+ int *resplen2, int *ansp2_malloced)
|
||||
{
|
||||
const HEADER *hp = (HEADER *) buf;
|
||||
const HEADER *hp2 = (HEADER *) buf2;
|
||||
@@ -896,6 +897,8 @@ send_vc(res_state statp,
|
||||
}
|
||||
*thisanssizp = MAXPACKET;
|
||||
*thisansp = newp;
|
||||
+ if (thisansp == ansp2)
|
||||
+ *ansp2_malloced = 1;
|
||||
anhp = (HEADER *) newp;
|
||||
/* A uint16_t can't be larger than MAXPACKET
|
||||
thus it's safe to allocate MAXPACKET but
|
||||
@@ -1128,7 +1131,7 @@ send_dg(res_state statp,
|
||||
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
|
||||
u_char **ansp, int *anssizp,
|
||||
int *terrno, int ns, int *v_circuit, int *gotsomewhere, u_char **anscp,
|
||||
- u_char **ansp2, int *anssizp2, int *resplen2)
|
||||
+ u_char **ansp2, int *anssizp2, int *resplen2, int *ansp2_malloced)
|
||||
{
|
||||
const HEADER *hp = (HEADER *) buf;
|
||||
const HEADER *hp2 = (HEADER *) buf2;
|
||||
@@ -1289,6 +1292,8 @@ send_dg(res_state statp,
|
||||
if (newp != NULL) {
|
||||
*thisanssizp = MAXPACKET;
|
||||
*thisansp = newp;
|
||||
+ if (thisansp == ansp2)
|
||||
+ *ansp2_malloced = 1;
|
||||
}
|
||||
}
|
||||
/* We could end up with truncation if anscp was NULL
|
||||
@@ -1,544 +0,0 @@
|
||||
Index: glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-host.c
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/resolv/nss_dns/dns-host.c
|
||||
+++ glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-host.c
|
||||
@@ -1043,7 +1043,10 @@ gaih_getanswer_slice (const querybuf *an
|
||||
int h_namelen = 0;
|
||||
|
||||
if (ancount == 0)
|
||||
- return NSS_STATUS_NOTFOUND;
|
||||
+ {
|
||||
+ *h_errnop = HOST_NOT_FOUND;
|
||||
+ return NSS_STATUS_NOTFOUND;
|
||||
+ }
|
||||
|
||||
while (ancount-- > 0 && cp < end_of_message && had_error == 0)
|
||||
{
|
||||
@@ -1217,7 +1220,14 @@ gaih_getanswer_slice (const querybuf *an
|
||||
/* Special case here: if the resolver sent a result but it only
|
||||
contains a CNAME while we are looking for a T_A or T_AAAA record,
|
||||
we fail with NOTFOUND instead of TRYAGAIN. */
|
||||
- return canon == NULL ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
|
||||
+ if (canon != NULL)
|
||||
+ {
|
||||
+ *h_errnop = HOST_NOT_FOUND;
|
||||
+ return NSS_STATUS_NOTFOUND;
|
||||
+ }
|
||||
+
|
||||
+ *h_errnop = NETDB_INTERNAL;
|
||||
+ return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
|
||||
@@ -1231,11 +1241,101 @@ gaih_getanswer (const querybuf *answer1,
|
||||
|
||||
enum nss_status status = NSS_STATUS_NOTFOUND;
|
||||
|
||||
+ /* Combining the NSS status of two distinct queries requires some
|
||||
+ compromise and attention to symmetry (A or AAAA queries can be
|
||||
+ returned in any order). What follows is a breakdown of how this
|
||||
+ code is expected to work and why. We discuss only SUCCESS,
|
||||
+ TRYAGAIN, NOTFOUND and UNAVAIL, since they are the only returns
|
||||
+ that apply (though RETURN and MERGE exist). We make a distinction
|
||||
+ between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable).
|
||||
+ A recoverable TRYAGAIN is almost always due to buffer size issues
|
||||
+ and returns ERANGE in errno and the caller is expected to retry
|
||||
+ with a larger buffer.
|
||||
+
|
||||
+ Lastly, you may be tempted to make significant changes to the
|
||||
+ conditions in this code to bring about symmetry between responses.
|
||||
+ Please don't change anything without due consideration for
|
||||
+ expected application behaviour. Some of the synthesized responses
|
||||
+ aren't very well thought out and sometimes appear to imply that
|
||||
+ IPv4 responses are always answer 1, and IPv6 responses are always
|
||||
+ answer 2, but that's not true (see the implemetnation of send_dg
|
||||
+ and send_vc to see response can arrive in any order, particlarly
|
||||
+ for UDP). However, we expect it holds roughly enough of the time
|
||||
+ that this code works, but certainly needs to be fixed to make this
|
||||
+ a more robust implementation.
|
||||
+
|
||||
+ ----------------------------------------------
|
||||
+ | Answer 1 Status / | Synthesized | Reason |
|
||||
+ | Answer 2 Status | Status | |
|
||||
+ |--------------------------------------------|
|
||||
+ | SUCCESS/SUCCESS | SUCCESS | [1] |
|
||||
+ | SUCCESS/TRYAGAIN | TRYAGAIN | [5] |
|
||||
+ | SUCCESS/TRYAGAIN' | SUCCESS | [1] |
|
||||
+ | SUCCESS/NOTFOUND | SUCCESS | [1] |
|
||||
+ | SUCCESS/UNAVAIL | SUCCESS | [1] |
|
||||
+ | TRYAGAIN/SUCCESS | TRYAGAIN | [2] |
|
||||
+ | TRYAGAIN/TRYAGAIN | TRYAGAIN | [2] |
|
||||
+ | TRYAGAIN/TRYAGAIN' | TRYAGAIN | [2] |
|
||||
+ | TRYAGAIN/NOTFOUND | TRYAGAIN | [2] |
|
||||
+ | TRYAGAIN/UNAVAIL | TRYAGAIN | [2] |
|
||||
+ | TRYAGAIN'/SUCCESS | SUCCESS | [3] |
|
||||
+ | TRYAGAIN'/TRYAGAIN | TRYAGAIN | [3] |
|
||||
+ | TRYAGAIN'/TRYAGAIN' | TRYAGAIN' | [3] |
|
||||
+ | TRYAGAIN'/NOTFOUND | TRYAGAIN' | [3] |
|
||||
+ | TRYAGAIN'/UNAVAIL | UNAVAIL | [3] |
|
||||
+ | NOTFOUND/SUCCESS | SUCCESS | [3] |
|
||||
+ | NOTFOUND/TRYAGAIN | TRYAGAIN | [3] |
|
||||
+ | NOTFOUND/TRYAGAIN' | TRYAGAIN' | [3] |
|
||||
+ | NOTFOUND/NOTFOUND | NOTFOUND | [3] |
|
||||
+ | NOTFOUND/UNAVAIL | UNAVAIL | [3] |
|
||||
+ | UNAVAIL/SUCCESS | UNAVAIL | [4] |
|
||||
+ | UNAVAIL/TRYAGAIN | UNAVAIL | [4] |
|
||||
+ | UNAVAIL/TRYAGAIN' | UNAVAIL | [4] |
|
||||
+ | UNAVAIL/NOTFOUND | UNAVAIL | [4] |
|
||||
+ | UNAVAIL/UNAVAIL | UNAVAIL | [4] |
|
||||
+ ----------------------------------------------
|
||||
+
|
||||
+ [1] If the first response is a success we return success.
|
||||
+ This ignores the state of the second answer and in fact
|
||||
+ incorrectly sets errno and h_errno to that of the second
|
||||
+ answer. However because the response is a success we ignore
|
||||
+ *errnop and *h_errnop (though that means you touched errno on
|
||||
+ success). We are being conservative here and returning the
|
||||
+ likely IPv4 response in the first answer as a success.
|
||||
+
|
||||
+ [2] If the first response is a recoverable TRYAGAIN we return
|
||||
+ that instead of looking at the second response. The
|
||||
+ expectation here is that we have failed to get an IPv4 response
|
||||
+ and should retry both queries.
|
||||
+
|
||||
+ [3] If the first response was not a SUCCESS and the second
|
||||
+ response is not NOTFOUND (had a SUCCESS, need to TRYAGAIN,
|
||||
+ or failed entirely e.g. TRYAGAIN' and UNAVAIL) then use the
|
||||
+ result from the second response, otherwise the first responses
|
||||
+ status is used. Again we have some odd side-effects when the
|
||||
+ second response is NOTFOUND because we overwrite *errnop and
|
||||
+ *h_errnop that means that a first answer of NOTFOUND might see
|
||||
+ its *errnop and *h_errnop values altered. Whether it matters
|
||||
+ in practice that a first response NOTFOUND has the wrong
|
||||
+ *errnop and *h_errnop is undecided.
|
||||
+
|
||||
+ [4] If the first response is UNAVAIL we return that instead of
|
||||
+ looking at the second response. The expectation here is that
|
||||
+ it will have failed similarly e.g. configuration failure.
|
||||
+
|
||||
+ [5] Testing this code is complicated by the fact that truncated
|
||||
+ second response buffers might be returned as SUCCESS if the
|
||||
+ first answer is a SUCCESS. To fix this we add symmetry to
|
||||
+ TRYAGAIN with the second response. If the second response
|
||||
+ is a recoverable error we now return TRYAGIN even if the first
|
||||
+ response was SUCCESS. */
|
||||
+
|
||||
if (anslen1 > 0)
|
||||
status = gaih_getanswer_slice(answer1, anslen1, qname,
|
||||
&pat, &buffer, &buflen,
|
||||
errnop, h_errnop, ttlp,
|
||||
&first);
|
||||
+
|
||||
if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
|
||||
|| (status == NSS_STATUS_TRYAGAIN
|
||||
&& (*errnop != ERANGE || *h_errnop == NO_RECOVERY)))
|
||||
@@ -1245,8 +1345,15 @@ gaih_getanswer (const querybuf *answer1,
|
||||
&pat, &buffer, &buflen,
|
||||
errnop, h_errnop, ttlp,
|
||||
&first);
|
||||
+ /* Use the second response status in some cases. */
|
||||
if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
|
||||
status = status2;
|
||||
+ /* Do not return a truncated second response (unless it was
|
||||
+ unavoidable e.g. unrecoverable TRYAGAIN). */
|
||||
+ if (status == NSS_STATUS_SUCCESS
|
||||
+ && (status2 == NSS_STATUS_TRYAGAIN
|
||||
+ && *errnop == ERANGE && *h_errnop != NO_RECOVERY))
|
||||
+ status = NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
return status;
|
||||
Index: glibc-2.12-2-gc4ccff1/resolv/res_send.c
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/resolv/res_send.c
|
||||
+++ glibc-2.12-2-gc4ccff1/resolv/res_send.c
|
||||
@@ -1,3 +1,20 @@
|
||||
+/* Copyright (C) 2016 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/>. */
|
||||
+
|
||||
/*
|
||||
* Copyright (c) 1985, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@@ -360,6 +377,8 @@ __libc_res_nsend(res_state statp, const
|
||||
#ifdef USE_HOOKS
|
||||
if (__builtin_expect (statp->qhook || statp->rhook, 0)) {
|
||||
if (anssiz < MAXPACKET && ansp) {
|
||||
+ /* Always allocate MAXPACKET, callers expect
|
||||
+ this specific size. */
|
||||
u_char *buf = malloc (MAXPACKET);
|
||||
if (buf == NULL)
|
||||
return (-1);
|
||||
@@ -652,6 +671,77 @@ libresolv_hidden_def (res_nsend)
|
||||
|
||||
/* Private */
|
||||
|
||||
+/* The send_vc function is responsible for sending a DNS query over TCP
|
||||
+ to the nameserver numbered NS from the res_state STATP i.e.
|
||||
+ EXT(statp).nssocks[ns]. The function supports sending both IPv4 and
|
||||
+ IPv6 queries at the same serially on the same socket.
|
||||
+
|
||||
+ Please note that for TCP there is no way to disable sending both
|
||||
+ queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP
|
||||
+ and sends the queries serially and waits for the result after each
|
||||
+ sent query. This implemetnation should be corrected to honour these
|
||||
+ options.
|
||||
+
|
||||
+ Please also note that for TCP we send both queries over the same
|
||||
+ socket one after another. This technically violates best practice
|
||||
+ since the server is allowed to read the first query, respond, and
|
||||
+ then close the socket (to service another client). If the server
|
||||
+ does this, then the remaining second query in the socket data buffer
|
||||
+ will cause the server to send the client an RST which will arrive
|
||||
+ asynchronously and the client's OS will likely tear down the socket
|
||||
+ receive buffer resulting in a potentially short read and lost
|
||||
+ response data. This will force the client to retry the query again,
|
||||
+ and this process may repeat until all servers and connection resets
|
||||
+ are exhausted and then the query will fail. It's not known if this
|
||||
+ happens with any frequency in real DNS server implementations. This
|
||||
+ implementation should be corrected to use two sockets by default for
|
||||
+ parallel queries.
|
||||
+
|
||||
+ The query stored in BUF of BUFLEN length is sent first followed by
|
||||
+ the query stored in BUF2 of BUFLEN2 length. Queries are sent
|
||||
+ serially on the same socket.
|
||||
+
|
||||
+ Answers to the query are stored firstly in *ANSP up to a max of
|
||||
+ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
|
||||
+ is non-NULL (to indicate that modifying the answer buffer is allowed)
|
||||
+ then malloc is used to allocate a new response buffer and ANSCP and
|
||||
+ ANSP will both point to the new buffer. If more than *ANSSIZP bytes
|
||||
+ are needed but ANSCP is NULL, then as much of the response as
|
||||
+ possible is read into the buffer, but the results will be truncated.
|
||||
+ When truncation happens because of a small answer buffer the DNS
|
||||
+ packets header feild TC will bet set to 1, indicating a truncated
|
||||
+ message and the rest of the socket data will be read and discarded.
|
||||
+
|
||||
+ Answers to the query are stored secondly in *ANSP2 up to a max of
|
||||
+ *ANSSIZP2 bytes, with the actual response length stored in
|
||||
+ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
|
||||
+ is non-NULL (required for a second query) then malloc is used to
|
||||
+ allocate a new response buffer, *ANSSIZP2 is set to the new buffer
|
||||
+ size and *ANSP2_MALLOCED is set to 1.
|
||||
+
|
||||
+ The ANSP2_MALLOCED argument will eventually be removed as the
|
||||
+ change in buffer pointer can be used to detect the buffer has
|
||||
+ changed and that the caller should use free on the new buffer.
|
||||
+
|
||||
+ Note that the answers may arrive in any order from the server and
|
||||
+ therefore the first and second answer buffers may not correspond to
|
||||
+ the first and second queries.
|
||||
+
|
||||
+ It is not supported to call this function with a non-NULL ANSP2
|
||||
+ but a NULL ANSCP. Put another way, you can call send_vc with a
|
||||
+ single unmodifiable buffer or two modifiable buffers, but no other
|
||||
+ combination is supported.
|
||||
+
|
||||
+ It is the caller's responsibility to free the malloc allocated
|
||||
+ buffers by detecting that the pointers have changed from their
|
||||
+ original values i.e. *ANSCP or *ANSP2 has changed.
|
||||
+
|
||||
+ If errors are encountered then *TERRNO is set to an appropriate
|
||||
+ errno value and a zero result is returned for a recoverable error,
|
||||
+ and a less-than zero result is returned for a non-recoverable error.
|
||||
+
|
||||
+ If no errors are encountered then *TERRNO is left unmodified and
|
||||
+ a the length of the first response in bytes is returned. */
|
||||
static int
|
||||
send_vc(res_state statp,
|
||||
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
|
||||
@@ -661,11 +751,7 @@ send_vc(res_state statp,
|
||||
{
|
||||
const HEADER *hp = (HEADER *) buf;
|
||||
const HEADER *hp2 = (HEADER *) buf2;
|
||||
- u_char *ans = *ansp;
|
||||
- int orig_anssizp = *anssizp;
|
||||
- // XXX REMOVE
|
||||
- // int anssiz = *anssizp;
|
||||
- HEADER *anhp = (HEADER *) ans;
|
||||
+ HEADER *anhp = (HEADER *) *ansp;
|
||||
struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
|
||||
int truncating, connreset, resplen, n;
|
||||
struct iovec iov[4];
|
||||
@@ -741,6 +827,8 @@ send_vc(res_state statp,
|
||||
* Receive length & response
|
||||
*/
|
||||
int recvresp1 = 0;
|
||||
+ /* Skip the second response if there is no second query.
|
||||
+ To do that we mark the second response as received. */
|
||||
int recvresp2 = buf2 == NULL;
|
||||
uint16_t rlen16;
|
||||
read_len:
|
||||
@@ -777,33 +865,14 @@ send_vc(res_state statp,
|
||||
u_char **thisansp;
|
||||
int *thisresplenp;
|
||||
if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
|
||||
+ /* We have not received any responses
|
||||
+ yet or we only have one response to
|
||||
+ receive. */
|
||||
thisanssizp = anssizp;
|
||||
thisansp = anscp ?: ansp;
|
||||
assert (anscp != NULL || ansp2 == NULL);
|
||||
thisresplenp = &resplen;
|
||||
} else {
|
||||
- if (*anssizp != MAXPACKET) {
|
||||
- /* No buffer allocated for the first
|
||||
- reply. We can try to use the rest
|
||||
- of the user-provided buffer. */
|
||||
-#ifdef _STRING_ARCH_unaligned
|
||||
- *anssizp2 = orig_anssizp - resplen;
|
||||
- *ansp2 = *ansp + resplen;
|
||||
-#else
|
||||
- int aligned_resplen
|
||||
- = ((resplen + __alignof__ (HEADER) - 1)
|
||||
- & ~(__alignof__ (HEADER) - 1));
|
||||
- *anssizp2 = orig_anssizp - aligned_resplen;
|
||||
- *ansp2 = *ansp + aligned_resplen;
|
||||
-#endif
|
||||
- } else {
|
||||
- /* The first reply did not fit into the
|
||||
- user-provided buffer. Maybe the second
|
||||
- answer will. */
|
||||
- *anssizp2 = orig_anssizp;
|
||||
- *ansp2 = *ansp;
|
||||
- }
|
||||
-
|
||||
thisanssizp = anssizp2;
|
||||
thisansp = ansp2;
|
||||
thisresplenp = resplen2;
|
||||
@@ -811,10 +880,14 @@ send_vc(res_state statp,
|
||||
anhp = (HEADER *) *thisansp;
|
||||
|
||||
*thisresplenp = rlen;
|
||||
- if (rlen > *thisanssizp) {
|
||||
- /* Yes, we test ANSCP here. If we have two buffers
|
||||
- both will be allocatable. */
|
||||
- if (__builtin_expect (anscp != NULL, 1)) {
|
||||
+ /* Is the answer buffer too small? */
|
||||
+ if (*thisanssizp < rlen) {
|
||||
+ /* If the current buffer is non-NULL and it's not
|
||||
+ pointing at the static user-supplied buffer then
|
||||
+ we can reallocate it. */
|
||||
+ if (thisansp != NULL && thisansp != ansp) {
|
||||
+ /* Always allocate MAXPACKET, callers expect
|
||||
+ this specific size. */
|
||||
u_char *newp = malloc (MAXPACKET);
|
||||
if (newp == NULL) {
|
||||
*terrno = ENOMEM;
|
||||
@@ -824,6 +897,9 @@ send_vc(res_state statp,
|
||||
*thisanssizp = MAXPACKET;
|
||||
*thisansp = newp;
|
||||
anhp = (HEADER *) newp;
|
||||
+ /* A uint16_t can't be larger than MAXPACKET
|
||||
+ thus it's safe to allocate MAXPACKET but
|
||||
+ read RLEN bytes instead. */
|
||||
len = rlen;
|
||||
} else {
|
||||
Dprint(statp->options & RES_DEBUG,
|
||||
@@ -987,6 +1063,66 @@ reopen (res_state statp, int *terrno, in
|
||||
return 1;
|
||||
}
|
||||
|
||||
+/* The send_dg function is responsible for sending a DNS query over UDP
|
||||
+ to the nameserver numbered NS from the res_state STATP i.e.
|
||||
+ EXT(statp).nssocks[ns]. The function supports IPv4 and IPv6 queries
|
||||
+ along with the ability to send the query in parallel for both stacks
|
||||
+ (default) or serially (RES_SINGLKUP). It also supports serial lookup
|
||||
+ with a close and reopen of the socket used to talk to the server
|
||||
+ (RES_SNGLKUPREOP) to work around broken name servers.
|
||||
+
|
||||
+ The query stored in BUF of BUFLEN length is sent first followed by
|
||||
+ the query stored in BUF2 of BUFLEN2 length. Queries are sent
|
||||
+ in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP).
|
||||
+
|
||||
+ Answers to the query are stored firstly in *ANSP up to a max of
|
||||
+ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
|
||||
+ is non-NULL (to indicate that modifying the answer buffer is allowed)
|
||||
+ then malloc is used to allocate a new response buffer and ANSCP and
|
||||
+ ANSP will both point to the new buffer. If more than *ANSSIZP bytes
|
||||
+ are needed but ANSCP is NULL, then as much of the response as
|
||||
+ possible is read into the buffer, but the results will be truncated.
|
||||
+ When truncation happens because of a small answer buffer the DNS
|
||||
+ packets header feild TC will bet set to 1, indicating a truncated
|
||||
+ message, while the rest of the UDP packet is discarded.
|
||||
+
|
||||
+ Answers to the query are stored secondly in *ANSP2 up to a max of
|
||||
+ *ANSSIZP2 bytes, with the actual response length stored in
|
||||
+ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
|
||||
+ is non-NULL (required for a second query) then malloc is used to
|
||||
+ allocate a new response buffer, *ANSSIZP2 is set to the new buffer
|
||||
+ size and *ANSP2_MALLOCED is set to 1.
|
||||
+
|
||||
+ The ANSP2_MALLOCED argument will eventually be removed as the
|
||||
+ change in buffer pointer can be used to detect the buffer has
|
||||
+ changed and that the caller should use free on the new buffer.
|
||||
+
|
||||
+ Note that the answers may arrive in any order from the server and
|
||||
+ therefore the first and second answer buffers may not correspond to
|
||||
+ the first and second queries.
|
||||
+
|
||||
+ It is not supported to call this function with a non-NULL ANSP2
|
||||
+ but a NULL ANSCP. Put another way, you can call send_vc with a
|
||||
+ single unmodifiable buffer or two modifiable buffers, but no other
|
||||
+ combination is supported.
|
||||
+
|
||||
+ It is the caller's responsibility to free the malloc allocated
|
||||
+ buffers by detecting that the pointers have changed from their
|
||||
+ original values i.e. *ANSCP or *ANSP2 has changed.
|
||||
+
|
||||
+ If an answer is truncated because of UDP datagram DNS limits then
|
||||
+ *V_CIRCUIT is set to 1 and the return value non-zero to indicate to
|
||||
+ the caller to retry with TCP. The value *GOTSOMEWHERE is set to 1
|
||||
+ if any progress was made reading a response from the nameserver and
|
||||
+ is used by the caller to distinguish between ECONNREFUSED and
|
||||
+ ETIMEDOUT (the latter if *GOTSOMEWHERE is 1).
|
||||
+
|
||||
+ If errors are encountered then *TERRNO is set to an appropriate
|
||||
+ errno value and a zero result is returned for a recoverable error,
|
||||
+ and a less-than zero result is returned for a non-recoverable error.
|
||||
+
|
||||
+ If no errors are encountered then *TERRNO is left unmodified and
|
||||
+ a the length of the first response in bytes is returned. */
|
||||
static int
|
||||
send_dg(res_state statp,
|
||||
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
|
||||
@@ -996,8 +1132,6 @@ send_dg(res_state statp,
|
||||
{
|
||||
const HEADER *hp = (HEADER *) buf;
|
||||
const HEADER *hp2 = (HEADER *) buf2;
|
||||
- u_char *ans = *ansp;
|
||||
- int orig_anssizp = *anssizp;
|
||||
struct timespec now, timeout, finish;
|
||||
struct pollfd pfd[1];
|
||||
int ptimeout;
|
||||
@@ -1029,6 +1163,8 @@ send_dg(res_state statp,
|
||||
int need_recompute = 0;
|
||||
int nwritten = 0;
|
||||
int recvresp1 = 0;
|
||||
+ /* Skip the second response if there is no second query.
|
||||
+ To do that we mark the second response as received. */
|
||||
int recvresp2 = buf2 == NULL;
|
||||
pfd[0].fd = EXT(statp).nssocks[ns];
|
||||
pfd[0].events = POLLOUT;
|
||||
@@ -1125,50 +1261,52 @@ send_dg(res_state statp,
|
||||
int *thisresplenp;
|
||||
|
||||
if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
|
||||
+ /* We have not received any responses
|
||||
+ yet or we only have one response to
|
||||
+ receive. */
|
||||
thisanssizp = anssizp;
|
||||
thisansp = anscp ?: ansp;
|
||||
assert (anscp != NULL || ansp2 == NULL);
|
||||
thisresplenp = &resplen;
|
||||
} else {
|
||||
- if (*anssizp != MAXPACKET) {
|
||||
- /* No buffer allocated for the first
|
||||
- reply. We can try to use the rest
|
||||
- of the user-provided buffer. */
|
||||
-#ifdef _STRING_ARCH_unaligned
|
||||
- *anssizp2 = orig_anssizp - resplen;
|
||||
- *ansp2 = *ansp + resplen;
|
||||
-#else
|
||||
- int aligned_resplen
|
||||
- = ((resplen + __alignof__ (HEADER) - 1)
|
||||
- & ~(__alignof__ (HEADER) - 1));
|
||||
- *anssizp2 = orig_anssizp - aligned_resplen;
|
||||
- *ansp2 = *ansp + aligned_resplen;
|
||||
-#endif
|
||||
- } else {
|
||||
- /* The first reply did not fit into the
|
||||
- user-provided buffer. Maybe the second
|
||||
- answer will. */
|
||||
- *anssizp2 = orig_anssizp;
|
||||
- *ansp2 = *ansp;
|
||||
- }
|
||||
-
|
||||
thisanssizp = anssizp2;
|
||||
thisansp = ansp2;
|
||||
thisresplenp = resplen2;
|
||||
}
|
||||
|
||||
if (*thisanssizp < MAXPACKET
|
||||
- /* Yes, we test ANSCP here. If we have two buffers
|
||||
- both will be allocatable. */
|
||||
- && anscp
|
||||
+ /* If the current buffer is non-NULL and it's not
|
||||
+ pointing at the static user-supplied buffer then
|
||||
+ we can reallocate it. */
|
||||
+ && (thisansp != NULL && thisansp != ansp)
|
||||
+ /* Is the size too small? */
|
||||
&& (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0
|
||||
- || *thisanssizp < *thisresplenp)) {
|
||||
+ || *thisanssizp < *thisresplenp)
|
||||
+ ) {
|
||||
+ /* Always allocate MAXPACKET, callers expect
|
||||
+ this specific size. */
|
||||
u_char *newp = malloc (MAXPACKET);
|
||||
if (newp != NULL) {
|
||||
- *anssizp = MAXPACKET;
|
||||
- *thisansp = ans = newp;
|
||||
+ *thisanssizp = MAXPACKET;
|
||||
+ *thisansp = newp;
|
||||
}
|
||||
}
|
||||
+ /* We could end up with truncation if anscp was NULL
|
||||
+ (not allowed to change caller's buffer) and the
|
||||
+ response buffer size is too small. This isn't a
|
||||
+ reliable way to detect truncation because the ioctl
|
||||
+ may be an inaccurate report of the UDP message size.
|
||||
+ Therefore we use this only to issue debug output.
|
||||
+ To do truncation accurately with UDP we need
|
||||
+ MSG_TRUNC which is only available on Linux. We
|
||||
+ can abstract out the Linux-specific feature in the
|
||||
+ future to detect truncation. */
|
||||
+ if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
|
||||
+ Dprint(statp->options & RES_DEBUG,
|
||||
+ (stdout, ";; response may be truncated (UDP)\n")
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
HEADER *anhp = (HEADER *) *thisansp;
|
||||
socklen_t fromlen = sizeof(struct sockaddr_in6);
|
||||
assert (sizeof(from) <= fromlen);
|
||||
Index: glibc-2.12-2-gc4ccff1/resolv/res_query.c
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/resolv/res_query.c
|
||||
+++ glibc-2.12-2-gc4ccff1/resolv/res_query.c
|
||||
@@ -391,6 +391,7 @@ __libc_res_nsearch(res_state statp,
|
||||
&& (*answerp2 < answer || *answerp2 >= answer + anslen))
|
||||
{
|
||||
free (*answerp2);
|
||||
+ *nanswerp2 = 0;
|
||||
*answerp2 = NULL;
|
||||
}
|
||||
}
|
||||
@@ -431,6 +432,7 @@ __libc_res_nsearch(res_state statp,
|
||||
|| *answerp2 >= answer + anslen))
|
||||
{
|
||||
free (*answerp2);
|
||||
+ *nanswerp2 = 0;
|
||||
*answerp2 = NULL;
|
||||
}
|
||||
|
||||
@@ -503,6 +505,7 @@ __libc_res_nsearch(res_state statp,
|
||||
if (answerp2 && (*answerp2 < answer || *answerp2 >= answer + anslen))
|
||||
{
|
||||
free (*answerp2);
|
||||
+ *nanswerp2 = NULL;
|
||||
*answerp2 = NULL;
|
||||
}
|
||||
if (saved_herrno != -1)
|
||||
@@ -1,61 +0,0 @@
|
||||
commit 2c1094bd700e63a8d7f547b3f5495bedb55c0a08
|
||||
Author: Ulrich Drepper <drepper@gmail.com>
|
||||
Date: Thu Dec 22 22:43:39 2011 -0500
|
||||
|
||||
Create internal threads with sufficient stack size
|
||||
|
||||
Index: glibc-2.12-2-gc4ccff1/nptl/Versions
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/nptl/Versions
|
||||
+++ glibc-2.12-2-gc4ccff1/nptl/Versions
|
||||
@@ -255,6 +255,6 @@ libpthread {
|
||||
GLIBC_PRIVATE {
|
||||
__pthread_initialize_minimal;
|
||||
__pthread_clock_gettime; __pthread_clock_settime;
|
||||
- __pthread_unwind;
|
||||
+ __pthread_unwind; __pthread_get_minstack;
|
||||
}
|
||||
}
|
||||
Index: glibc-2.12-2-gc4ccff1/nptl/nptl-init.c
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/nptl/nptl-init.c
|
||||
+++ glibc-2.12-2-gc4ccff1/nptl/nptl-init.c
|
||||
@@ -507,3 +507,13 @@ __pthread_initialize_minimal_internal (i
|
||||
}
|
||||
strong_alias (__pthread_initialize_minimal_internal,
|
||||
__pthread_initialize_minimal)
|
||||
+
|
||||
+
|
||||
+size_t
|
||||
+__pthread_get_minstack (const pthread_attr_t *attr)
|
||||
+{
|
||||
+ struct pthread_attr *iattr = (struct pthread_attr *) attr;
|
||||
+
|
||||
+ return (GLRO(dl_pagesize) + __static_tls_size + PTHREAD_STACK_MIN
|
||||
+ + iattr->guardsize);
|
||||
+}
|
||||
Index: glibc-2.12-2-gc4ccff1/nptl/pthreadP.h
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/nptl/pthreadP.h
|
||||
+++ glibc-2.12-2-gc4ccff1/nptl/pthreadP.h
|
||||
@@ -397,6 +397,7 @@ weak_function;
|
||||
|
||||
extern void __pthread_init_static_tls (struct link_map *) attribute_hidden;
|
||||
|
||||
+extern size_t __pthread_get_minstack (const pthread_attr_t *attr);
|
||||
|
||||
/* Namespace save aliases. */
|
||||
extern int __pthread_getschedparam (pthread_t thread_id, int *policy,
|
||||
Index: glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/timer_routines.c
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/nptl/sysdeps/unix/sysv/linux/timer_routines.c
|
||||
+++ glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/timer_routines.c
|
||||
@@ -165,7 +165,7 @@ __start_helper_thread (void)
|
||||
and should go away automatically when canceled. */
|
||||
pthread_attr_t attr;
|
||||
(void) pthread_attr_init (&attr);
|
||||
- (void) pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
|
||||
+ (void) pthread_attr_setstacksize (&attr, __pthread_get_minstack (&attr));
|
||||
|
||||
/* Block all signals in the helper thread but SIGSETXID. To do this
|
||||
thoroughly we temporarily have to block all signals here. The
|
||||
@@ -1,19 +0,0 @@
|
||||
commit 232872379ee82cd040a52a48cbbae65a249b5765
|
||||
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
|
||||
Date: Sun Jan 8 19:56:52 2012 -0500
|
||||
|
||||
Use __pthread_get_minstack for AIO helper thread
|
||||
|
||||
diff --git a/nptl/sysdeps/unix/sysv/linux/aio_misc.h b/nptl/sysdeps/unix/sysv/linux/aio_misc.h
|
||||
index 406d96e..8011c3e 100644
|
||||
--- a/nptl/sysdeps/unix/sysv/linux/aio_misc.h
|
||||
+++ b/nptl/sysdeps/unix/sysv/linux/aio_misc.h
|
||||
@@ -47,7 +47,7 @@ __aio_create_helper_thread (pthread_t *threadp, void *(*tf) (void *),
|
||||
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
|
||||
|
||||
/* The helper thread needs only very little resources. */
|
||||
- (void) pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
|
||||
+ (void) pthread_attr_setstacksize (&attr, __pthread_get_minstack (&attr));
|
||||
|
||||
/* Block all signals in the helper thread. To do this thoroughly we
|
||||
temporarily have to block all signals here. */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,296 +0,0 @@
|
||||
2010-07-03 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* tst-abstime.c (do_test): Some more cleanups
|
||||
|
||||
2010-07-02 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* tst-abstime.c: Correct testing and add test for sem_timedwait.
|
||||
|
||||
2010-07-01 Andreas Schwab <schwab@redhat.com>
|
||||
Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* Makefile (tests): Add tst-abstime.
|
||||
* tst-abstime.c: New file.
|
||||
* sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
|
||||
(__lll_timedlock_wait): Check for timestamp before the Epoch.
|
||||
* sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
|
||||
(__lll_timedlock_wait): Likewise.
|
||||
* sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
|
||||
(__lll_robust_timedlock_wait): Likewise.
|
||||
* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
|
||||
(__pthread_cond_timedwait): Likewise.
|
||||
* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
|
||||
(pthread_rwlock_timedrdlock): Likewise.
|
||||
* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
|
||||
(pthread_rwlock_timedwrlock): Likewise.
|
||||
* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S (sem_timedwait):
|
||||
Likewise.
|
||||
|
||||
Index: glibc-2.12-2-gc4ccff1/nptl/Makefile
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/nptl/Makefile
|
||||
+++ glibc-2.12-2-gc4ccff1/nptl/Makefile
|
||||
@@ -256,6 +256,7 @@ tests = tst-typesizes \
|
||||
tst-sched1 \
|
||||
tst-backtrace1 \
|
||||
tst-oddstacklimit \
|
||||
+ tst-abstime \
|
||||
tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \
|
||||
tst-getpid1 tst-getpid2 tst-getpid3 \
|
||||
tst-initializers1 $(patsubst %,tst-initializers1-%,c89 gnu89 c99 gnu99)
|
||||
Index: glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
|
||||
+++ glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
|
||||
@@ -188,6 +188,9 @@ __lll_timedlock_wait:
|
||||
je .Lreltmo
|
||||
# endif
|
||||
|
||||
+ cmpl $0, (%edx)
|
||||
+ js 8f
|
||||
+
|
||||
movl %ecx, %ebx
|
||||
movl %esi, %ecx
|
||||
movl %edx, %esi
|
||||
@@ -223,6 +226,9 @@ __lll_timedlock_wait:
|
||||
cfi_restore(%ebp)
|
||||
ret
|
||||
|
||||
+8: movl $ETIMEDOUT, %eax
|
||||
+ jmp 7b
|
||||
+
|
||||
# ifndef __ASSUME_FUTEX_CLOCK_REALTIME
|
||||
.Lreltmo:
|
||||
/* Check for a valid timeout value. */
|
||||
Index: glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
|
||||
+++ glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
|
||||
@@ -169,9 +169,13 @@ __lll_timedlock_wait:
|
||||
je .Lreltmo
|
||||
# endif
|
||||
|
||||
+ cmpq $0, (%rdx)
|
||||
+ js 5f
|
||||
+
|
||||
pushq %r9
|
||||
cfi_adjust_cfa_offset(8)
|
||||
cfi_rel_offset(%r9, 0)
|
||||
+
|
||||
movq %rdx, %r10
|
||||
movl $0xffffffff, %r9d
|
||||
LOAD_FUTEX_WAIT_ABS (%esi)
|
||||
@@ -202,6 +206,9 @@ __lll_timedlock_wait:
|
||||
cfi_restore(%r9)
|
||||
retq
|
||||
|
||||
+5: movl $ETIMEDOUT, %eax
|
||||
+ retq
|
||||
+
|
||||
# ifndef __ASSUME_FUTEX_CLOCK_REALTIME
|
||||
.Lreltmo:
|
||||
/* Check for a valid timeout value. */
|
||||
Index: glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
|
||||
+++ glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
|
||||
@@ -125,6 +125,9 @@ __lll_robust_timedlock_wait:
|
||||
je .Lreltmo
|
||||
# endif
|
||||
|
||||
+ cmpq $0, (%rdx)
|
||||
+ js 7f
|
||||
+
|
||||
pushq %r9
|
||||
cfi_adjust_cfa_offset(8)
|
||||
cfi_rel_offset(%r9, 0)
|
||||
@@ -180,6 +183,9 @@ __lll_robust_timedlock_wait:
|
||||
cfi_adjust_cfa_offset(-8)
|
||||
cfi_restore(%r9)
|
||||
|
||||
+7: movl $ETIMEDOUT, %eax
|
||||
+ retq
|
||||
+
|
||||
|
||||
# ifndef __ASSUME_FUTEX_CLOCK_REALTIME
|
||||
.Lreltmo:
|
||||
Index: glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
|
||||
+++ glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
|
||||
@@ -144,6 +144,10 @@ __pthread_cond_timedwait:
|
||||
movq %r9, 24(%rsp)
|
||||
movl %edx, 4(%rsp)
|
||||
|
||||
+ cmpq $0, (%r13)
|
||||
+ movq $-ETIMEDOUT, %r14
|
||||
+ js 36f
|
||||
+
|
||||
38: movl cond_futex(%rdi), %r12d
|
||||
|
||||
/* Unlock. */
|
||||
Index: glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
|
||||
+++ glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
|
||||
@@ -102,6 +102,9 @@ pthread_rwlock_timedrdlock:
|
||||
je .Lreltmo
|
||||
#endif
|
||||
|
||||
+ cmpq $0, (%r13)
|
||||
+ js 16f /* Time is already up. */
|
||||
+
|
||||
movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %esi
|
||||
xorl PSHARED(%r12), %esi
|
||||
movq %r13, %r10
|
||||
Index: glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
|
||||
+++ glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
|
||||
@@ -99,6 +99,9 @@ pthread_rwlock_timedwrlock:
|
||||
je .Lreltmo
|
||||
#endif
|
||||
|
||||
+ cmpq $0, (%r13)
|
||||
+ js 16f /* Time is already up. */
|
||||
+
|
||||
movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %esi
|
||||
xorl PSHARED(%r12), %esi
|
||||
movq %r13, %r10
|
||||
Index: glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
|
||||
+++ glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
|
||||
@@ -77,6 +77,9 @@ sem_timedwait:
|
||||
je .Lreltmo
|
||||
#endif
|
||||
|
||||
+ cmpq $0, (%rsi)
|
||||
+ js 16f
|
||||
+
|
||||
/* This push is only needed to store the sem_t pointer for the
|
||||
exception handler. */
|
||||
pushq %rdi
|
||||
@@ -169,6 +172,19 @@ sem_timedwait:
|
||||
|
||||
retq
|
||||
|
||||
+16:
|
||||
+#if USE___THREAD
|
||||
+ movq errno@gottpoff(%rip), %rdx
|
||||
+ movl $ETIMEDOUT, %fs:(%rdx)
|
||||
+#else
|
||||
+ callq __errno_location@plt
|
||||
+ movl $ETIMEDOUT, (%rax)
|
||||
+#endif
|
||||
+
|
||||
+ orl $-1, %eax
|
||||
+
|
||||
+ retq
|
||||
+
|
||||
#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
|
||||
.Lreltmo:
|
||||
pushq %r12
|
||||
Index: glibc-2.12-2-gc4ccff1/nptl/tst-abstime.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ glibc-2.12-2-gc4ccff1/nptl/tst-abstime.c
|
||||
@@ -0,0 +1,98 @@
|
||||
+/* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+ Contributed by Andreas Schwab <schwab@redhat.com>, 2010.
|
||||
+
|
||||
+ 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, write to the Free
|
||||
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
+ 02111-1307 USA. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <pthread.h>
|
||||
+#include <semaphore.h>
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
|
||||
+static pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER;
|
||||
+static pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER;
|
||||
+static pthread_rwlock_t rw1 = PTHREAD_RWLOCK_INITIALIZER;
|
||||
+static pthread_rwlock_t rw2 = PTHREAD_RWLOCK_INITIALIZER;
|
||||
+static sem_t sem;
|
||||
+
|
||||
+static void *
|
||||
+th (void *arg)
|
||||
+{
|
||||
+ long int res = 0;
|
||||
+ int r;
|
||||
+ struct timespec t = { -2, 0 };
|
||||
+
|
||||
+ r = pthread_mutex_timedlock (&m1, &t);
|
||||
+ if (r != ETIMEDOUT)
|
||||
+ {
|
||||
+ puts ("pthread_mutex_timedlock did not return ETIMEDOUT");
|
||||
+ res = 1;
|
||||
+ }
|
||||
+ r = pthread_rwlock_timedrdlock (&rw1, &t);
|
||||
+ if (r != ETIMEDOUT)
|
||||
+ {
|
||||
+ puts ("pthread_rwlock_timedrdlock did not return ETIMEDOUT");
|
||||
+ res = 1;
|
||||
+ }
|
||||
+ r = pthread_rwlock_timedwrlock (&rw2, &t);
|
||||
+ if (r != ETIMEDOUT)
|
||||
+ {
|
||||
+ puts ("pthread_rwlock_timedwrlock did not return ETIMEDOUT");
|
||||
+ res = 1;
|
||||
+ }
|
||||
+ return (void *) res;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ int res = 0;
|
||||
+ int r;
|
||||
+ struct timespec t = { -2, 0 };
|
||||
+ pthread_t pth;
|
||||
+
|
||||
+ sem_init (&sem, 0, 0);
|
||||
+ r = sem_timedwait (&sem, &t);
|
||||
+ if (r != -1 || errno != ETIMEDOUT)
|
||||
+ {
|
||||
+ puts ("sem_timedwait did not fail with ETIMEDOUT");
|
||||
+ res = 1;
|
||||
+ }
|
||||
+
|
||||
+ pthread_mutex_lock (&m1);
|
||||
+ pthread_rwlock_wrlock (&rw1);
|
||||
+ pthread_rwlock_rdlock (&rw2);
|
||||
+ pthread_mutex_lock (&m2);
|
||||
+ if (pthread_create (&pth, 0, th, 0) != 0)
|
||||
+ {
|
||||
+ puts ("cannot create thread");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ r = pthread_cond_timedwait (&c, &m2, &t);
|
||||
+ if (r != ETIMEDOUT)
|
||||
+ {
|
||||
+ puts ("pthread_cond_timedwait did not return ETIMEDOUT");
|
||||
+ res = 1;
|
||||
+ }
|
||||
+ void *thres;
|
||||
+ pthread_join (pth, &thres);
|
||||
+ return res | (thres != NULL);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#include "../test-skeleton.c"
|
||||
@@ -1,13 +0,0 @@
|
||||
Index: glibc-2.11-382-g1cdb215/nscd/nscd.init
|
||||
===================================================================
|
||||
--- glibc-2.11-382-g1cdb215.orig/nscd/nscd.init
|
||||
+++ glibc-2.11-382-g1cdb215/nscd/nscd.init
|
||||
@@ -76,7 +76,7 @@ case "$1" in
|
||||
RETVAL=$?
|
||||
;;
|
||||
stop)
|
||||
- stop
|
||||
+ [ ! -e /var/lock/subsys/nscd ] || stop
|
||||
RETVAL=$?
|
||||
;;
|
||||
status)
|
||||
@@ -1,13 +0,0 @@
|
||||
Index: glibc-2.11-382-g1cdb215/posix/regexec.c
|
||||
===================================================================
|
||||
--- glibc-2.11-382-g1cdb215.orig/posix/regexec.c
|
||||
+++ glibc-2.11-382-g1cdb215/posix/regexec.c
|
||||
@@ -4031,7 +4031,7 @@ find_collation_sequence_value (const uns
|
||||
/* Skip the collation sequence value. */
|
||||
idx += sizeof (uint32_t);
|
||||
/* Skip the wide char sequence of the collating element. */
|
||||
- idx = idx + sizeof (uint32_t) * (extra[idx] + 1);
|
||||
+ idx = idx + sizeof (uint32_t) * (*(int32_t *) (extra + idx) + 1);
|
||||
/* If we found the entry, return the sequence value. */
|
||||
if (found)
|
||||
return *(uint32_t *) (extra + idx);
|
||||
@@ -1,42 +0,0 @@
|
||||
2010-05-06 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* malloc/malloc.c (_int_free): Possible race in the most recently
|
||||
added check. Only act on the data if no current modification
|
||||
happened.
|
||||
|
||||
Index: glibc-2.12-2-gc4ccff1/malloc/malloc.c
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/malloc/malloc.c
|
||||
+++ glibc-2.12-2-gc4ccff1/malloc/malloc.c
|
||||
@@ -4859,6 +4859,7 @@ _int_free(mstate av, mchunkptr p)
|
||||
#ifdef ATOMIC_FASTBINS
|
||||
mchunkptr fd;
|
||||
mchunkptr old = *fb;
|
||||
+ unsigned int old_idx = ~0u;
|
||||
do
|
||||
{
|
||||
/* Another simple check: make sure the top of the bin is not the
|
||||
@@ -4868,15 +4869,17 @@ _int_free(mstate av, mchunkptr p)
|
||||
errstr = "double free or corruption (fasttop)";
|
||||
goto errout;
|
||||
}
|
||||
- if (old != NULL
|
||||
- && __builtin_expect (fastbin_index(chunksize(old)) != idx, 0))
|
||||
- {
|
||||
- errstr = "invalid fastbin entry (free)";
|
||||
- goto errout;
|
||||
- }
|
||||
+ if (old != NULL)
|
||||
+ old_idx = fastbin_index(chunksize(old));
|
||||
p->fd = fd = old;
|
||||
}
|
||||
while ((old = catomic_compare_and_exchange_val_rel (fb, p, fd)) != fd);
|
||||
+
|
||||
+ if (fd != NULL && __builtin_expect (old_idx != idx, 0))
|
||||
+ {
|
||||
+ errstr = "invalid fastbin entry (free)";
|
||||
+ goto errout;
|
||||
+ }
|
||||
#else
|
||||
/* Another simple check: make sure the top of the bin is not the
|
||||
record we are going to add (i.e., double free). */
|
||||
@@ -1,179 +0,0 @@
|
||||
2010-05-26 Andreas Schwab <schwab@redhat.com>
|
||||
|
||||
* elf/Makefile: Add rules to build and run unload8 test.
|
||||
* elf/unload8.c: New file.
|
||||
* elf/unload8mod1.c: New file.
|
||||
* elf/unload8mod1x.c: New file.
|
||||
* elf/unload8mod2.c: New file.
|
||||
* elf/unload8mod3.c: New file.
|
||||
|
||||
* elf/dl-close.c (_dl_close_worker): Reset private search list if
|
||||
it wasn't used.
|
||||
|
||||
Index: glibc-2.12-2-gc4ccff1/elf/Makefile
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/elf/Makefile
|
||||
+++ glibc-2.12-2-gc4ccff1/elf/Makefile
|
||||
@@ -89,6 +89,7 @@ distribute := rtld-Rules \
|
||||
unload4mod1.c unload4mod2.c unload4mod3.c unload4mod4.c \
|
||||
unload6mod1.c unload6mod2.c unload6mod3.c \
|
||||
unload7mod1.c unload7mod2.c \
|
||||
+ unload8mod1.c unload8mod1x.c unload8mod2.c unload8mod3.c \
|
||||
tst-audit1.c tst-audit2.c tst-audit3.c tst-audit4.c \
|
||||
tst-auditmod1.c tst-auditmod3a.c tst-auditmod3b.c \
|
||||
tst-auditmod4a.c tst-auditmod4b.c \
|
||||
@@ -196,7 +197,7 @@ tests += loadtest restest1 preloadtest l
|
||||
tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \
|
||||
tst-dlmodcount tst-dlopenrpath tst-deep1 \
|
||||
tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \
|
||||
- unload3 unload4 unload5 unload6 unload7 tst-global1 order2 \
|
||||
+ unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \
|
||||
tst-audit1 tst-audit2 \
|
||||
tst-stackguard1 tst-addr1 tst-thrlock \
|
||||
tst-unique1 tst-unique2
|
||||
@@ -247,6 +248,7 @@ modules-names = testobj1 testobj2 testob
|
||||
unload4mod1 unload4mod2 unload4mod3 unload4mod4 \
|
||||
unload6mod1 unload6mod2 unload6mod3 \
|
||||
unload7mod1 unload7mod2 \
|
||||
+ unload8mod1 unload8mod1x unload8mod2 unload8mod3 \
|
||||
order2mod1 order2mod2 order2mod3 order2mod4 \
|
||||
tst-unique1mod1 tst-unique1mod2 \
|
||||
tst-unique2mod1 tst-unique2mod2
|
||||
@@ -522,6 +524,9 @@ $(objpfx)unload6mod2.so: $(libdl)
|
||||
$(objpfx)unload6mod3.so: $(libdl)
|
||||
$(objpfx)unload7mod1.so: $(libdl)
|
||||
$(objpfx)unload7mod2.so: $(objpfx)unload7mod1.so
|
||||
+$(objpfx)unload8mod1.so: $(objpfx)unload8mod2.so
|
||||
+$(objpfx)unload8mod2.so: $(objpfx)unload8mod3.so
|
||||
+$(objpfx)unload8mod3.so: $(libdl)
|
||||
|
||||
LDFLAGS-tst-tlsmod5.so = -nostdlib
|
||||
LDFLAGS-tst-tlsmod6.so = -nostdlib
|
||||
@@ -823,6 +828,9 @@ $(objpfx)unload7: $(libdl)
|
||||
$(objpfx)unload7.out: $(objpfx)unload7mod1.so $(objpfx)unload7mod2.so
|
||||
unload7-ENV = MALLOC_PERTURB_=85
|
||||
|
||||
+$(objpfx)unload8: $(libdl)
|
||||
+$(objpfx)unload8.out: $(objpfx)unload8mod1.so $(objpfx)unload8mod1x.so
|
||||
+
|
||||
ifdef libdl
|
||||
$(objpfx)tst-tls9-static: $(common-objpfx)dlfcn/libdl.a
|
||||
$(objpfx)tst-tls9-static.out: $(objpfx)tst-tlsmod5.so $(objpfx)tst-tlsmod6.so
|
||||
Index: glibc-2.12-2-gc4ccff1/elf/dl-close.c
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/elf/dl-close.c
|
||||
+++ glibc-2.12-2-gc4ccff1/elf/dl-close.c
|
||||
@@ -421,6 +421,13 @@ _dl_close_worker (struct link_map *map)
|
||||
|
||||
imap->l_scope_max = new_size;
|
||||
}
|
||||
+ else if (new_list != NULL)
|
||||
+ {
|
||||
+ /* We didn't change the scope array, so reset the search
|
||||
+ list. */
|
||||
+ imap->l_searchlist.r_list = NULL;
|
||||
+ imap->l_searchlist.r_nlist = 0;
|
||||
+ }
|
||||
|
||||
/* The loader is gone, so mark the object as not having one.
|
||||
Note: l_idx != IDX_STILL_USED -> object will be removed. */
|
||||
Index: glibc-2.12-2-gc4ccff1/elf/unload8.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ glibc-2.12-2-gc4ccff1/elf/unload8.c
|
||||
@@ -0,0 +1,33 @@
|
||||
+#include <dlfcn.h>
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+int
|
||||
+main (void)
|
||||
+{
|
||||
+ void *h = dlopen ("$ORIGIN/unload8mod1.so", RTLD_LAZY);
|
||||
+ if (h == NULL)
|
||||
+ {
|
||||
+ puts ("dlopen unload8mod1.so failed");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ void *h2 = dlopen ("$ORIGIN/unload8mod1x.so", RTLD_LAZY);
|
||||
+ if (h2 == NULL)
|
||||
+ {
|
||||
+ puts ("dlopen unload8mod1x.so failed");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ dlclose (h2);
|
||||
+
|
||||
+ int (*mod1) (void) = dlsym (h, "mod1");
|
||||
+ if (mod1 == NULL)
|
||||
+ {
|
||||
+ puts ("dlsym failed");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ mod1 ();
|
||||
+ dlclose (h);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
Index: glibc-2.12-2-gc4ccff1/elf/unload8mod1.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ glibc-2.12-2-gc4ccff1/elf/unload8mod1.c
|
||||
@@ -0,0 +1,7 @@
|
||||
+extern void mod2 (void);
|
||||
+
|
||||
+void
|
||||
+mod1 (void)
|
||||
+{
|
||||
+ mod2 ();
|
||||
+}
|
||||
Index: glibc-2.12-2-gc4ccff1/elf/unload8mod1x.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ glibc-2.12-2-gc4ccff1/elf/unload8mod1x.c
|
||||
@@ -0,0 +1 @@
|
||||
+int mod1x;
|
||||
Index: glibc-2.12-2-gc4ccff1/elf/unload8mod2.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ glibc-2.12-2-gc4ccff1/elf/unload8mod2.c
|
||||
@@ -0,0 +1,7 @@
|
||||
+extern void mod3 (void);
|
||||
+
|
||||
+void
|
||||
+mod2 (void)
|
||||
+{
|
||||
+ mod3 ();
|
||||
+}
|
||||
Index: glibc-2.12-2-gc4ccff1/elf/unload8mod3.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ glibc-2.12-2-gc4ccff1/elf/unload8mod3.c
|
||||
@@ -0,0 +1,27 @@
|
||||
+#include <dlfcn.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+void
|
||||
+mod3_fini2 (void)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+mod3_fini (void)
|
||||
+{
|
||||
+ mod3_fini2 ();
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+mod3 (void)
|
||||
+{
|
||||
+ void *h = dlopen ("$ORIGIN/unload8mod2.so", RTLD_LAZY);
|
||||
+ if (h == NULL)
|
||||
+ {
|
||||
+ puts ("dlopen unload8mod2.so failed");
|
||||
+ exit (1);
|
||||
+ }
|
||||
+
|
||||
+ atexit (mod3_fini);
|
||||
+}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,26 +0,0 @@
|
||||
2010-09-07 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* sysdeps/x86_64/cacheinfo.c (init_cacheinfo): Round cache sizes
|
||||
up to multiple of 256 bytes.
|
||||
|
||||
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/cacheinfo.c
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/x86_64/cacheinfo.c
|
||||
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/cacheinfo.c
|
||||
@@ -661,12 +661,16 @@ init_cacheinfo (void)
|
||||
|
||||
if (data > 0)
|
||||
{
|
||||
+ /* Round data cache size up to multiple of 256 bytes. */
|
||||
+ data = (data + 255) & ~255L;
|
||||
__x86_64_data_cache_size_half = data / 2;
|
||||
__x86_64_data_cache_size = data;
|
||||
}
|
||||
|
||||
if (shared > 0)
|
||||
{
|
||||
+ /* Round shared cache size up to multiple of 256 bytes. */
|
||||
+ shared = (shared + 255) & ~255L;
|
||||
__x86_64_shared_cache_size_half = shared / 2;
|
||||
__x86_64_shared_cache_size = shared;
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
Index: glibc-2.12-2-gc4ccff1/nptl/allocatestack.c
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/nptl/allocatestack.c
|
||||
+++ glibc-2.12-2-gc4ccff1/nptl/allocatestack.c
|
||||
@@ -994,7 +994,16 @@ setxid_mark_thread (struct xid_command *
|
||||
|
||||
/* If the thread is exiting right now, ignore it. */
|
||||
if ((ch & EXITING_BITMASK) != 0)
|
||||
- return;
|
||||
+ {
|
||||
+ /* Release the futex if there is no other setxid in
|
||||
+ progress. */
|
||||
+ if ((ch & SETXID_BITMASK) == 0)
|
||||
+ {
|
||||
+ t->setxid_futex = 1;
|
||||
+ lll_futex_wake (&t->setxid_futex, 1, LLL_PRIVATE);
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
while (atomic_compare_and_exchange_bool_acq (&t->cancelhandling,
|
||||
ch | SETXID_BITMASK, ch));
|
||||
@@ -1,21 +0,0 @@
|
||||
2010-07-27 Andreas Schwab <schwab@redhat.com>
|
||||
|
||||
* manual/memory.texi (Malloc Tunable Parameters): Document
|
||||
M_PERTURB.
|
||||
|
||||
Index: glibc-2.12-2-gc4ccff1/manual/memory.texi
|
||||
===================================================================
|
||||
--- glibc-2.12-2-gc4ccff1.orig/manual/memory.texi
|
||||
+++ glibc-2.12-2-gc4ccff1/manual/memory.texi
|
||||
@@ -702,6 +702,11 @@ be allocated via @code{mmap}.
|
||||
@item M_MMAP_MAX
|
||||
The maximum number of chunks to allocate with @code{mmap}. Setting this
|
||||
to zero disables all use of @code{mmap}.
|
||||
+@item M_PERTURB
|
||||
+If non-zero, memory blocks are filled with values depending on some
|
||||
+low order bits of this parameter when they are allocated (except when
|
||||
+allocated by @code{calloc}) and freed. This can be used to debug the
|
||||
+use of uninitialized or freed heap memory.
|
||||
@end table
|
||||
|
||||
@end deftypefun
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user