gnu: Add jmtpfs.
[jackhill/guix/guix.git] / gnu / packages / patches / glibc-CVE-2017-1000366-pt3.patch
1 From 6d0ba622891bed9d8394eef1935add53003b12e8 Mon Sep 17 00:00:00 2001
2 From: Florian Weimer <fweimer@redhat.com>
3 Date: Mon, 19 Jun 2017 22:31:04 +0200
4 Subject: [PATCH] ld.so: Reject overly long LD_PRELOAD path elements
5
6 patch from:
7 https://sourceware.org/git/?p=glibc.git;a=patch;h=6d0ba622891bed9d8394eef1935add53003b12e8
8
9 ---
10 ChangeLog | 7 ++++++
11 elf/rtld.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++------------
12 2 files changed, 73 insertions(+), 16 deletions(-)
13
14 diff --git a/elf/rtld.c b/elf/rtld.c
15 index 2269dbe..86ae20c 100644
16 --- a/elf/rtld.c
17 +++ b/elf/rtld.c
18 @@ -99,6 +99,35 @@ uintptr_t __pointer_chk_guard_local
19 strong_alias (__pointer_chk_guard_local, __pointer_chk_guard)
20 #endif
21
22 +/* Length limits for names and paths, to protect the dynamic linker,
23 + particularly when __libc_enable_secure is active. */
24 +#ifdef NAME_MAX
25 +# define SECURE_NAME_LIMIT NAME_MAX
26 +#else
27 +# define SECURE_NAME_LIMIT 255
28 +#endif
29 +#ifdef PATH_MAX
30 +# define SECURE_PATH_LIMIT PATH_MAX
31 +#else
32 +# define SECURE_PATH_LIMIT 1024
33 +#endif
34 +
35 +/* Check that AT_SECURE=0, or that the passed name does not contain
36 + directories and is not overly long. Reject empty names
37 + unconditionally. */
38 +static bool
39 +dso_name_valid_for_suid (const char *p)
40 +{
41 + if (__glibc_unlikely (__libc_enable_secure))
42 + {
43 + /* Ignore pathnames with directories for AT_SECURE=1
44 + programs, and also skip overlong names. */
45 + size_t len = strlen (p);
46 + if (len >= SECURE_NAME_LIMIT || memchr (p, '/', len) != NULL)
47 + return false;
48 + }
49 + return *p != '\0';
50 +}
51
52 /* List of auditing DSOs. */
53 static struct audit_list
54 @@ -718,6 +747,42 @@ static const char *preloadlist attribute_relro;
55 /* Nonzero if information about versions has to be printed. */
56 static int version_info attribute_relro;
57
58 +/* The LD_PRELOAD environment variable gives list of libraries
59 + separated by white space or colons that are loaded before the
60 + executable's dependencies and prepended to the global scope list.
61 + (If the binary is running setuid all elements containing a '/' are
62 + ignored since it is insecure.) Return the number of preloads
63 + performed. */
64 +unsigned int
65 +handle_ld_preload (const char *preloadlist, struct link_map *main_map)
66 +{
67 + unsigned int npreloads = 0;
68 + const char *p = preloadlist;
69 + char fname[SECURE_PATH_LIMIT];
70 +
71 + while (*p != '\0')
72 + {
73 + /* Split preload list at space/colon. */
74 + size_t len = strcspn (p, " :");
75 + if (len > 0 && len < sizeof (fname))
76 + {
77 + memcpy (fname, p, len);
78 + fname[len] = '\0';
79 + }
80 + else
81 + fname[0] = '\0';
82 +
83 + /* Skip over the substring and the following delimiter. */
84 + p += len;
85 + if (*p != '\0')
86 + ++p;
87 +
88 + if (dso_name_valid_for_suid (fname))
89 + npreloads += do_preload (fname, main_map, "LD_PRELOAD");
90 + }
91 + return npreloads;
92 +}
93 +
94 static void
95 dl_main (const ElfW(Phdr) *phdr,
96 ElfW(Word) phnum,
97 @@ -1464,23 +1529,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
98
99 if (__glibc_unlikely (preloadlist != NULL))
100 {
101 - /* The LD_PRELOAD environment variable gives list of libraries
102 - separated by white space or colons that are loaded before the
103 - executable's dependencies and prepended to the global scope
104 - list. If the binary is running setuid all elements
105 - containing a '/' are ignored since it is insecure. */
106 - char *list = strdupa (preloadlist);
107 - char *p;
108 -
109 HP_TIMING_NOW (start);
110 -
111 - /* Prevent optimizing strsep. Speed is not important here. */
112 - while ((p = (strsep) (&list, " :")) != NULL)
113 - if (p[0] != '\0'
114 - && (__builtin_expect (! __libc_enable_secure, 1)
115 - || strchr (p, '/') == NULL))
116 - npreloads += do_preload (p, main_map, "LD_PRELOAD");
117 -
118 + npreloads += handle_ld_preload (preloadlist, main_map);
119 HP_TIMING_NOW (stop);
120 HP_TIMING_DIFF (diff, start, stop);
121 HP_TIMING_ACCUM_NT (load_time, diff);
122 --
123 2.9.3
124