Codebase list hdf5 / bc0473d
New patch HDFFV-8917.patch from upstream changeset r25681 to fix resource exhaustion bug. Gilles Filippini 9 years ago
3 changed file(s) with 309 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 hdf5 (1.8.13+docs-15) unstable; urgency=medium
1
2 * New patch HDFFV-8917.patch from upstream to fix a resource
3 exhaustion bug (closes: #765511).
4
5 -- Gilles Filippini <pini@debian.org> Fri, 17 Oct 2014 07:51:24 +0200
6
07 hdf5 (1.8.13+docs-14) unstable; urgency=medium
18
29 * Use legacy library names in pkg-config files, to be consistent with
0 Description: Merge upstream fix for issue HDFFV-8917
1 Changeset from upstream SVN r25681 (branches/hdf5_1_8).
2 Index: hdf5/src/H5T.c
3 ===================================================================
4 --- hdf5.orig/src/H5T.c
5 +++ hdf5/src/H5T.c
6 @@ -529,7 +529,7 @@ H5FL_DEFINE_STATIC(H5T_path_t);
7 /* Datatype ID class */
8 static const H5I_class_t H5I_DATATYPE_CLS[1] = {{
9 H5I_DATATYPE, /* ID class value */
10 - 0, /* Class flags */
11 + H5I_CLASS_REUSE_IDS, /* Class flags */
12 8, /* # of reserved IDs for class */
13 (H5I_free_t)H5T_close /* Callback routine for closing objects of this class */
14 }};
15 Index: hdf5/src/H5E.c
16 ===================================================================
17 --- hdf5.orig/src/H5E.c
18 +++ hdf5/src/H5E.c
19 @@ -122,7 +122,7 @@ H5FL_DEFINE_STATIC(H5E_msg_t);
20 /* Error class ID class */
21 static const H5I_class_t H5I_ERRCLS_CLS[1] = {{
22 H5I_ERROR_CLASS, /* ID class value */
23 - 0, /* Class flags */
24 + H5I_CLASS_REUSE_IDS, /* Class flags */
25 0, /* # of reserved IDs for class */
26 (H5I_free_t)H5E_unregister_class /* Callback routine for closing objects of this class */
27 }};
28 @@ -130,7 +130,7 @@ static const H5I_class_t H5I_ERRCLS_CLS[
29 /* Error message ID class */
30 static const H5I_class_t H5I_ERRMSG_CLS[1] = {{
31 H5I_ERROR_MSG, /* ID class value */
32 - 0, /* Class flags */
33 + H5I_CLASS_REUSE_IDS, /* Class flags */
34 0, /* # of reserved IDs for class */
35 (H5I_free_t)H5E_close_msg /* Callback routine for closing objects of this class */
36 }};
37 @@ -138,7 +138,7 @@ static const H5I_class_t H5I_ERRMSG_CLS[
38 /* Error stack ID class */
39 static const H5I_class_t H5I_ERRSTK_CLS[1] = {{
40 H5I_ERROR_STACK, /* ID class value */
41 - 0, /* Class flags */
42 + H5I_CLASS_REUSE_IDS, /* Class flags */
43 0, /* # of reserved IDs for class */
44 (H5I_free_t)H5E_close_stack /* Callback routine for closing objects of this class */
45 }};
46 Index: hdf5/src/H5I.c
47 ===================================================================
48 --- hdf5.orig/src/H5I.c
49 +++ hdf5/src/H5I.c
50 @@ -814,7 +814,7 @@ H5I__wrapped_cb(void *_item, void UNUSED
51 HDassert(udata);
52
53 /* Break out if we see a free ID */
54 - if(udata->nextid != item->id) {
55 + if(udata->nextid != (ID_MASK & item->id)) {
56 /* Sanity check */
57 HDassert(item->id > udata->nextid);
58
59 @@ -874,6 +874,40 @@ H5I_register(H5I_type_t type, const void
60 /* If no available ID structure, then create a new id for use, and
61 * allocate a new struct to house it. */
62 else {
63 + /*
64 + * This next section of code checks for the 'nextid' getting too large and
65 + * wrapping around, thus necessitating checking for duplicate IDs being
66 + * handed out.
67 + */
68 + if(type_ptr->nextid > (hid_t)ID_MASK)
69 + type_ptr->wrapped = TRUE;
70 +
71 + /*
72 + * If we've wrapped around then we need to check for duplicate id's being
73 + * handed out.
74 + */
75 + if(type_ptr->wrapped) {
76 + H5I_wrap_ud_t udata; /* User data for iteration */
77 + herr_t iter_status; /* Iteration status */
78 +
79 + /* Set up user data for iteration */
80 + udata.nextid = (hid_t)type_ptr->cls->reserved;
81 +
82 + /* Iterate over all the ID nodes, looking for a gap in the ID sequence */
83 + if((iter_status = H5SL_iterate(type_ptr->ids, H5I__wrapped_cb, &udata)) < 0)
84 + HGOTO_ERROR(H5E_ATOM, H5E_BADITER, FAIL, "ID iteration failed")
85 +
86 + /* If we didn't break out of the iteration and we're at the max. ID, we've used all the IDs */
87 + if(0 == iter_status && udata.nextid >= ID_MASK)
88 + HGOTO_ERROR(H5E_ATOM, H5E_NOIDS, FAIL, "no IDs available in type")
89 +
90 + /* Sanity check */
91 + HDassert(udata.nextid < ID_MASK);
92 +
93 + /* Retain the next ID for the class */
94 + type_ptr->nextid = udata.nextid;
95 + } /* end if */
96 +
97 /* Allocate new ID struct */
98 if(NULL == (id_ptr = H5FL_MALLOC(H5I_id_info_t)))
99 HGOTO_ERROR(H5E_ATOM, H5E_NOSPACE, FAIL, "memory allocation failed")
100 @@ -895,40 +929,6 @@ H5I_register(H5I_type_t type, const void
101 HGOTO_ERROR(H5E_ATOM, H5E_CANTINSERT, FAIL, "can't insert ID node into skip list")
102 type_ptr->id_count++;
103
104 - /*
105 - * This next section of code checks for the 'nextid' getting too large and
106 - * wrapping around, thus necessitating checking for duplicate IDs being
107 - * handed out.
108 - */
109 - if(type_ptr->nextid > (hid_t)ID_MASK)
110 - type_ptr->wrapped = TRUE;
111 -
112 - /*
113 - * If we've wrapped around then we need to check for duplicate id's being
114 - * handed out.
115 - */
116 - if(type_ptr->wrapped) {
117 - H5I_wrap_ud_t udata; /* User data for iteration */
118 - herr_t iter_status; /* Iteration status */
119 -
120 - /* Set up user data for iteration */
121 - udata.nextid = (hid_t)type_ptr->cls->reserved;
122 -
123 - /* Iterate over all the ID nodes, looking for a gap in the ID sequence */
124 - if((iter_status = H5SL_iterate(type_ptr->ids, H5I__wrapped_cb, &udata)) < 0)
125 - HGOTO_ERROR(H5E_ATOM, H5E_BADITER, FAIL, "ID iteration failed")
126 -
127 - /* If we didn't break out of the iteration and we're at the max. ID, we've used all the IDs */
128 - if(0 == iter_status && udata.nextid >= ID_MASK)
129 - HGOTO_ERROR(H5E_ATOM, H5E_NOIDS, FAIL, "no IDs available in type")
130 -
131 - /* Sanity check */
132 - HDassert(udata.nextid < ID_MASK);
133 -
134 - /* Retain the next ID for the class */
135 - type_ptr->nextid = udata.nextid;
136 - } /* end if */
137 -
138 /* Set return value */
139 ret_value = id_ptr->id;
140
141 @@ -1249,13 +1249,24 @@ H5I__remove_common(H5I_id_type_t *type_p
142 /* (Casting away const OK -QAK) */
143 ret_value = (void *)curr_id->obj_ptr;
144
145 - /* If there's room, and we can save IDs of this type, then
146 - save the struct (and its ID) for future re-use */
147 - if((type_ptr->cls->flags & H5I_CLASS_REUSE_IDS)
148 - && (type_ptr->avail_count < MAX_FREE_ID_STRUCTS)) {
149 - if(H5SL_insert(type_ptr->avail_ids, curr_id, &curr_id->id) < 0)
150 - HGOTO_ERROR(H5E_ATOM, H5E_CANTINSERT, NULL, "can't insert available ID node into skip list")
151 - type_ptr->avail_count++;
152 + /* See if we can reuse IDs of this type */
153 + if(type_ptr->cls->flags & H5I_CLASS_REUSE_IDS) {
154 + /* See if we can decrement the next ID for the ID class */
155 + if(type_ptr->nextid == (ID_MASK & (curr_id->id + 1))) {
156 + type_ptr->nextid--;
157 + curr_id = H5FL_FREE(H5I_id_info_t, curr_id);
158 + } /* end if */
159 + else {
160 + /* Store the ID on the available ID list, for later */
161 + if((type_ptr->avail_count < MAX_FREE_ID_STRUCTS)
162 + && (type_ptr->id_count > 1)) {
163 + if(H5SL_insert(type_ptr->avail_ids, curr_id, &curr_id->id) < 0)
164 + HGOTO_ERROR(H5E_ATOM, H5E_CANTINSERT, NULL, "can't insert available ID node into skip list")
165 + type_ptr->avail_count++;
166 + }
167 + else
168 + curr_id = H5FL_FREE(H5I_id_info_t, curr_id);
169 + } /* end else */
170 } /* end if */
171 /* Otherwise, just toss it. */
172 else
173 Index: hdf5/src/H5Pint.c
174 ===================================================================
175 --- hdf5.orig/src/H5Pint.c
176 +++ hdf5/src/H5Pint.c
177 @@ -276,7 +276,7 @@ static const H5I_class_t H5I_GENPROPCLS_
178 /* Generic Property List ID class */
179 static const H5I_class_t H5I_GENPROPLST_CLS[1] = {{
180 H5I_GENPROP_LST, /* ID class value */
181 - 0, /* Class flags */
182 + H5I_CLASS_REUSE_IDS, /* Class flags */
183 0, /* # of reserved IDs for class */
184 (H5I_free_t)H5P_close /* Callback routine for closing objects of this class */
185 }};
186 Index: hdf5/test/tid.c
187 ===================================================================
188 --- hdf5.orig/test/tid.c
189 +++ hdf5/test/tid.c
190 @@ -533,6 +533,103 @@ out:
191 return -1;
192 }
193
194 +/* 'Fake' free routine for ID wrapping test */
195 +static herr_t fake_free(void *obj)
196 +{
197 + /* Shut compilers up */
198 + obj = obj;
199 +
200 + return(0);
201 +}
202 +
203 + /* Test boundary cases with lots of IDs */
204 +
205 +/* Type IDs range from 0 to ID_MASK before wrapping around. The code will assign */
206 +/* IDs in sequential order until ID_MASK IDs have been given out, at which */
207 +/* point it will search for type IDs that were allocated but have since been */
208 +/* closed. */
209 +/* This test will allocate IDs up to ID_MASK, ensure that IDs wrap around */
210 +/* to low values successfully, ensure that an error is thrown when all possible */
211 +/* type IDs are taken, then ensure that deleting types frees up their IDs. */
212 +/* NOTE: this test depends on the implementation of IDs, so may break */
213 +/* if the implementation changes. */
214 +static int test_id_wrap(void)
215 +{
216 + H5I_type_t testType; /* ID class for testing */
217 + hid_t *id_array; /* Array of IDs allocated */
218 + hid_t test_id; /* Test ID */
219 + void *obj; /* Object pointer returned for ID */
220 + unsigned u; /* Local index variable */
221 + herr_t status; /* Status from routine */
222 +
223 + /* Allocate array for storing IDs */
224 + id_array = (hid_t *)HDmalloc((ID_MASK + 1) * sizeof(hid_t));
225 + CHECK(id_array, NULL, "HDmalloc");
226 +
227 + /* Register type for testing */
228 + testType = H5Iregister_type((size_t)8, 0, (H5I_free_t)fake_free);
229 + CHECK(testType, H5I_BADID, "H5Iregister_type");
230 + if(testType == H5I_BADID)
231 + goto out;
232 +
233 + /* Get IDs, up to the maximum possible */
234 + for(u = 0; u <= ID_MASK; u++) {
235 + id_array[u] = H5Iregister(testType, &id_array[u]);
236 + CHECK(id_array[u], FAIL, "H5Iregister");
237 + if(id_array[u] < 0)
238 + goto out;
239 + } /* end for */
240 +
241 + /* There should be no room at the inn for a new ID */
242 + H5E_BEGIN_TRY
243 + test_id = H5Iregister(testType, id_array);
244 + H5E_END_TRY
245 + VERIFY(test_id, H5I_BADID, "H5Iregister_type");
246 + if(test_id != H5I_BADID)
247 + goto out;
248 +
249 + /* Release the first ID in the array */
250 + obj = H5Iremove_verify(id_array[0], testType);
251 + CHECK(obj, NULL, "H5Iremove_verify");
252 + if(NULL == obj)
253 + goto out;
254 + VERIFY(obj, &id_array[0], "H5Iremove_verify");
255 + if(&id_array[0] != obj)
256 + goto out;
257 +
258 + /* Register another object, should be room now, but will wraparound */
259 + test_id = H5Iregister(testType, &id_array[0]);
260 + CHECK(test_id, FAIL, "H5Iregister");
261 + if(test_id < 0)
262 + goto out;
263 + VERIFY(test_id, id_array[0], "H5Iregister");
264 + if(id_array[0] != test_id)
265 + goto out;
266 +
267 + /* Release all IDs, unregister the ID class and free the array */
268 + for(u = 0; u <= ID_MASK; u++) {
269 + obj = H5Iremove_verify(id_array[u], testType);
270 + CHECK(obj, NULL, "H5Iremove_verify");
271 + if(NULL == obj)
272 + goto out;
273 + VERIFY(obj, &id_array[u], "H5Iremove_verify");
274 + if(&id_array[u] != obj)
275 + goto out;
276 + } /* end for */
277 +
278 + status = H5Idestroy_type(testType);
279 + CHECK(status, FAIL, "H5Idestroy_type");
280 + if(status < 0)
281 + goto out;
282 +
283 + HDfree(id_array);
284 +
285 + return(0);
286 +
287 +out:
288 + return(-1);
289 +}
290 +
291 void test_ids(void)
292 {
293 if (basic_id_test() < 0) TestErrPrintf("Basic ID test failed\n");
294 @@ -540,5 +637,5 @@ void test_ids(void)
295 if (test_is_valid() < 0) TestErrPrintf("H5Iis_valid test failed\n");
296 if (test_get_type() < 0) TestErrPrintf("H5Iget_type test failed\n");
297 if (test_id_type_list() < 0) TestErrPrintf("ID type list test failed\n");
298 -
299 + if (test_id_wrap() < 0) TestErrPrintf("ID wraparound test failed\n");
300 }
44 relax-version-check.patch
55 #skip_cxx_inclusion.diff
66 soname.diff
7 HDFFV-8917.patch