diff options
Diffstat (limited to 'meta/recipes-multimedia/libsndfile/files/0001-src-sd2.c-Fix-segfault-in-SD2-RSRC-parser.patch')
-rw-r--r-- | meta/recipes-multimedia/libsndfile/files/0001-src-sd2.c-Fix-segfault-in-SD2-RSRC-parser.patch | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/meta/recipes-multimedia/libsndfile/files/0001-src-sd2.c-Fix-segfault-in-SD2-RSRC-parser.patch b/meta/recipes-multimedia/libsndfile/files/0001-src-sd2.c-Fix-segfault-in-SD2-RSRC-parser.patch new file mode 100644 index 0000000000..cd48710fb7 --- /dev/null +++ b/meta/recipes-multimedia/libsndfile/files/0001-src-sd2.c-Fix-segfault-in-SD2-RSRC-parser.patch | |||
@@ -0,0 +1,211 @@ | |||
1 | From 9341e9c6e70cd3ad76c901c3cf052d4cb52fd827 Mon Sep 17 00:00:00 2001 | ||
2 | From: Erik de Castro Lopo <erikd@mega-nerd.com> | ||
3 | Date: Thu, 27 Jun 2013 18:04:03 +1000 | ||
4 | Subject: [PATCH] src/sd2.c : Fix segfault in SD2 RSRC parser. | ||
5 | |||
6 | (Upstream commit 9341e9c6e70cd3ad76c901c3cf052d4cb52fd827) | ||
7 | |||
8 | A specially crafted resource fork for an SD2 file can cause | ||
9 | the SD2 RSRC parser to read data from outside a dynamically | ||
10 | defined buffer. The data that is read is converted into a | ||
11 | short or int and used during further processing. | ||
12 | |||
13 | Since no write occurs, this is unlikely to be exploitable. | ||
14 | |||
15 | Bug reported by The Mayhem Team from Cylab, Carnegie Mellon | ||
16 | Univeristy. Paper is: | ||
17 | http://users.ece.cmu.edu/~arebert/papers/mayhem-oakland-12.pdf | ||
18 | |||
19 | Upstream-Status: Backport | ||
20 | |||
21 | Signed-off-by: Yue Tao <yue.tao@windriver.com> | ||
22 | --- | ||
23 | src/sd2.c | 93 ++++++++++++++++++++++++++++++++++++------------------------- | ||
24 | 1 file changed, 55 insertions(+), 38 deletions(-) | ||
25 | |||
26 | diff --git a/src/sd2.c b/src/sd2.c | ||
27 | index 35ce36b..6be150c 100644 | ||
28 | --- a/src/sd2.c | ||
29 | +++ b/src/sd2.c | ||
30 | @@ -1,5 +1,5 @@ | ||
31 | /* | ||
32 | -** Copyright (C) 2001-2011 Erik de Castro Lopo <erikd@mega-nerd.com> | ||
33 | +** Copyright (C) 2001-2013 Erik de Castro Lopo <erikd@mega-nerd.com> | ||
34 | ** Copyright (C) 2004 Paavo Jumppanen | ||
35 | ** | ||
36 | ** This program is free software; you can redistribute it and/or modify | ||
37 | @@ -371,44 +371,61 @@ sd2_write_rsrc_fork (SF_PRIVATE *psf, int UNUSED (calc_length)) | ||
38 | */ | ||
39 | |||
40 | static inline int | ||
41 | -read_char (const unsigned char * data, int offset) | ||
42 | -{ return data [offset] ; | ||
43 | -} /* read_char */ | ||
44 | +read_rsrc_char (const SD2_RSRC *prsrc, int offset) | ||
45 | +{ const unsigned char * data = prsrc->rsrc_data ; | ||
46 | + if (offset < 0 || offset >= prsrc->rsrc_len) | ||
47 | + return 0 ; | ||
48 | + return data [offset] ; | ||
49 | +} /* read_rsrc_char */ | ||
50 | |||
51 | static inline int | ||
52 | -read_short (const unsigned char * data, int offset) | ||
53 | -{ return (data [offset] << 8) + data [offset + 1] ; | ||
54 | -} /* read_short */ | ||
55 | +read_rsrc_short (const SD2_RSRC *prsrc, int offset) | ||
56 | +{ const unsigned char * data = prsrc->rsrc_data ; | ||
57 | + if (offset < 0 || offset + 1 >= prsrc->rsrc_len) | ||
58 | + return 0 ; | ||
59 | + return (data [offset] << 8) + data [offset + 1] ; | ||
60 | +} /* read_rsrc_short */ | ||
61 | |||
62 | static inline int | ||
63 | -read_int (const unsigned char * data, int offset) | ||
64 | -{ return (data [offset] << 24) + (data [offset + 1] << 16) + (data [offset + 2] << 8) + data [offset + 3] ; | ||
65 | -} /* read_int */ | ||
66 | +read_rsrc_int (const SD2_RSRC *prsrc, int offset) | ||
67 | +{ const unsigned char * data = prsrc->rsrc_data ; | ||
68 | + if (offset < 0 || offset + 3 >= prsrc->rsrc_len) | ||
69 | + return 0 ; | ||
70 | + return (data [offset] << 24) + (data [offset + 1] << 16) + (data [offset + 2] << 8) + data [offset + 3] ; | ||
71 | +} /* read_rsrc_int */ | ||
72 | |||
73 | static inline int | ||
74 | -read_marker (const unsigned char * data, int offset) | ||
75 | -{ | ||
76 | +read_rsrc_marker (const SD2_RSRC *prsrc, int offset) | ||
77 | +{ const unsigned char * data = prsrc->rsrc_data ; | ||
78 | + | ||
79 | + if (offset < 0 || offset + 3 >= prsrc->rsrc_len) | ||
80 | + return 0 ; | ||
81 | + | ||
82 | if (CPU_IS_BIG_ENDIAN) | ||
83 | return (data [offset] << 24) + (data [offset + 1] << 16) + (data [offset + 2] << 8) + data [offset + 3] ; | ||
84 | - else if (CPU_IS_LITTLE_ENDIAN) | ||
85 | + if (CPU_IS_LITTLE_ENDIAN) | ||
86 | return data [offset] + (data [offset + 1] << 8) + (data [offset + 2] << 16) + (data [offset + 3] << 24) ; | ||
87 | - else | ||
88 | - return 0x666 ; | ||
89 | -} /* read_marker */ | ||
90 | + | ||
91 | + return 0 ; | ||
92 | +} /* read_rsrc_marker */ | ||
93 | |||
94 | static void | ||
95 | -read_str (const unsigned char * data, int offset, char * buffer, int buffer_len) | ||
96 | -{ int k ; | ||
97 | +read_rsrc_str (const SD2_RSRC *prsrc, int offset, char * buffer, int buffer_len) | ||
98 | +{ const unsigned char * data = prsrc->rsrc_data ; | ||
99 | + int k ; | ||
100 | |||
101 | memset (buffer, 0, buffer_len) ; | ||
102 | |||
103 | + if (offset < 0 || offset + buffer_len >= prsrc->rsrc_len) | ||
104 | + return ; | ||
105 | + | ||
106 | for (k = 0 ; k < buffer_len - 1 ; k++) | ||
107 | { if (psf_isprint (data [offset + k]) == 0) | ||
108 | return ; | ||
109 | buffer [k] = data [offset + k] ; | ||
110 | } ; | ||
111 | return ; | ||
112 | -} /* read_str */ | ||
113 | +} /* read_rsrc_str */ | ||
114 | |||
115 | static int | ||
116 | sd2_parse_rsrc_fork (SF_PRIVATE *psf) | ||
117 | @@ -435,17 +452,17 @@ sd2_parse_rsrc_fork (SF_PRIVATE *psf) | ||
118 | /* Reset the header storage because we have changed to the rsrcdes. */ | ||
119 | psf->headindex = psf->headend = rsrc.rsrc_len ; | ||
120 | |||
121 | - rsrc.data_offset = read_int (rsrc.rsrc_data, 0) ; | ||
122 | - rsrc.map_offset = read_int (rsrc.rsrc_data, 4) ; | ||
123 | - rsrc.data_length = read_int (rsrc.rsrc_data, 8) ; | ||
124 | - rsrc.map_length = read_int (rsrc.rsrc_data, 12) ; | ||
125 | + rsrc.data_offset = read_rsrc_int (&rsrc, 0) ; | ||
126 | + rsrc.map_offset = read_rsrc_int (&rsrc, 4) ; | ||
127 | + rsrc.data_length = read_rsrc_int (&rsrc, 8) ; | ||
128 | + rsrc.map_length = read_rsrc_int (&rsrc, 12) ; | ||
129 | |||
130 | if (rsrc.data_offset == 0x51607 && rsrc.map_offset == 0x20000) | ||
131 | { psf_log_printf (psf, "Trying offset of 0x52 bytes.\n") ; | ||
132 | - rsrc.data_offset = read_int (rsrc.rsrc_data, 0x52 + 0) + 0x52 ; | ||
133 | - rsrc.map_offset = read_int (rsrc.rsrc_data, 0x52 + 4) + 0x52 ; | ||
134 | - rsrc.data_length = read_int (rsrc.rsrc_data, 0x52 + 8) ; | ||
135 | - rsrc.map_length = read_int (rsrc.rsrc_data, 0x52 + 12) ; | ||
136 | + rsrc.data_offset = read_rsrc_int (&rsrc, 0x52 + 0) + 0x52 ; | ||
137 | + rsrc.map_offset = read_rsrc_int (&rsrc, 0x52 + 4) + 0x52 ; | ||
138 | + rsrc.data_length = read_rsrc_int (&rsrc, 0x52 + 8) ; | ||
139 | + rsrc.map_length = read_rsrc_int (&rsrc, 0x52 + 12) ; | ||
140 | } ; | ||
141 | |||
142 | psf_log_printf (psf, " data offset : 0x%04X\n map offset : 0x%04X\n" | ||
143 | @@ -488,7 +505,7 @@ sd2_parse_rsrc_fork (SF_PRIVATE *psf) | ||
144 | goto parse_rsrc_fork_cleanup ; | ||
145 | } ; | ||
146 | |||
147 | - rsrc.string_offset = rsrc.map_offset + read_short (rsrc.rsrc_data, rsrc.map_offset + 26) ; | ||
148 | + rsrc.string_offset = rsrc.map_offset + read_rsrc_short (&rsrc, rsrc.map_offset + 26) ; | ||
149 | if (rsrc.string_offset > rsrc.rsrc_len) | ||
150 | { psf_log_printf (psf, "Bad string offset (%d).\n", rsrc.string_offset) ; | ||
151 | error = SFE_SD2_BAD_RSRC ; | ||
152 | @@ -497,7 +514,7 @@ sd2_parse_rsrc_fork (SF_PRIVATE *psf) | ||
153 | |||
154 | rsrc.type_offset = rsrc.map_offset + 30 ; | ||
155 | |||
156 | - rsrc.type_count = read_short (rsrc.rsrc_data, rsrc.map_offset + 28) + 1 ; | ||
157 | + rsrc.type_count = read_rsrc_short (&rsrc, rsrc.map_offset + 28) + 1 ; | ||
158 | if (rsrc.type_count < 1) | ||
159 | { psf_log_printf (psf, "Bad type count.\n") ; | ||
160 | error = SFE_SD2_BAD_RSRC ; | ||
161 | @@ -513,11 +530,11 @@ sd2_parse_rsrc_fork (SF_PRIVATE *psf) | ||
162 | |||
163 | rsrc.str_index = -1 ; | ||
164 | for (k = 0 ; k < rsrc.type_count ; k ++) | ||
165 | - { marker = read_marker (rsrc.rsrc_data, rsrc.type_offset + k * 8) ; | ||
166 | + { marker = read_rsrc_marker (&rsrc, rsrc.type_offset + k * 8) ; | ||
167 | |||
168 | if (marker == STR_MARKER) | ||
169 | { rsrc.str_index = k ; | ||
170 | - rsrc.str_count = read_short (rsrc.rsrc_data, rsrc.type_offset + k * 8 + 4) + 1 ; | ||
171 | + rsrc.str_count = read_rsrc_short (&rsrc, rsrc.type_offset + k * 8 + 4) + 1 ; | ||
172 | error = parse_str_rsrc (psf, &rsrc) ; | ||
173 | goto parse_rsrc_fork_cleanup ; | ||
174 | } ; | ||
175 | @@ -549,26 +566,26 @@ parse_str_rsrc (SF_PRIVATE *psf, SD2_RSRC * rsrc) | ||
176 | for (k = 0 ; data_offset + data_len < rsrc->rsrc_len ; k++) | ||
177 | { int slen ; | ||
178 | |||
179 | - slen = read_char (rsrc->rsrc_data, str_offset) ; | ||
180 | - read_str (rsrc->rsrc_data, str_offset + 1, name, SF_MIN (SIGNED_SIZEOF (name), slen + 1)) ; | ||
181 | + slen = read_rsrc_char (rsrc, str_offset) ; | ||
182 | + read_rsrc_str (rsrc, str_offset + 1, name, SF_MIN (SIGNED_SIZEOF (name), slen + 1)) ; | ||
183 | str_offset += slen + 1 ; | ||
184 | |||
185 | - rsrc_id = read_short (rsrc->rsrc_data, rsrc->item_offset + k * 12) ; | ||
186 | + rsrc_id = read_rsrc_short (rsrc, rsrc->item_offset + k * 12) ; | ||
187 | |||
188 | - data_offset = rsrc->data_offset + read_int (rsrc->rsrc_data, rsrc->item_offset + k * 12 + 4) ; | ||
189 | + data_offset = rsrc->data_offset + read_rsrc_int (rsrc, rsrc->item_offset + k * 12 + 4) ; | ||
190 | if (data_offset < 0 || data_offset > rsrc->rsrc_len) | ||
191 | { psf_log_printf (psf, "Exiting parser on data offset of %d.\n", data_offset) ; | ||
192 | break ; | ||
193 | } ; | ||
194 | |||
195 | - data_len = read_int (rsrc->rsrc_data, data_offset) ; | ||
196 | + data_len = read_rsrc_int (rsrc, data_offset) ; | ||
197 | if (data_len < 0 || data_len > rsrc->rsrc_len) | ||
198 | { psf_log_printf (psf, "Exiting parser on data length of %d.\n", data_len) ; | ||
199 | break ; | ||
200 | } ; | ||
201 | |||
202 | - slen = read_char (rsrc->rsrc_data, data_offset + 4) ; | ||
203 | - read_str (rsrc->rsrc_data, data_offset + 5, value, SF_MIN (SIGNED_SIZEOF (value), slen + 1)) ; | ||
204 | + slen = read_rsrc_char (rsrc, data_offset + 4) ; | ||
205 | + read_rsrc_str (rsrc, data_offset + 5, value, SF_MIN (SIGNED_SIZEOF (value), slen + 1)) ; | ||
206 | |||
207 | psf_log_printf (psf, " 0x%04x %4d %4d %3d '%s'\n", data_offset, rsrc_id, data_len, slen, value) ; | ||
208 | |||
209 | -- | ||
210 | 1.7.9.5 | ||
211 | |||