Переглянути джерело

[settings] Avoid memory leak when unregistering autovivified settings blocks

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 роки тому
джерело
коміт
071b4000d9
1 змінених файлів з 27 додано та 3 видалено
  1. 27
    3
      src/core/settings.c

+ 27
- 3
src/core/settings.c Переглянути файл

@@ -230,6 +230,27 @@ struct generic_settings generic_settings_root = {
230 230
 /** Root settings block */
231 231
 #define settings_root generic_settings_root.settings
232 232
 
233
+/** Autovivified settings block */
234
+struct autovivified_settings {
235
+	/** Reference count */
236
+	struct refcnt refcnt;
237
+	/** Generic settings block */
238
+	struct generic_settings generic;
239
+};
240
+
241
+/**
242
+ * Free autovivified settings block
243
+ *
244
+ * @v refcnt		Reference count
245
+ */
246
+static void autovivified_settings_free ( struct refcnt *refcnt ) {
247
+	struct autovivified_settings *autovivified =
248
+		container_of ( refcnt, struct autovivified_settings, refcnt );
249
+
250
+	generic_settings_clear ( &autovivified->generic.settings );
251
+	free ( autovivified );
252
+}
253
+
233 254
 /**
234 255
  * Find child named settings block
235 256
  *
@@ -264,7 +285,7 @@ static struct settings * find_child_settings ( struct settings *parent,
264 285
 static struct settings * autovivify_child_settings ( struct settings *parent,
265 286
 						     const char *name ) {
266 287
 	struct {
267
-		struct generic_settings generic;
288
+		struct autovivified_settings autovivified;
268 289
 		char name[ strlen ( name ) + 1 /* NUL */ ];
269 290
 	} *new_child;
270 291
 	struct settings *settings;
@@ -281,8 +302,11 @@ static struct settings * autovivify_child_settings ( struct settings *parent,
281 302
 		return NULL;
282 303
 	}
283 304
 	memcpy ( new_child->name, name, sizeof ( new_child->name ) );
284
-	generic_settings_init ( &new_child->generic, NULL );
285
-	settings = &new_child->generic.settings;
305
+	ref_init ( &new_child->autovivified.refcnt,
306
+		   autovivified_settings_free );
307
+	generic_settings_init ( &new_child->autovivified.generic,
308
+				&new_child->autovivified.refcnt );
309
+	settings = &new_child->autovivified.generic.settings;
286 310
 	register_settings ( settings, parent, new_child->name );
287 311
 	return settings;
288 312
 }

Завантаження…
Відмінити
Зберегти