From: Simon Glass <sjg@chromium.org> The extlinux and PXE drivers allocate a pxe_context in priv but never free it on device removal, leaking the bootdir string and any parsed menu. Add extlinux_bootmeth_remove() which frees the context, shared by both drivers. Move the VBE driver to use a pxe_context embedded in its own abrec_priv, since extlinux_plat no longer contains it. Signed-off-by: Simon Glass <sjg@chromium.org> --- boot/bootmeth_extlinux.c | 12 ++++++++++++ boot/bootmeth_pxe.c | 1 + boot/vbe_abrec.h | 4 ++++ boot/vbe_abrec_os.c | 8 ++++---- include/extlinux.h | 10 ++++++++++ 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/boot/bootmeth_extlinux.c b/boot/bootmeth_extlinux.c index ad2f32ca8a5..ca9120c3f99 100644 --- a/boot/bootmeth_extlinux.c +++ b/boot/bootmeth_extlinux.c @@ -233,6 +233,17 @@ static int extlinux_local_read_all(struct udevice *dev, struct bootflow *bflow) } #endif +int extlinux_bootmeth_remove(struct udevice *dev) +{ + struct extlinux_priv *priv = dev_get_priv(dev); + + if (priv->ctx.cfg) + pxe_menu_uninit(priv->ctx.cfg); + pxe_destroy_ctx(&priv->ctx); + + return 0; +} + static int extlinux_bootmeth_bind(struct udevice *dev) { struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev); @@ -267,6 +278,7 @@ U_BOOT_DRIVER(bootmeth_1extlinux) = { .of_match = extlinux_bootmeth_ids, .ops = &extlinux_bootmeth_ops, .bind = extlinux_bootmeth_bind, + .remove = extlinux_bootmeth_remove, .plat_auto = sizeof(struct extlinux_plat), .priv_auto = sizeof(struct extlinux_priv), }; diff --git a/boot/bootmeth_pxe.c b/boot/bootmeth_pxe.c index 55e7f60c5cd..772acc9107d 100644 --- a/boot/bootmeth_pxe.c +++ b/boot/bootmeth_pxe.c @@ -193,6 +193,7 @@ U_BOOT_DRIVER(bootmeth_zpxe) = { .of_match = extlinux_bootmeth_pxe_ids, .ops = &extlinux_bootmeth_pxe_ops, .bind = extlinux_bootmeth_pxe_bind, + .remove = extlinux_bootmeth_remove, .plat_auto = sizeof(struct extlinux_plat), .priv_auto = sizeof(struct extlinux_priv), }; diff --git a/boot/vbe_abrec.h b/boot/vbe_abrec.h index 590ad3cfacb..005e64af25f 100644 --- a/boot/vbe_abrec.h +++ b/boot/vbe_abrec.h @@ -9,6 +9,8 @@ #ifndef __VBE_ABREC_H #define __VBE_ABREC_H +#include <pxe_utils.h> + #include <vbe.h> #include <dm/ofnode_decl.h> @@ -34,6 +36,7 @@ struct udevice; * @version_size: Size of the version info * @storage: Storage device to use, in the form <uclass><devnum>, e.g. "mmc1" * @oem_devicetree: true if we should read an OEM devicetree + * @ctx: PXE context for extlinux boot/read_all */ struct abrec_priv { u32 area_start; @@ -45,6 +48,7 @@ struct abrec_priv { u32 version_size; const char *storage; bool oem_devicetree; + struct pxe_context ctx; }; /** struct abrec_state - state information read from media diff --git a/boot/vbe_abrec_os.c b/boot/vbe_abrec_os.c index 7d5c9bc9dcb..9d0136b059b 100644 --- a/boot/vbe_abrec_os.c +++ b/boot/vbe_abrec_os.c @@ -204,7 +204,7 @@ err_buf: static int vbe_abrec_boot(struct udevice *dev, struct bootflow *bflow) { - struct extlinux_plat *plat = dev_get_plat(dev); + struct abrec_priv *priv = dev_get_priv(dev); const struct bootflow_img *img; int ret; @@ -231,16 +231,16 @@ static int vbe_abrec_boot(struct udevice *dev, struct bootflow *bflow) printf("Loading OS FIT%s\n", img ? " keeping existing FDT" : ""); - return extlinux_boot(dev, bflow, &plat->ctx, vbe_abrec_getfile, true, + return extlinux_boot(dev, bflow, &priv->ctx, vbe_abrec_getfile, true, bflow->fname, img); } #if CONFIG_IS_ENABLED(BOOTSTD_FULL) static int vbe_abrec_read_all(struct udevice *dev, struct bootflow *bflow) { - struct extlinux_plat *plat = dev_get_plat(dev); + struct abrec_priv *priv = dev_get_priv(dev); - return extlinux_read_all(dev, bflow, &plat->ctx, vbe_abrec_getfile, + return extlinux_read_all(dev, bflow, &priv->ctx, vbe_abrec_getfile, true, bflow->fname); } #endif diff --git a/include/extlinux.h b/include/extlinux.h index 66500f4c8cf..8630a8e3dc7 100644 --- a/include/extlinux.h +++ b/include/extlinux.h @@ -42,6 +42,16 @@ struct extlinux_priv { struct pxe_context ctx; }; +/** + * extlinux_bootmeth_remove() - Remove function for extlinux-based bootmeths + * + * Frees the PXE context. Shared by extlinux and PXE drivers. + * + * @dev: Bootmethod device + * Return: 0 if OK + */ +int extlinux_bootmeth_remove(struct udevice *dev); + /** * extlinux_set_property() - set an extlinux property * -- 2.43.0