| From 13530c491f3eb446e3dae42c187857a94062467b Mon Sep 17 00:00:00 2001 |
| From: Arvind Sankar <nivedita@alum.mit.edu> |
| Date: Fri, 6 Dec 2019 16:55:40 +0000 |
| Subject: [PATCH] efi/gop: Fix memory leak in __gop_query32/64() |
| |
| commit ff397be685e410a59c34b21ce0c55d4daa466bb7 upstream. |
| |
| efi_graphics_output_protocol::query_mode() returns info in |
| callee-allocated memory which must be freed by the caller, which |
| we aren't doing. |
| |
| We don't actually need to call query_mode() in order to obtain the |
| info for the current graphics mode, which is already there in |
| gop->mode->info, so just access it directly in the setup_gop32/64() |
| functions. |
| |
| Also nothing uses the size of the info structure, so don't update the |
| passed-in size (which is the size of the gop_handle table in bytes) |
| unnecessarily. |
| |
| Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu> |
| Signed-off-by: Ard Biesheuvel <ardb@kernel.org> |
| Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> |
| Cc: Bhupesh Sharma <bhsharma@redhat.com> |
| Cc: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com> |
| Cc: linux-efi@vger.kernel.org |
| Link: https://lkml.kernel.org/r/20191206165542.31469-5-ardb@kernel.org |
| Signed-off-by: Ingo Molnar <mingo@kernel.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/firmware/efi/libstub/gop.c b/drivers/firmware/efi/libstub/gop.c |
| index 69b2b019a1d0..b7bf1e993b8b 100644 |
| --- a/drivers/firmware/efi/libstub/gop.c |
| +++ b/drivers/firmware/efi/libstub/gop.c |
| @@ -84,30 +84,6 @@ setup_pixel_info(struct screen_info *si, u32 pixels_per_scan_line, |
| } |
| |
| static efi_status_t |
| -__gop_query32(efi_system_table_t *sys_table_arg, |
| - struct efi_graphics_output_protocol_32 *gop32, |
| - struct efi_graphics_output_mode_info **info, |
| - unsigned long *size, u64 *fb_base) |
| -{ |
| - struct efi_graphics_output_protocol_mode_32 *mode; |
| - efi_graphics_output_protocol_query_mode query_mode; |
| - efi_status_t status; |
| - unsigned long m; |
| - |
| - m = gop32->mode; |
| - mode = (struct efi_graphics_output_protocol_mode_32 *)m; |
| - query_mode = (void *)(unsigned long)gop32->query_mode; |
| - |
| - status = __efi_call_early(query_mode, (void *)gop32, mode->mode, size, |
| - info); |
| - if (status != EFI_SUCCESS) |
| - return status; |
| - |
| - *fb_base = mode->frame_buffer_base; |
| - return status; |
| -} |
| - |
| -static efi_status_t |
| setup_gop32(efi_system_table_t *sys_table_arg, struct screen_info *si, |
| efi_guid_t *proto, unsigned long size, void **gop_handle) |
| { |
| @@ -128,6 +104,7 @@ setup_gop32(efi_system_table_t *sys_table_arg, struct screen_info *si, |
| |
| nr_gops = size / sizeof(u32); |
| for (i = 0; i < nr_gops; i++) { |
| + struct efi_graphics_output_protocol_mode_32 *mode; |
| struct efi_graphics_output_mode_info *info = NULL; |
| efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID; |
| bool conout_found = false; |
| @@ -145,9 +122,11 @@ setup_gop32(efi_system_table_t *sys_table_arg, struct screen_info *si, |
| if (status == EFI_SUCCESS) |
| conout_found = true; |
| |
| - status = __gop_query32(sys_table_arg, gop32, &info, &size, |
| - ¤t_fb_base); |
| - if (status == EFI_SUCCESS && (!first_gop || conout_found) && |
| + mode = (void *)(unsigned long)gop32->mode; |
| + info = (void *)(unsigned long)mode->info; |
| + current_fb_base = mode->frame_buffer_base; |
| + |
| + if ((!first_gop || conout_found) && |
| info->pixel_format != PIXEL_BLT_ONLY) { |
| /* |
| * Systems that use the UEFI Console Splitter may |
| @@ -202,30 +181,6 @@ setup_gop32(efi_system_table_t *sys_table_arg, struct screen_info *si, |
| } |
| |
| static efi_status_t |
| -__gop_query64(efi_system_table_t *sys_table_arg, |
| - struct efi_graphics_output_protocol_64 *gop64, |
| - struct efi_graphics_output_mode_info **info, |
| - unsigned long *size, u64 *fb_base) |
| -{ |
| - struct efi_graphics_output_protocol_mode_64 *mode; |
| - efi_graphics_output_protocol_query_mode query_mode; |
| - efi_status_t status; |
| - unsigned long m; |
| - |
| - m = gop64->mode; |
| - mode = (struct efi_graphics_output_protocol_mode_64 *)m; |
| - query_mode = (void *)(unsigned long)gop64->query_mode; |
| - |
| - status = __efi_call_early(query_mode, (void *)gop64, mode->mode, size, |
| - info); |
| - if (status != EFI_SUCCESS) |
| - return status; |
| - |
| - *fb_base = mode->frame_buffer_base; |
| - return status; |
| -} |
| - |
| -static efi_status_t |
| setup_gop64(efi_system_table_t *sys_table_arg, struct screen_info *si, |
| efi_guid_t *proto, unsigned long size, void **gop_handle) |
| { |
| @@ -246,6 +201,7 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct screen_info *si, |
| |
| nr_gops = size / sizeof(u64); |
| for (i = 0; i < nr_gops; i++) { |
| + struct efi_graphics_output_protocol_mode_64 *mode; |
| struct efi_graphics_output_mode_info *info = NULL; |
| efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID; |
| bool conout_found = false; |
| @@ -263,9 +219,11 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct screen_info *si, |
| if (status == EFI_SUCCESS) |
| conout_found = true; |
| |
| - status = __gop_query64(sys_table_arg, gop64, &info, &size, |
| - ¤t_fb_base); |
| - if (status == EFI_SUCCESS && (!first_gop || conout_found) && |
| + mode = (void *)(unsigned long)gop64->mode; |
| + info = (void *)(unsigned long)mode->info; |
| + current_fb_base = mode->frame_buffer_base; |
| + |
| + if ((!first_gop || conout_found) && |
| info->pixel_format != PIXEL_BLT_ONLY) { |
| /* |
| * Systems that use the UEFI Console Splitter may |
| -- |
| 2.7.4 |
| |