]> git.pld-linux.org Git - packages/xen.git/blame - 0010-libelf-check-nul-terminated-strings-properly.patch
- rel 4
[packages/xen.git] / 0010-libelf-check-nul-terminated-strings-properly.patch
CommitLineData
23d51c33
JR
1From db14d5bd9b6508adfcd2b910f454fae12fa4ba00 Mon Sep 17 00:00:00 2001
2From: Ian Jackson <ian.jackson@eu.citrix.com>
3Date: Fri, 14 Jun 2013 16:43:17 +0100
4Subject: [PATCH 10/23] libelf: check nul-terminated strings properly
5
6It is not safe to simply take pointers into the ELF and use them as C
7pointers. They might not be properly nul-terminated (and the pointers
8might be wild).
9
10So we are going to introduce a new function elf_strval for safely
11getting strings. This will check that the addresses are in range and
12that there is a proper nul-terminated string. Of course it might
13discover that there isn't. In that case, it will be made to fail.
14This means that elf_note_name might fail, too.
15
16For the benefit of call sites which are just going to pass the value
17to a printf-like function, we provide elf_strfmt which returns
18"(invalid)" on failure rather than NULL.
19
20In this patch we introduce dummy definitions of these functions. We
21introduce calls to elf_strval and elf_strfmt everywhere, and update
22all the call sites with appropriate error checking.
23
24There is not yet any semantic change, since before this patch all the
25places where we introduce elf_strval dereferenced the value anyway, so
26it mustn't have been NULL.
27
28In future patches, when elf_strval is made able return NULL, when it
29does so it will mark the elf "broken" so that an appropriate
30diagnostic can be printed.
31
32This is part of the fix to a security issue, XSA-55.
33
34Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
35Acked-by: Ian Campbell <ian.campbell@citrix.com>
36Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
37---
38 tools/xcutils/readnotes.c | 11 ++++++++---
39 xen/common/libelf/libelf-dominfo.c | 13 ++++++++++---
40 xen/common/libelf/libelf-tools.c | 10 +++++++---
41 xen/include/xen/libelf.h | 7 +++++--
42 4 files changed, 30 insertions(+), 11 deletions(-)
43
44diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
45index 7ff2530..cfae994 100644
46--- a/tools/xcutils/readnotes.c
47+++ b/tools/xcutils/readnotes.c
48@@ -63,7 +63,7 @@ struct setup_header {
49 static void print_string_note(const char *prefix, struct elf_binary *elf,
50 ELF_HANDLE_DECL(elf_note) note)
51 {
52- printf("%s: %s\n", prefix, (char*)elf_note_desc(elf, note));
53+ printf("%s: %s\n", prefix, elf_strfmt(elf, elf_note_desc(elf, note)));
54 }
55
56 static void print_numeric_note(const char *prefix, struct elf_binary *elf,
57@@ -103,10 +103,14 @@ static int print_notes(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) start,
58 {
59 ELF_HANDLE_DECL(elf_note) note;
60 int notes_found = 0;
61+ const char *this_note_name;
62
63 for ( note = start; ELF_HANDLE_PTRVAL(note) < ELF_HANDLE_PTRVAL(end); note = elf_note_next(elf, note) )
64 {
65- if (0 != strcmp(elf_note_name(elf, note), "Xen"))
66+ this_note_name = elf_note_name(elf, note);
67+ if (NULL == this_note_name)
68+ continue;
69+ if (0 != strcmp(this_note_name, "Xen"))
70 continue;
71
72 notes_found++;
73@@ -294,7 +298,8 @@ int main(int argc, char **argv)
74
75 shdr = elf_shdr_by_name(&elf, "__xen_guest");
76 if (ELF_HANDLE_VALID(shdr))
77- printf("__xen_guest: %s\n", (char*)elf_section_start(&elf, shdr));
78+ printf("__xen_guest: %s\n",
79+ elf_strfmt(&elf, elf_section_start(&elf, shdr)));
80
81 return 0;
82 }
83diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
84index 7140d59..b217f8f 100644
85--- a/xen/common/libelf/libelf-dominfo.c
86+++ b/xen/common/libelf/libelf-dominfo.c
87@@ -137,7 +137,10 @@ int elf_xen_parse_note(struct elf_binary *elf,
88
89 if ( note_desc[type].str )
90 {
91- str = elf_note_desc(elf, note);
92+ str = elf_strval(elf, elf_note_desc(elf, note));
93+ if (str == NULL)
94+ /* elf_strval will mark elf broken if it fails so no need to log */
95+ return 0;
96 elf_msg(elf, "%s: %s = \"%s\"\n", __FUNCTION__,
97 note_desc[type].name, str);
98 parms->elf_notes[type].type = XEN_ENT_STR;
99@@ -220,6 +223,7 @@ static int elf_xen_parse_notes(struct elf_binary *elf,
100 {
101 int xen_elfnotes = 0;
102 ELF_HANDLE_DECL(elf_note) note;
103+ const char *note_name;
104
105 parms->elf_note_start = start;
106 parms->elf_note_end = end;
107@@ -227,7 +231,10 @@ static int elf_xen_parse_notes(struct elf_binary *elf,
108 ELF_HANDLE_PTRVAL(note) < parms->elf_note_end;
109 note = elf_note_next(elf, note) )
110 {
111- if ( strcmp(elf_note_name(elf, note), "Xen") )
112+ note_name = elf_note_name(elf, note);
113+ if ( note_name == NULL )
114+ continue;
115+ if ( strcmp(note_name, "Xen") )
116 continue;
117 if ( elf_xen_parse_note(elf, parms, note) )
118 return -1;
119@@ -541,7 +548,7 @@ int elf_xen_parse(struct elf_binary *elf,
120 parms->elf_note_start = ELF_INVALID_PTRVAL;
121 parms->elf_note_end = ELF_INVALID_PTRVAL;
122 elf_msg(elf, "%s: __xen_guest: \"%s\"\n", __FUNCTION__,
123- parms->guest_info);
124+ elf_strfmt(elf, parms->guest_info));
125 elf_xen_parse_guest_info(elf, parms);
126 break;
127 }
128diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
129index f1fd886..3a0cde1 100644
130--- a/xen/common/libelf/libelf-tools.c
131+++ b/xen/common/libelf/libelf-tools.c
132@@ -119,7 +119,7 @@ const char *elf_section_name(struct elf_binary *elf,
133 if ( ELF_PTRVAL_INVALID(elf->sec_strtab) )
134 return "unknown";
135
136- return elf->sec_strtab + elf_uval(elf, shdr, sh_name);
137+ return elf_strval(elf, elf->sec_strtab + elf_uval(elf, shdr, sh_name));
138 }
139
140 ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr)
141@@ -151,6 +151,7 @@ ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *sym
142 ELF_PTRVAL_CONST_VOID end = elf_section_end(elf, elf->sym_tab);
143 ELF_HANDLE_DECL(elf_sym) sym;
144 uint64_t info, name;
145+ const char *sym_name;
146
147 for ( ; ptr < end; ptr += elf_size(elf, sym) )
148 {
149@@ -159,7 +160,10 @@ ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *sym
150 name = elf_uval(elf, sym, st_name);
151 if ( ELF32_ST_BIND(info) != STB_GLOBAL )
152 continue;
153- if ( strcmp(elf->sym_strtab + name, symbol) )
154+ sym_name = elf_strval(elf, elf->sym_strtab + name);
155+ if ( sym_name == NULL ) /* out of range, oops */
156+ return ELF_INVALID_HANDLE(elf_sym);
157+ if ( strcmp(sym_name, symbol) )
158 continue;
159 return sym;
160 }
161@@ -177,7 +181,7 @@ ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, int index)
162
163 const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
164 {
165- return ELF_HANDLE_PTRVAL(note) + elf_size(elf, note);
166+ return elf_strval(elf, ELF_HANDLE_PTRVAL(note) + elf_size(elf, note));
167 }
168
169 ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
170diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
171index cefd3d3..af5b5c5 100644
172--- a/xen/include/xen/libelf.h
173+++ b/xen/include/xen/libelf.h
174@@ -252,6 +252,9 @@ uint64_t elf_access_unsigned(struct elf_binary *elf, ELF_PTRVAL_CONST_VOID ptr,
175 uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr);
176
177
178+#define elf_strval(elf,x) ((const char*)(x)) /* may return NULL in the future */
179+#define elf_strfmt(elf,x) ((const char*)(x)) /* will return (invalid) instead */
180+
181 #define elf_memcpy_safe(elf, dst, src, sz) memcpy((dst),(src),(sz))
182 #define elf_memset_safe(elf, dst, c, sz) memset((dst),(c),(sz))
183 /*
184@@ -279,7 +282,7 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *n
185 ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, int index);
186 ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, int index);
187
188-const char *elf_section_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
189+const char *elf_section_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr); /* might return NULL if inputs are invalid */
190 ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
191 ELF_PTRVAL_CONST_VOID elf_section_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
192
193@@ -289,7 +292,7 @@ ELF_PTRVAL_CONST_VOID elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(el
194 ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *symbol);
195 ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, int index);
196
197-const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
198+const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note); /* may return NULL */
199 ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
200 uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
201 uint64_t elf_note_numeric_array(struct elf_binary *, ELF_HANDLE_DECL(elf_note),
202--
2031.7.2.5
204
This page took 0.359732 seconds and 4 git commands to generate.