diff options
Diffstat (limited to 'meta/recipes-core/glibc/glibc/0002-ld.so-Reject-overly-long-LD_PRELOAD-path-elements.patch')
-rw-r--r-- | meta/recipes-core/glibc/glibc/0002-ld.so-Reject-overly-long-LD_PRELOAD-path-elements.patch | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/meta/recipes-core/glibc/glibc/0002-ld.so-Reject-overly-long-LD_PRELOAD-path-elements.patch b/meta/recipes-core/glibc/glibc/0002-ld.so-Reject-overly-long-LD_PRELOAD-path-elements.patch new file mode 100644 index 0000000000..7f81ed1566 --- /dev/null +++ b/meta/recipes-core/glibc/glibc/0002-ld.so-Reject-overly-long-LD_PRELOAD-path-elements.patch | |||
@@ -0,0 +1,145 @@ | |||
1 | From 6d49272e6d6741496e3456f2cc22ebc2b9f7f989 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 | (cherry picked from commit 6d0ba622891bed9d8394eef1935add53003b12e8) | ||
7 | |||
8 | Upstream-Status: Backport | ||
9 | https://sourceware.org/git/?p=glibc.git;a=commit;h=aab04ca5d359150e17631e6a9b44b65e93bdc467 | ||
10 | https://anonscm.debian.org/cgit/pkg-glibc/glibc.git/commit/?h=stretch&id=2755c57269f24e9d59c22c49788f92515346c1bb | ||
11 | |||
12 | CVE: CVE-2017-1000366 | ||
13 | |||
14 | Signed-off-by: George McCollister <george.mccollister@gmail.com> | ||
15 | --- | ||
16 | ChangeLog | 7 ++++++ | ||
17 | elf/rtld.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ | ||
18 | 2 files changed, 73 insertions(+), 16 deletions(-) | ||
19 | |||
20 | diff --git a/ChangeLog b/ChangeLog | ||
21 | index 7a999802dd..ea5ecd4a1e 100644 | ||
22 | --- a/ChangeLog | ||
23 | +++ b/ChangeLog | ||
24 | @@ -1,3 +1,10 @@ | ||
25 | +2017-06-19 Florian Weimer <fweimer@redhat.com> | ||
26 | + | ||
27 | + * elf/rtld.c (SECURE_NAME_LIMIT, SECURE_PATH_LIMIT): Define. | ||
28 | + (dso_name_valid_for_suid): New function. | ||
29 | + (handle_ld_preload): Likewise. | ||
30 | + (dl_main): Call it. Remove alloca. | ||
31 | + | ||
32 | 2017-06-19 Florian Weimer <fweimer@redhat.com> | ||
33 | |||
34 | [BZ #21624] | ||
35 | diff --git a/elf/rtld.c b/elf/rtld.c | ||
36 | index 215a9aec8f..1d8eab9fe2 100644 | ||
37 | --- a/elf/rtld.c | ||
38 | +++ b/elf/rtld.c | ||
39 | @@ -99,6 +99,35 @@ uintptr_t __pointer_chk_guard_local | ||
40 | strong_alias (__pointer_chk_guard_local, __pointer_chk_guard) | ||
41 | #endif | ||
42 | |||
43 | +/* Length limits for names and paths, to protect the dynamic linker, | ||
44 | + particularly when __libc_enable_secure is active. */ | ||
45 | +#ifdef NAME_MAX | ||
46 | +# define SECURE_NAME_LIMIT NAME_MAX | ||
47 | +#else | ||
48 | +# define SECURE_NAME_LIMIT 255 | ||
49 | +#endif | ||
50 | +#ifdef PATH_MAX | ||
51 | +# define SECURE_PATH_LIMIT PATH_MAX | ||
52 | +#else | ||
53 | +# define SECURE_PATH_LIMIT 1024 | ||
54 | +#endif | ||
55 | + | ||
56 | +/* Check that AT_SECURE=0, or that the passed name does not contain | ||
57 | + directories and is not overly long. Reject empty names | ||
58 | + unconditionally. */ | ||
59 | +static bool | ||
60 | +dso_name_valid_for_suid (const char *p) | ||
61 | +{ | ||
62 | + if (__glibc_unlikely (__libc_enable_secure)) | ||
63 | + { | ||
64 | + /* Ignore pathnames with directories for AT_SECURE=1 | ||
65 | + programs, and also skip overlong names. */ | ||
66 | + size_t len = strlen (p); | ||
67 | + if (len >= SECURE_NAME_LIMIT || memchr (p, '/', len) != NULL) | ||
68 | + return false; | ||
69 | + } | ||
70 | + return *p != '\0'; | ||
71 | +} | ||
72 | |||
73 | /* List of auditing DSOs. */ | ||
74 | static struct audit_list | ||
75 | @@ -730,6 +759,42 @@ static const char *preloadlist attribute_relro; | ||
76 | /* Nonzero if information about versions has to be printed. */ | ||
77 | static int version_info attribute_relro; | ||
78 | |||
79 | +/* The LD_PRELOAD environment variable gives list of libraries | ||
80 | + separated by white space or colons that are loaded before the | ||
81 | + executable's dependencies and prepended to the global scope list. | ||
82 | + (If the binary is running setuid all elements containing a '/' are | ||
83 | + ignored since it is insecure.) Return the number of preloads | ||
84 | + performed. */ | ||
85 | +unsigned int | ||
86 | +handle_ld_preload (const char *preloadlist, struct link_map *main_map) | ||
87 | +{ | ||
88 | + unsigned int npreloads = 0; | ||
89 | + const char *p = preloadlist; | ||
90 | + char fname[SECURE_PATH_LIMIT]; | ||
91 | + | ||
92 | + while (*p != '\0') | ||
93 | + { | ||
94 | + /* Split preload list at space/colon. */ | ||
95 | + size_t len = strcspn (p, " :"); | ||
96 | + if (len > 0 && len < sizeof (fname)) | ||
97 | + { | ||
98 | + memcpy (fname, p, len); | ||
99 | + fname[len] = '\0'; | ||
100 | + } | ||
101 | + else | ||
102 | + fname[0] = '\0'; | ||
103 | + | ||
104 | + /* Skip over the substring and the following delimiter. */ | ||
105 | + p += len; | ||
106 | + if (*p != '\0') | ||
107 | + ++p; | ||
108 | + | ||
109 | + if (dso_name_valid_for_suid (fname)) | ||
110 | + npreloads += do_preload (fname, main_map, "LD_PRELOAD"); | ||
111 | + } | ||
112 | + return npreloads; | ||
113 | +} | ||
114 | + | ||
115 | static void | ||
116 | dl_main (const ElfW(Phdr) *phdr, | ||
117 | ElfW(Word) phnum, | ||
118 | @@ -1481,23 +1546,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", | ||
119 | |||
120 | if (__glibc_unlikely (preloadlist != NULL)) | ||
121 | { | ||
122 | - /* The LD_PRELOAD environment variable gives list of libraries | ||
123 | - separated by white space or colons that are loaded before the | ||
124 | - executable's dependencies and prepended to the global scope | ||
125 | - list. If the binary is running setuid all elements | ||
126 | - containing a '/' are ignored since it is insecure. */ | ||
127 | - char *list = strdupa (preloadlist); | ||
128 | - char *p; | ||
129 | - | ||
130 | HP_TIMING_NOW (start); | ||
131 | - | ||
132 | - /* Prevent optimizing strsep. Speed is not important here. */ | ||
133 | - while ((p = (strsep) (&list, " :")) != NULL) | ||
134 | - if (p[0] != '\0' | ||
135 | - && (__builtin_expect (! __libc_enable_secure, 1) | ||
136 | - || strchr (p, '/') == NULL)) | ||
137 | - npreloads += do_preload (p, main_map, "LD_PRELOAD"); | ||
138 | - | ||
139 | + npreloads += handle_ld_preload (preloadlist, main_map); | ||
140 | HP_TIMING_NOW (stop); | ||
141 | HP_TIMING_DIFF (diff, start, stop); | ||
142 | HP_TIMING_ACCUM_NT (load_time, diff); | ||
143 | -- | ||
144 | 2.15.0 | ||
145 | |||