* Re: [BUG] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() [not found] ` <ZCLPaYGKHlFQGKYQ@kroah.com> @ 2023-03-28 11:59 ` Mirsad Todorovac 2023-03-28 12:08 ` Mirsad Todorovac 0 siblings, 1 reply; 24+ messages in thread From: Mirsad Todorovac @ 2023-03-28 11:59 UTC (permalink / raw) To: Greg Kroah-Hartman Cc: Rafael J. Wysocki, linux-kernel, Hans de Goede, Mark Gross, platform-driver-x86 On 3/28/23 13:28, Greg Kroah-Hartman wrote: > On Tue, Mar 28, 2023 at 01:13:33PM +0200, Mirsad Todorovac wrote: >> Hi all, >> >> Here is another kernel memory leak report, just as I thought we have done with >> them by the xhci patch by Mathias. >> >> The memory leaks were caught on an AlmaLinux 8.7 (CentOS) fork system, running >> on a Lenovo desktop box (see lshw.txt) and the newest Linux kernel 6.3-rc4 commit >> g3a93e40326c8 with Mathias' patch for a xhci systemd-devd triggered leak. >> >> See: <20230327095019.1017159-1-mathias.nyman@linux.intel.com> on LKML. >> >> This leak is also systemd-devd triggered, except for the memstick_check() leaks >> which I was unable to bisect due to the box not booting older kernels (work in >> progress). >> >> unreferenced object 0xffff88ad12392710 (size 96): >> comm "systemd-udevd", pid 735, jiffies 4294896759 (age 2257.568s) >> hex dump (first 32 bytes): >> 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 SerialPort1Addre >> 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 ss,3F8/IRQ4;[Opt >> backtrace: >> [<ffffffffae8fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >> [<ffffffffae902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >> [<ffffffffae8773c9>] __kmalloc_node_track_caller+0x59/0x180 >> [<ffffffffae866a1a>] kstrdup+0x3a/0x70 >> [<ffffffffc0d839aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >> [<ffffffffc0d83b64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >> [<ffffffffc0d842b1>] tlmi_probe+0x591/0xba0 [think_lmi] >> [<ffffffffc051dc53>] wmi_dev_probe+0x163/0x230 [wmi] > > Why aren't you looking at the wmi.c driver? That should be where the > issue is, not the driver core, right? > > thanks, > > greg k-h Hi, Mr. Greg, Thanks for the quick reply. I have added CC: for additional developers per drivers/platform/x86/wmi.c, however, this seems to me like hieroglyphs. There is nothing obvious, but I had not noticed it with v6.3-rc3? Maybe, there seems to be something off: 949 static int wmi_dev_probe(struct device *dev) 950 { 951 struct wmi_block *wblock = dev_to_wblock(dev); 952 struct wmi_driver *wdriver = drv_to_wdrv(dev->driver); 953 int ret = 0; 954 char *buf; 955 956 if (ACPI_FAILURE(wmi_method_enable(wblock, true))) 957 dev_warn(dev, "failed to enable device -- probing anyway\n"); 958 959 if (wdriver->probe) { 960 ret = wdriver->probe(dev_to_wdev(dev), 961 find_guid_context(wblock, wdriver)); 962 if (ret != 0) 963 goto probe_failure; 964 } 965 966 /* driver wants a character device made */ 967 if (wdriver->filter_callback) { 968 /* check that required buffer size declared by driver or MOF */ 969 if (!wblock->req_buf_size) { 970 dev_err(&wblock->dev.dev, 971 "Required buffer size not set\n"); 972 ret = -EINVAL; 973 goto probe_failure; 974 } 975 976 wblock->handler_data = kmalloc(wblock->req_buf_size, 977 GFP_KERNEL); 978 if (!wblock->handler_data) { 979 ret = -ENOMEM; 980 goto probe_failure; 981 } 982 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", wdriver->driver.name); 984 if (!buf) { 985 ret = -ENOMEM; 986 goto probe_string_failure; 987 } 988 wblock->char_dev.minor = MISC_DYNAMIC_MINOR; 989 wblock->char_dev.name = buf; 990 wblock->char_dev.fops = &wmi_fops; 991 wblock->char_dev.mode = 0444; 992 ret = misc_register(&wblock->char_dev); 993 if (ret) { 994 dev_warn(dev, "failed to register char dev: %d\n", ret); 995 ret = -ENOMEM; 996 goto probe_misc_failure; 997 } 998 } 999 1000 set_bit(WMI_PROBED, &wblock->flags); 1001 return 0; 1002 1003 probe_misc_failure: 1004 kfree(buf); 1005 probe_string_failure: 1006 kfree(wblock->handler_data); 1007 probe_failure: 1008 if (ACPI_FAILURE(wmi_method_enable(wblock, false))) 1009 dev_warn(dev, "failed to disable device\n"); char *buf is passed to kfree(buf) uninitialised if wdriver->filter_callback is not set. It seems like a logical error per se, but I don't believe this is the cause of the leak? Thank you again. Best regards, Mirsad -- Mirsad Goran Todorovac Sistem inženjer Grafički fakultet | Akademija likovnih umjetnosti Sveučilište u Zagrebu System engineer Faculty of Graphic Arts | Academy of Fine Arts University of Zagreb, Republic of Croatia "What’s this thing suddenly coming towards me very fast? Very very fast. ... I wonder if it will be friends with me?" ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-28 11:59 ` [BUG] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() Mirsad Todorovac @ 2023-03-28 12:08 ` Mirsad Todorovac 2023-03-28 12:17 ` Greg Kroah-Hartman 0 siblings, 1 reply; 24+ messages in thread From: Mirsad Todorovac @ 2023-03-28 12:08 UTC (permalink / raw) To: Greg Kroah-Hartman Cc: Rafael J. Wysocki, linux-kernel, Hans de Goede, Mark Gross, platform-driver-x86 On 3/28/23 13:59, Mirsad Todorovac wrote: > On 3/28/23 13:28, Greg Kroah-Hartman wrote: >> On Tue, Mar 28, 2023 at 01:13:33PM +0200, Mirsad Todorovac wrote: >>> Hi all, >>> >>> Here is another kernel memory leak report, just as I thought we have done with >>> them by the xhci patch by Mathias. >>> >>> The memory leaks were caught on an AlmaLinux 8.7 (CentOS) fork system, running >>> on a Lenovo desktop box (see lshw.txt) and the newest Linux kernel 6.3-rc4 commit >>> g3a93e40326c8 with Mathias' patch for a xhci systemd-devd triggered leak. >>> >>> See: <20230327095019.1017159-1-mathias.nyman@linux.intel.com> on LKML. >>> >>> This leak is also systemd-devd triggered, except for the memstick_check() leaks >>> which I was unable to bisect due to the box not booting older kernels (work in >>> progress). >>> >>> unreferenced object 0xffff88ad12392710 (size 96): >>> comm "systemd-udevd", pid 735, jiffies 4294896759 (age 2257.568s) >>> hex dump (first 32 bytes): >>> 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 SerialPort1Addre >>> 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 ss,3F8/IRQ4;[Opt >>> backtrace: >>> [<ffffffffae8fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>> [<ffffffffae902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>> [<ffffffffae8773c9>] __kmalloc_node_track_caller+0x59/0x180 >>> [<ffffffffae866a1a>] kstrdup+0x3a/0x70 >>> [<ffffffffc0d839aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >>> [<ffffffffc0d83b64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>> [<ffffffffc0d842b1>] tlmi_probe+0x591/0xba0 [think_lmi] >>> [<ffffffffc051dc53>] wmi_dev_probe+0x163/0x230 [wmi] >> >> Why aren't you looking at the wmi.c driver? That should be where the >> issue is, not the driver core, right? >> >> thanks, >> >> greg k-h > > Hi, Mr. Greg, > > Thanks for the quick reply. > > I have added CC: for additional developers per drivers/platform/x86/wmi.c, > however, this seems to me like hieroglyphs. There is nothing obvious, but > I had not noticed it with v6.3-rc3? > > Maybe, there seems to be something off: > > 949 static int wmi_dev_probe(struct device *dev) > 950 { > 951 struct wmi_block *wblock = dev_to_wblock(dev); > 952 struct wmi_driver *wdriver = drv_to_wdrv(dev->driver); > 953 int ret = 0; > 954 char *buf; > 955 > 956 if (ACPI_FAILURE(wmi_method_enable(wblock, true))) > 957 dev_warn(dev, "failed to enable device -- probing anyway\n"); > 958 > 959 if (wdriver->probe) { > 960 ret = wdriver->probe(dev_to_wdev(dev), > 961 find_guid_context(wblock, wdriver)); > 962 if (ret != 0) > 963 goto probe_failure; > 964 } > 965 > 966 /* driver wants a character device made */ > 967 if (wdriver->filter_callback) { > 968 /* check that required buffer size declared by driver or MOF */ > 969 if (!wblock->req_buf_size) { > 970 dev_err(&wblock->dev.dev, > 971 "Required buffer size not set\n"); > 972 ret = -EINVAL; > 973 goto probe_failure; > 974 } > 975 > 976 wblock->handler_data = kmalloc(wblock->req_buf_size, > 977 GFP_KERNEL); > 978 if (!wblock->handler_data) { > 979 ret = -ENOMEM; > 980 goto probe_failure; > 981 } > 982 > 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", wdriver->driver.name); > 984 if (!buf) { > 985 ret = -ENOMEM; > 986 goto probe_string_failure; > 987 } > 988 wblock->char_dev.minor = MISC_DYNAMIC_MINOR; > 989 wblock->char_dev.name = buf; > 990 wblock->char_dev.fops = &wmi_fops; > 991 wblock->char_dev.mode = 0444; > 992 ret = misc_register(&wblock->char_dev); > 993 if (ret) { > 994 dev_warn(dev, "failed to register char dev: %d\n", ret); > 995 ret = -ENOMEM; > 996 goto probe_misc_failure; > 997 } > 998 } > 999 > 1000 set_bit(WMI_PROBED, &wblock->flags); > 1001 return 0; > 1002 > 1003 probe_misc_failure: > 1004 kfree(buf); > 1005 probe_string_failure: > 1006 kfree(wblock->handler_data); > 1007 probe_failure: > 1008 if (ACPI_FAILURE(wmi_method_enable(wblock, false))) > 1009 dev_warn(dev, "failed to disable device\n"); > > > char *buf is passed to kfree(buf) uninitialised if wdriver->filter_callback > is not set. > > It seems like a logical error per se, but I don't believe this is the cause > of the leak? CORRECTION: I overlooked the "return 0" in line 1001. This is why I don't think things should be rushed, but analysed with clear and cold head. And with as many eyes as possible :) The driver stuff is my long-term research interest. To state the obvious, the printing and multimedia education and industry in general would benefit from the open-source drivers for many instruments that still work, but are obsoleted by the producer and require unsupported versions of the OS. Thank you again for reviewing the bug report, however, ATM I do not think I have what it takes to hunt down the memleak. :-/ Best regards, Mirsad -- Mirsad Goran Todorovac Sistem inženjer Grafički fakultet | Akademija likovnih umjetnosti Sveučilište u Zagrebu System engineer Faculty of Graphic Arts | Academy of Fine Arts University of Zagreb, Republic of Croatia "What’s this thing suddenly coming towards me very fast? Very very fast. ... I wonder if it will be friends with me?" ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-28 12:08 ` Mirsad Todorovac @ 2023-03-28 12:17 ` Greg Kroah-Hartman 2023-03-28 12:44 ` Mirsad Todorovac 0 siblings, 1 reply; 24+ messages in thread From: Greg Kroah-Hartman @ 2023-03-28 12:17 UTC (permalink / raw) To: Mirsad Todorovac Cc: Rafael J. Wysocki, linux-kernel, Hans de Goede, Mark Gross, platform-driver-x86 On Tue, Mar 28, 2023 at 02:08:06PM +0200, Mirsad Todorovac wrote: > On 3/28/23 13:59, Mirsad Todorovac wrote: > > > On 3/28/23 13:28, Greg Kroah-Hartman wrote: > > > On Tue, Mar 28, 2023 at 01:13:33PM +0200, Mirsad Todorovac wrote: > > > > Hi all, > > > > > > > > Here is another kernel memory leak report, just as I thought we have done with > > > > them by the xhci patch by Mathias. > > > > > > > > The memory leaks were caught on an AlmaLinux 8.7 (CentOS) fork system, running > > > > on a Lenovo desktop box (see lshw.txt) and the newest Linux kernel 6.3-rc4 commit > > > > g3a93e40326c8 with Mathias' patch for a xhci systemd-devd triggered leak. > > > > > > > > See: <20230327095019.1017159-1-mathias.nyman@linux.intel.com> on LKML. > > > > > > > > This leak is also systemd-devd triggered, except for the memstick_check() leaks > > > > which I was unable to bisect due to the box not booting older kernels (work in > > > > progress). > > > > > > > > unreferenced object 0xffff88ad12392710 (size 96): > > > > comm "systemd-udevd", pid 735, jiffies 4294896759 (age 2257.568s) > > > > hex dump (first 32 bytes): > > > > 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 SerialPort1Addre > > > > 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 ss,3F8/IRQ4;[Opt > > > > backtrace: > > > > [<ffffffffae8fb26c>] slab_post_alloc_hook+0x8c/0x3e0 > > > > [<ffffffffae902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 > > > > [<ffffffffae8773c9>] __kmalloc_node_track_caller+0x59/0x180 > > > > [<ffffffffae866a1a>] kstrdup+0x3a/0x70 > > > > [<ffffffffc0d839aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] > > > > [<ffffffffc0d83b64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] > > > > [<ffffffffc0d842b1>] tlmi_probe+0x591/0xba0 [think_lmi] > > > > [<ffffffffc051dc53>] wmi_dev_probe+0x163/0x230 [wmi] > > > > > > Why aren't you looking at the wmi.c driver? That should be where the > > > issue is, not the driver core, right? > > > > > > thanks, > > > > > > greg k-h > > > > Hi, Mr. Greg, > > > > Thanks for the quick reply. > > > > I have added CC: for additional developers per drivers/platform/x86/wmi.c, > > however, this seems to me like hieroglyphs. There is nothing obvious, but > > I had not noticed it with v6.3-rc3? > > > > Maybe, there seems to be something off: > > > > 949 static int wmi_dev_probe(struct device *dev) > > 950 { > > 951 struct wmi_block *wblock = dev_to_wblock(dev); > > 952 struct wmi_driver *wdriver = drv_to_wdrv(dev->driver); > > 953 int ret = 0; > > 954 char *buf; > > 955 > > 956 if (ACPI_FAILURE(wmi_method_enable(wblock, true))) > > 957 dev_warn(dev, "failed to enable device -- probing anyway\n"); > > 958 > > 959 if (wdriver->probe) { > > 960 ret = wdriver->probe(dev_to_wdev(dev), > > 961 find_guid_context(wblock, wdriver)); > > 962 if (ret != 0) > > 963 goto probe_failure; > > 964 } > > 965 > > 966 /* driver wants a character device made */ > > 967 if (wdriver->filter_callback) { > > 968 /* check that required buffer size declared by driver or MOF */ > > 969 if (!wblock->req_buf_size) { > > 970 dev_err(&wblock->dev.dev, > > 971 "Required buffer size not set\n"); > > 972 ret = -EINVAL; > > 973 goto probe_failure; > > 974 } > > 975 > > 976 wblock->handler_data = kmalloc(wblock->req_buf_size, > > 977 GFP_KERNEL); > > 978 if (!wblock->handler_data) { > > 979 ret = -ENOMEM; > > 980 goto probe_failure; > > 981 } > > 982 > > 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", wdriver->driver.name); > > 984 if (!buf) { > > 985 ret = -ENOMEM; > > 986 goto probe_string_failure; > > 987 } > > 988 wblock->char_dev.minor = MISC_DYNAMIC_MINOR; > > 989 wblock->char_dev.name = buf; > > 990 wblock->char_dev.fops = &wmi_fops; > > 991 wblock->char_dev.mode = 0444; > > 992 ret = misc_register(&wblock->char_dev); > > 993 if (ret) { > > 994 dev_warn(dev, "failed to register char dev: %d\n", ret); > > 995 ret = -ENOMEM; > > 996 goto probe_misc_failure; > > 997 } > > 998 } > > 999 > > 1000 set_bit(WMI_PROBED, &wblock->flags); > > 1001 return 0; > > 1002 > > 1003 probe_misc_failure: > > 1004 kfree(buf); > > 1005 probe_string_failure: > > 1006 kfree(wblock->handler_data); > > 1007 probe_failure: > > 1008 if (ACPI_FAILURE(wmi_method_enable(wblock, false))) > > 1009 dev_warn(dev, "failed to disable device\n"); > > > > > > char *buf is passed to kfree(buf) uninitialised if wdriver->filter_callback > > is not set. > > > > It seems like a logical error per se, but I don't believe this is the cause > > of the leak? > > CORRECTION: > > I overlooked the "return 0" in line 1001. Yeah, and the memory looks to be freed properly in the wmi_dev_remove() callback, right? > This is why I don't think things should be rushed, but analysed with clear and > cold head. And with as many eyes as possible :) > > The driver stuff is my long-term research interest. To state the obvious, > the printing and multimedia education and industry in general would benefit from > the open-source drivers for many instruments that still work, but are obsoleted > by the producer and require unsupported versions of the OS. > > Thank you again for reviewing the bug report, however, ATM I do not think I have > what it takes to hunt down the memleak. :-/ Do you have a reproducer that you can use to show the problem better? Or can you test kernel patches to verify the problem is fixed or not if we send you patches to test? thanks, greg k-h ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-28 12:17 ` Greg Kroah-Hartman @ 2023-03-28 12:44 ` Mirsad Todorovac 2023-03-28 16:53 ` Armin Wolf 0 siblings, 1 reply; 24+ messages in thread From: Mirsad Todorovac @ 2023-03-28 12:44 UTC (permalink / raw) To: Greg Kroah-Hartman Cc: Rafael J. Wysocki, linux-kernel, Hans de Goede, Mark Gross, platform-driver-x86 On 3/28/23 14:17, Greg Kroah-Hartman wrote: > On Tue, Mar 28, 2023 at 02:08:06PM +0200, Mirsad Todorovac wrote: >> On 3/28/23 13:59, Mirsad Todorovac wrote: >> >>> On 3/28/23 13:28, Greg Kroah-Hartman wrote: >>>> On Tue, Mar 28, 2023 at 01:13:33PM +0200, Mirsad Todorovac wrote: >>>>> Hi all, >>>>> >>>>> Here is another kernel memory leak report, just as I thought we have done with >>>>> them by the xhci patch by Mathias. >>>>> >>>>> The memory leaks were caught on an AlmaLinux 8.7 (CentOS) fork system, running >>>>> on a Lenovo desktop box (see lshw.txt) and the newest Linux kernel 6.3-rc4 commit >>>>> g3a93e40326c8 with Mathias' patch for a xhci systemd-devd triggered leak. >>>>> >>>>> See: <20230327095019.1017159-1-mathias.nyman@linux.intel.com> on LKML. >>>>> >>>>> This leak is also systemd-devd triggered, except for the memstick_check() leaks >>>>> which I was unable to bisect due to the box not booting older kernels (work in >>>>> progress). >>>>> >>>>> unreferenced object 0xffff88ad12392710 (size 96): >>>>> comm "systemd-udevd", pid 735, jiffies 4294896759 (age 2257.568s) >>>>> hex dump (first 32 bytes): >>>>> 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 SerialPort1Addre >>>>> 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 ss,3F8/IRQ4;[Opt >>>>> backtrace: >>>>> [<ffffffffae8fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>> [<ffffffffae902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>> [<ffffffffae8773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>> [<ffffffffae866a1a>] kstrdup+0x3a/0x70 >>>>> [<ffffffffc0d839aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >>>>> [<ffffffffc0d83b64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>>> [<ffffffffc0d842b1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>> [<ffffffffc051dc53>] wmi_dev_probe+0x163/0x230 [wmi] >>>> >>>> Why aren't you looking at the wmi.c driver? That should be where the >>>> issue is, not the driver core, right? >>>> >>>> thanks, >>>> >>>> greg k-h >>> >>> Hi, Mr. Greg, >>> >>> Thanks for the quick reply. >>> >>> I have added CC: for additional developers per drivers/platform/x86/wmi.c, >>> however, this seems to me like hieroglyphs. There is nothing obvious, but >>> I had not noticed it with v6.3-rc3? >>> >>> Maybe, there seems to be something off: >>> >>> 949 static int wmi_dev_probe(struct device *dev) >>> 950 { >>> 951 struct wmi_block *wblock = dev_to_wblock(dev); >>> 952 struct wmi_driver *wdriver = drv_to_wdrv(dev->driver); >>> 953 int ret = 0; >>> 954 char *buf; >>> 955 >>> 956 if (ACPI_FAILURE(wmi_method_enable(wblock, true))) >>> 957 dev_warn(dev, "failed to enable device -- probing anyway\n"); >>> 958 >>> 959 if (wdriver->probe) { >>> 960 ret = wdriver->probe(dev_to_wdev(dev), >>> 961 find_guid_context(wblock, wdriver)); >>> 962 if (ret != 0) >>> 963 goto probe_failure; >>> 964 } >>> 965 >>> 966 /* driver wants a character device made */ >>> 967 if (wdriver->filter_callback) { >>> 968 /* check that required buffer size declared by driver or MOF */ >>> 969 if (!wblock->req_buf_size) { >>> 970 dev_err(&wblock->dev.dev, >>> 971 "Required buffer size not set\n"); >>> 972 ret = -EINVAL; >>> 973 goto probe_failure; >>> 974 } >>> 975 >>> 976 wblock->handler_data = kmalloc(wblock->req_buf_size, >>> 977 GFP_KERNEL); >>> 978 if (!wblock->handler_data) { >>> 979 ret = -ENOMEM; >>> 980 goto probe_failure; >>> 981 } >>> 982 >>> 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", wdriver->driver.name); >>> 984 if (!buf) { >>> 985 ret = -ENOMEM; >>> 986 goto probe_string_failure; >>> 987 } >>> 988 wblock->char_dev.minor = MISC_DYNAMIC_MINOR; >>> 989 wblock->char_dev.name = buf; >>> 990 wblock->char_dev.fops = &wmi_fops; >>> 991 wblock->char_dev.mode = 0444; >>> 992 ret = misc_register(&wblock->char_dev); >>> 993 if (ret) { >>> 994 dev_warn(dev, "failed to register char dev: %d\n", ret); >>> 995 ret = -ENOMEM; >>> 996 goto probe_misc_failure; >>> 997 } >>> 998 } >>> 999 >>> 1000 set_bit(WMI_PROBED, &wblock->flags); >>> 1001 return 0; >>> 1002 >>> 1003 probe_misc_failure: >>> 1004 kfree(buf); >>> 1005 probe_string_failure: >>> 1006 kfree(wblock->handler_data); >>> 1007 probe_failure: >>> 1008 if (ACPI_FAILURE(wmi_method_enable(wblock, false))) >>> 1009 dev_warn(dev, "failed to disable device\n"); >>> >>> >>> char *buf is passed to kfree(buf) uninitialised if wdriver->filter_callback >>> is not set. >>> >>> It seems like a logical error per se, but I don't believe this is the cause >>> of the leak? >> >> CORRECTION: >> >> I overlooked the "return 0" in line 1001. > > Yeah, and the memory looks to be freed properly in the wmi_dev_remove() > callback, right? It would appear so. To verify that: Alloc: 976 wblock->handler_data = kmalloc(wblock->req_buf_size, GFP_KERNEL); <check> 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", wdriver->driver.name); <check> 989 wblock->char_dev.name = buf; In lines 1022-1023: 1022 kfree(wblock->char_dev.name); 1023 kfree(wblock->handler_data); >> This is why I don't think things should be rushed, but analysed with clear and >> cold head. And with as many eyes as possible :) >> >> The driver stuff is my long-term research interest. To state the obvious, >> the printing and multimedia education and industry in general would benefit from >> the open-source drivers for many instruments that still work, but are obsoleted >> by the producer and require unsupported versions of the OS. >> >> Thank you again for reviewing the bug report, however, ATM I do not think I have >> what it takes to hunt down the memleak. :-/ > > Do you have a reproducer that you can use to show the problem better? Unfortunately, the problem doesn't seem to appear during the run of a particular test, but immediately on startup of the OS. This makes it awkward to pinpoint the exact service that triggered memory leaks. But they would appear to have to do with the initialisation of the USB devices, wouldn't they? There seem to be strings: "USBPortAccess,Enabled;[Optional:" "USBBIOSSupport,Enabled;[Optional" "USBEnumerationDelay,Disabled;[Op" This seems to be happening during USB initialisation and before any services. But I might as well be wrong. > Or can you test kernel patches to verify the problem is fixed or not if > we send you patches to test? Certainly, Lord willing, I can test the patches in the same environment that mainfeted the bug (or memleak). Best regards, Mirsad -- Mirsad Goran Todorovac Sistem inženjer Grafički fakultet | Akademija likovnih umjetnosti Sveučilište u Zagrebu System engineer Faculty of Graphic Arts | Academy of Fine Arts University of Zagreb, Republic of Croatia "What’s this thing suddenly coming towards me very fast? Very very fast. ... I wonder if it will be friends with me?" ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-28 12:44 ` Mirsad Todorovac @ 2023-03-28 16:53 ` Armin Wolf 2023-03-28 19:06 ` Mirsad Goran Todorovac 0 siblings, 1 reply; 24+ messages in thread From: Armin Wolf @ 2023-03-28 16:53 UTC (permalink / raw) To: Mirsad Todorovac, Greg Kroah-Hartman Cc: Rafael J. Wysocki, linux-kernel, Hans de Goede, Mark Gross, platform-driver-x86 Am 28.03.23 um 14:44 schrieb Mirsad Todorovac: > On 3/28/23 14:17, Greg Kroah-Hartman wrote: >> On Tue, Mar 28, 2023 at 02:08:06PM +0200, Mirsad Todorovac wrote: >>> On 3/28/23 13:59, Mirsad Todorovac wrote: >>> >>>> On 3/28/23 13:28, Greg Kroah-Hartman wrote: >>>>> On Tue, Mar 28, 2023 at 01:13:33PM +0200, Mirsad Todorovac wrote: >>>>>> Hi all, >>>>>> >>>>>> Here is another kernel memory leak report, just as I thought we >>>>>> have done with >>>>>> them by the xhci patch by Mathias. >>>>>> >>>>>> The memory leaks were caught on an AlmaLinux 8.7 (CentOS) fork >>>>>> system, running >>>>>> on a Lenovo desktop box (see lshw.txt) and the newest Linux >>>>>> kernel 6.3-rc4 commit >>>>>> g3a93e40326c8 with Mathias' patch for a xhci systemd-devd >>>>>> triggered leak. >>>>>> >>>>>> See: >>>>>> <20230327095019.1017159-1-mathias.nyman@linux.intel.com> on LKML. >>>>>> >>>>>> This leak is also systemd-devd triggered, except for the >>>>>> memstick_check() leaks >>>>>> which I was unable to bisect due to the box not booting older >>>>>> kernels (work in >>>>>> progress). >>>>>> >>>>>> unreferenced object 0xffff88ad12392710 (size 96): >>>>>> comm "systemd-udevd", pid 735, jiffies 4294896759 (age >>>>>> 2257.568s) >>>>>> hex dump (first 32 bytes): >>>>>> 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 >>>>>> SerialPort1Addre >>>>>> 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 >>>>>> ss,3F8/IRQ4;[Opt >>>>>> backtrace: >>>>>> [<ffffffffae8fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>>> [<ffffffffae902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>>> [<ffffffffae8773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>>> [<ffffffffae866a1a>] kstrdup+0x3a/0x70 >>>>>> [<ffffffffc0d839aa>] >>>>>> tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >>>>>> [<ffffffffc0d83b64>] tlmi_setting.constprop.4+0x54/0x90 >>>>>> [think_lmi] >>>>>> [<ffffffffc0d842b1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>>> [<ffffffffc051dc53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>> Hi, this "SerialPort1Address" string looks like a BIOS setup option, and indeed think_lmi allows for changing BIOS setup options over sysfs. While looking at current_value_show() in think-lmi.c, i noticed that "item" holds a string which is allocated with kstrdup(), so it has to be freed using kfree(). This however does not happen if strbrk() fails, so maybe the memory leak is caused by this? Armin Wolf >>>>> Why aren't you looking at the wmi.c driver? That should be where the >>>>> issue is, not the driver core, right? >>>>> >>>>> thanks, >>>>> >>>>> greg k-h >>>> >>>> Hi, Mr. Greg, >>>> >>>> Thanks for the quick reply. >>>> >>>> I have added CC: for additional developers per >>>> drivers/platform/x86/wmi.c, >>>> however, this seems to me like hieroglyphs. There is nothing >>>> obvious, but >>>> I had not noticed it with v6.3-rc3? >>>> >>>> Maybe, there seems to be something off: >>>> >>>> 949 static int wmi_dev_probe(struct device *dev) >>>> 950 { >>>> 951 struct wmi_block *wblock = dev_to_wblock(dev); >>>> 952 struct wmi_driver *wdriver = >>>> drv_to_wdrv(dev->driver); >>>> 953 int ret = 0; >>>> 954 char *buf; >>>> 955 >>>> 956 if (ACPI_FAILURE(wmi_method_enable(wblock, true))) >>>> 957 dev_warn(dev, "failed to enable device -- >>>> probing anyway\n"); >>>> 958 >>>> 959 if (wdriver->probe) { >>>> 960 ret = wdriver->probe(dev_to_wdev(dev), >>>> 961 find_guid_context(wblock, wdriver)); >>>> 962 if (ret != 0) >>>> 963 goto probe_failure; >>>> 964 } >>>> 965 >>>> 966 /* driver wants a character device made */ >>>> 967 if (wdriver->filter_callback) { >>>> 968 /* check that required buffer size >>>> declared by driver or MOF */ >>>> 969 if (!wblock->req_buf_size) { >>>> 970 dev_err(&wblock->dev.dev, >>>> 971 "Required buffer size not >>>> set\n"); >>>> 972 ret = -EINVAL; >>>> 973 goto probe_failure; >>>> 974 } >>>> 975 >>>> 976 wblock->handler_data = >>>> kmalloc(wblock->req_buf_size, >>>> 977 GFP_KERNEL); >>>> 978 if (!wblock->handler_data) { >>>> 979 ret = -ENOMEM; >>>> 980 goto probe_failure; >>>> 981 } >>>> 982 >>>> 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", >>>> wdriver->driver.name); >>>> 984 if (!buf) { >>>> 985 ret = -ENOMEM; >>>> 986 goto probe_string_failure; >>>> 987 } >>>> 988 wblock->char_dev.minor = MISC_DYNAMIC_MINOR; >>>> 989 wblock->char_dev.name = buf; >>>> 990 wblock->char_dev.fops = &wmi_fops; >>>> 991 wblock->char_dev.mode = 0444; >>>> 992 ret = misc_register(&wblock->char_dev); >>>> 993 if (ret) { >>>> 994 dev_warn(dev, "failed to register >>>> char dev: %d\n", ret); >>>> 995 ret = -ENOMEM; >>>> 996 goto probe_misc_failure; >>>> 997 } >>>> 998 } >>>> 999 >>>> 1000 set_bit(WMI_PROBED, &wblock->flags); >>>> 1001 return 0; >>>> 1002 >>>> 1003 probe_misc_failure: >>>> 1004 kfree(buf); >>>> 1005 probe_string_failure: >>>> 1006 kfree(wblock->handler_data); >>>> 1007 probe_failure: >>>> 1008 if (ACPI_FAILURE(wmi_method_enable(wblock, false))) >>>> 1009 dev_warn(dev, "failed to disable device\n"); >>>> >>>> >>>> char *buf is passed to kfree(buf) uninitialised if >>>> wdriver->filter_callback >>>> is not set. >>>> >>>> It seems like a logical error per se, but I don't believe this is >>>> the cause >>>> of the leak? >>> >>> CORRECTION: >>> >>> I overlooked the "return 0" in line 1001. >> >> Yeah, and the memory looks to be freed properly in the wmi_dev_remove() >> callback, right? > > It would appear so. To verify that: > > Alloc: > 976 wblock->handler_data = kmalloc(wblock->req_buf_size, > GFP_KERNEL); > <check> > > 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", wdriver->driver.name); > <check> > 989 wblock->char_dev.name = buf; > > In lines 1022-1023: > > 1022 kfree(wblock->char_dev.name); > 1023 kfree(wblock->handler_data); > >>> This is why I don't think things should be rushed, but analysed with >>> clear and >>> cold head. And with as many eyes as possible :) >>> >>> The driver stuff is my long-term research interest. To state the >>> obvious, >>> the printing and multimedia education and industry in general would >>> benefit from >>> the open-source drivers for many instruments that still work, but >>> are obsoleted >>> by the producer and require unsupported versions of the OS. >>> >>> Thank you again for reviewing the bug report, however, ATM I do not >>> think I have >>> what it takes to hunt down the memleak. :-/ >> >> Do you have a reproducer that you can use to show the problem better? > > Unfortunately, the problem doesn't seem to appear during the run of a > particular > test, but immediately on startup of the OS. This makes it awkward to > pinpoint the > exact service that triggered memory leaks. But they would appear to > have to do > with the initialisation of the USB devices, wouldn't they? > > There seem to be strings: > > "USBPortAccess,Enabled;[Optional:" > "USBBIOSSupport,Enabled;[Optional" > "USBEnumerationDelay,Disabled;[Op" > > This seems to be happening during USB initialisation and before any > services. > But I might as well be wrong. > >> Or can you test kernel patches to verify the problem is fixed or not if >> we send you patches to test? > > Certainly, Lord willing, I can test the patches in the same > environment that > mainfeted the bug (or memleak). > > Best regards, > Mirsad > ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-28 16:53 ` Armin Wolf @ 2023-03-28 19:06 ` Mirsad Goran Todorovac 2023-03-28 19:55 ` Armin Wolf 0 siblings, 1 reply; 24+ messages in thread From: Mirsad Goran Todorovac @ 2023-03-28 19:06 UTC (permalink / raw) To: Armin Wolf, Greg Kroah-Hartman Cc: Rafael J. Wysocki, linux-kernel, Hans de Goede, Mark Gross, platform-driver-x86 On 3/28/2023 6:53 PM, Armin Wolf wrote: > Am 28.03.23 um 14:44 schrieb Mirsad Todorovac: > >> On 3/28/23 14:17, Greg Kroah-Hartman wrote: >>> On Tue, Mar 28, 2023 at 02:08:06PM +0200, Mirsad Todorovac wrote: >>>> On 3/28/23 13:59, Mirsad Todorovac wrote: >>>> >>>>> On 3/28/23 13:28, Greg Kroah-Hartman wrote: >>>>>> On Tue, Mar 28, 2023 at 01:13:33PM +0200, Mirsad Todorovac wrote: >>>>>>> Hi all, >>>>>>> >>>>>>> Here is another kernel memory leak report, just as I thought we have done with >>>>>>> them by the xhci patch by Mathias. >>>>>>> >>>>>>> The memory leaks were caught on an AlmaLinux 8.7 (CentOS) fork system, running >>>>>>> on a Lenovo desktop box (see lshw.txt) and the newest Linux kernel 6.3-rc4 commit >>>>>>> g3a93e40326c8 with Mathias' patch for a xhci systemd-devd triggered leak. >>>>>>> >>>>>>> See: <20230327095019.1017159-1-mathias.nyman@linux.intel.com> on LKML. >>>>>>> >>>>>>> This leak is also systemd-devd triggered, except for the memstick_check() leaks >>>>>>> which I was unable to bisect due to the box not booting older kernels (work in >>>>>>> progress). >>>>>>> >>>>>>> unreferenced object 0xffff88ad12392710 (size 96): >>>>>>> comm "systemd-udevd", pid 735, jiffies 4294896759 (age 2257.568s) >>>>>>> hex dump (first 32 bytes): >>>>>>> 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 SerialPort1Addre >>>>>>> 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 ss,3F8/IRQ4;[Opt >>>>>>> backtrace: >>>>>>> [<ffffffffae8fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>>>> [<ffffffffae902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>>>> [<ffffffffae8773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>>>> [<ffffffffae866a1a>] kstrdup+0x3a/0x70 >>>>>>> [<ffffffffc0d839aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >>>>>>> [<ffffffffc0d83b64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>>>>> [<ffffffffc0d842b1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>>>> [<ffffffffc051dc53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>>> > Hi, > > this "SerialPort1Address" string looks like a BIOS setup option, and indeed think_lmi allows for > changing BIOS setup options over sysfs. While looking at current_value_show() in think-lmi.c, i noticed > that "item" holds a string which is allocated with kstrdup(), so it has to be freed using kfree(). > This however does not happen if strbrk() fails, so maybe the memory leak is caused by this? > > Armin Wolf Hi Armin, I tried your suggestion, and though it is an obvious improvement and a leak fix, this was not the one we were searching for. I tested the following patch: diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index c816646eb661..1e77ecb0cba8 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a /* validate and split from `item,value` -> `value` */ value = strpbrk(item, ","); - if (!value || value == item || !strlen(value + 1)) + if (!value || value == item || !strlen(value + 1)) { + kfree(item); return -EINVAL; + } ret = sysfs_emit(buf, "%s\n", value + 1); kfree(item); (I would also object to the use of strlen() here, for it is inherently insecure against SEGFAULT in kernel space.) I still get: [root@pc-mtodorov marvin]# uname -rms Linux 6.3.0-rc4-armin-patch-00025-g3a93e40326c8-dirty x86_64 [root@pc-mtodorov marvin]# cat /sys/kernel/debug/kmemleak [edited] unreferenced object 0xffff8eb008ef9260 (size 96): comm "systemd-udevd", pid 771, jiffies 4294896499 (age 74.880s) hex dump (first 32 bytes): 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 SerialPort1Addre 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 ss,3F8/IRQ4;[Opt backtrace: [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 [<ffffffff9f197c62>] driver_attach+0x22/0x30 [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 [<ffffffff9f19a0a2>] driver_register+0x62/0x120 unreferenced object 0xffff8eb018ddbb40 (size 64): comm "systemd-udevd", pid 771, jiffies 4294896528 (age 74.780s) hex dump (first 32 bytes): 55 53 42 50 6f 72 74 41 63 63 65 73 73 2c 45 6e USBPortAccess,En 61 62 6c 65 64 3b 5b 4f 70 74 69 6f 6e 61 6c 3a abled;[Optional: backtrace: [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 [<ffffffff9f197c62>] driver_attach+0x22/0x30 [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 [<ffffffff9f19a0a2>] driver_register+0x62/0x120 unreferenced object 0xffff8eb006fe2b40 (size 64): comm "systemd-udevd", pid 771, jiffies 4294896542 (age 74.724s) hex dump (first 32 bytes): 55 53 42 42 49 4f 53 53 75 70 70 6f 72 74 2c 45 USBBIOSSupport,E 6e 61 62 6c 65 64 3b 5b 4f 70 74 69 6f 6e 61 6c nabled;[Optional backtrace: [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 [<ffffffff9f197c62>] driver_attach+0x22/0x30 [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 [<ffffffff9f19a0a2>] driver_register+0x62/0x120 There are currently 84 wmi_dev_probe leaks, sized mostly 64 bytes, and one 96 and two 192 bytes. I also cannot figure out the mechanism by which current_value_show() is called, when it is static? Any idea? Thanks. Best regards, Mirsad >>>>>> Why aren't you looking at the wmi.c driver? That should be where the >>>>>> issue is, not the driver core, right? >>>>>> >>>>>> thanks, >>>>>> >>>>>> greg k-h >>>>> >>>>> Hi, Mr. Greg, >>>>> >>>>> Thanks for the quick reply. >>>>> >>>>> I have added CC: for additional developers per drivers/platform/x86/wmi.c, >>>>> however, this seems to me like hieroglyphs. There is nothing obvious, but >>>>> I had not noticed it with v6.3-rc3? >>>>> >>>>> Maybe, there seems to be something off: >>>>> >>>>> 949 static int wmi_dev_probe(struct device *dev) >>>>> 950 { >>>>> 951 struct wmi_block *wblock = dev_to_wblock(dev); >>>>> 952 struct wmi_driver *wdriver = drv_to_wdrv(dev->driver); >>>>> 953 int ret = 0; >>>>> 954 char *buf; >>>>> 955 >>>>> 956 if (ACPI_FAILURE(wmi_method_enable(wblock, true))) >>>>> 957 dev_warn(dev, "failed to enable device -- probing anyway\n"); >>>>> 958 >>>>> 959 if (wdriver->probe) { >>>>> 960 ret = wdriver->probe(dev_to_wdev(dev), >>>>> 961 find_guid_context(wblock, wdriver)); >>>>> 962 if (ret != 0) >>>>> 963 goto probe_failure; >>>>> 964 } >>>>> 965 >>>>> 966 /* driver wants a character device made */ >>>>> 967 if (wdriver->filter_callback) { >>>>> 968 /* check that required buffer size declared by driver or MOF */ >>>>> 969 if (!wblock->req_buf_size) { >>>>> 970 dev_err(&wblock->dev.dev, >>>>> 971 "Required buffer size not set\n"); >>>>> 972 ret = -EINVAL; >>>>> 973 goto probe_failure; >>>>> 974 } >>>>> 975 >>>>> 976 wblock->handler_data = kmalloc(wblock->req_buf_size, >>>>> 977 GFP_KERNEL); >>>>> 978 if (!wblock->handler_data) { >>>>> 979 ret = -ENOMEM; >>>>> 980 goto probe_failure; >>>>> 981 } >>>>> 982 >>>>> 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", wdriver->driver.name); >>>>> 984 if (!buf) { >>>>> 985 ret = -ENOMEM; >>>>> 986 goto probe_string_failure; >>>>> 987 } >>>>> 988 wblock->char_dev.minor = MISC_DYNAMIC_MINOR; >>>>> 989 wblock->char_dev.name = buf; >>>>> 990 wblock->char_dev.fops = &wmi_fops; >>>>> 991 wblock->char_dev.mode = 0444; >>>>> 992 ret = misc_register(&wblock->char_dev); >>>>> 993 if (ret) { >>>>> 994 dev_warn(dev, "failed to register char dev: %d\n", ret); >>>>> 995 ret = -ENOMEM; >>>>> 996 goto probe_misc_failure; >>>>> 997 } >>>>> 998 } >>>>> 999 >>>>> 1000 set_bit(WMI_PROBED, &wblock->flags); >>>>> 1001 return 0; >>>>> 1002 >>>>> 1003 probe_misc_failure: >>>>> 1004 kfree(buf); >>>>> 1005 probe_string_failure: >>>>> 1006 kfree(wblock->handler_data); >>>>> 1007 probe_failure: >>>>> 1008 if (ACPI_FAILURE(wmi_method_enable(wblock, false))) >>>>> 1009 dev_warn(dev, "failed to disable device\n"); >>>>> >>>>> >>>>> char *buf is passed to kfree(buf) uninitialised if wdriver->filter_callback >>>>> is not set. >>>>> >>>>> It seems like a logical error per se, but I don't believe this is the cause >>>>> of the leak? >>>> >>>> CORRECTION: >>>> >>>> I overlooked the "return 0" in line 1001. >>> >>> Yeah, and the memory looks to be freed properly in the wmi_dev_remove() >>> callback, right? >> >> It would appear so. To verify that: >> >> Alloc: >> 976 wblock->handler_data = kmalloc(wblock->req_buf_size, >> GFP_KERNEL); >> <check> >> >> 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", wdriver->driver.name); >> <check> >> 989 wblock->char_dev.name = buf; >> >> In lines 1022-1023: >> >> 1022 kfree(wblock->char_dev.name); >> 1023 kfree(wblock->handler_data); >> >>>> This is why I don't think things should be rushed, but analysed with clear and >>>> cold head. And with as many eyes as possible :) >>>> >>>> The driver stuff is my long-term research interest. To state the obvious, >>>> the printing and multimedia education and industry in general would benefit from >>>> the open-source drivers for many instruments that still work, but are obsoleted >>>> by the producer and require unsupported versions of the OS. >>>> >>>> Thank you again for reviewing the bug report, however, ATM I do not think I have >>>> what it takes to hunt down the memleak. :-/ >>> >>> Do you have a reproducer that you can use to show the problem better? >> >> Unfortunately, the problem doesn't seem to appear during the run of a particular >> test, but immediately on startup of the OS. This makes it awkward to pinpoint the >> exact service that triggered memory leaks. But they would appear to have to do >> with the initialisation of the USB devices, wouldn't they? >> >> There seem to be strings: >> >> "USBPortAccess,Enabled;[Optional:" >> "USBBIOSSupport,Enabled;[Optional" >> "USBEnumerationDelay,Disabled;[Op" >> >> This seems to be happening during USB initialisation and before any services. >> But I might as well be wrong. >> >>> Or can you test kernel patches to verify the problem is fixed or not if >>> we send you patches to test? >> >> Certainly, Lord willing, I can test the patches in the same environment that >> mainfeted the bug (or memleak). >> >> Best regards, >> Mirsad >> -- Mirsad Todorovac Sistem inženjer Grafički fakultet | Akademija likovnih umjetnosti Sveučilište u Zagrebu System engineer Faculty of Graphic Arts | Academy of Fine Arts University of Zagreb, Republic of Croatia tel. +385 (0)1 3711 451 mob. +385 91 57 88 355 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [BUG] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-28 19:06 ` Mirsad Goran Todorovac @ 2023-03-28 19:55 ` Armin Wolf 2023-03-29 8:13 ` Mirsad Goran Todorovac 0 siblings, 1 reply; 24+ messages in thread From: Armin Wolf @ 2023-03-28 19:55 UTC (permalink / raw) To: Mirsad Goran Todorovac, Greg Kroah-Hartman Cc: Rafael J. Wysocki, linux-kernel, Hans de Goede, Mark Gross, platform-driver-x86 Am 28.03.23 um 21:06 schrieb Mirsad Goran Todorovac: > On 3/28/2023 6:53 PM, Armin Wolf wrote: >> Am 28.03.23 um 14:44 schrieb Mirsad Todorovac: >> >>> On 3/28/23 14:17, Greg Kroah-Hartman wrote: >>>> On Tue, Mar 28, 2023 at 02:08:06PM +0200, Mirsad Todorovac wrote: >>>>> On 3/28/23 13:59, Mirsad Todorovac wrote: >>>>> >>>>>> On 3/28/23 13:28, Greg Kroah-Hartman wrote: >>>>>>> On Tue, Mar 28, 2023 at 01:13:33PM +0200, Mirsad Todorovac wrote: >>>>>>>> Hi all, >>>>>>>> >>>>>>>> Here is another kernel memory leak report, just as I thought we >>>>>>>> have done with >>>>>>>> them by the xhci patch by Mathias. >>>>>>>> >>>>>>>> The memory leaks were caught on an AlmaLinux 8.7 (CentOS) fork >>>>>>>> system, running >>>>>>>> on a Lenovo desktop box (see lshw.txt) and the newest Linux >>>>>>>> kernel 6.3-rc4 commit >>>>>>>> g3a93e40326c8 with Mathias' patch for a xhci systemd-devd >>>>>>>> triggered leak. >>>>>>>> >>>>>>>> See: >>>>>>>> <20230327095019.1017159-1-mathias.nyman@linux.intel.com> on LKML. >>>>>>>> >>>>>>>> This leak is also systemd-devd triggered, except for the >>>>>>>> memstick_check() leaks >>>>>>>> which I was unable to bisect due to the box not booting older >>>>>>>> kernels (work in >>>>>>>> progress). >>>>>>>> >>>>>>>> unreferenced object 0xffff88ad12392710 (size 96): >>>>>>>> comm "systemd-udevd", pid 735, jiffies 4294896759 (age >>>>>>>> 2257.568s) >>>>>>>> hex dump (first 32 bytes): >>>>>>>> 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 >>>>>>>> SerialPort1Addre >>>>>>>> 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 >>>>>>>> ss,3F8/IRQ4;[Opt >>>>>>>> backtrace: >>>>>>>> [<ffffffffae8fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>>>>> [<ffffffffae902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>>>>> [<ffffffffae8773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>>>>> [<ffffffffae866a1a>] kstrdup+0x3a/0x70 >>>>>>>> [<ffffffffc0d839aa>] >>>>>>>> tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >>>>>>>> [<ffffffffc0d83b64>] tlmi_setting.constprop.4+0x54/0x90 >>>>>>>> [think_lmi] >>>>>>>> [<ffffffffc0d842b1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>>>>> [<ffffffffc051dc53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>>>> >> Hi, >> >> this "SerialPort1Address" string looks like a BIOS setup option, and >> indeed think_lmi allows for >> changing BIOS setup options over sysfs. While looking at >> current_value_show() in think-lmi.c, i noticed >> that "item" holds a string which is allocated with kstrdup(), so it >> has to be freed using kfree(). >> This however does not happen if strbrk() fails, so maybe the memory >> leak is caused by this? >> >> Armin Wolf > > Hi Armin, > > I tried your suggestion, and though it is an obvious improvement and a > leak fix, this > was not the one we were searching for. > > I tested the following patch: > > diff --git a/drivers/platform/x86/think-lmi.c > b/drivers/platform/x86/think-lmi.c > index c816646eb661..1e77ecb0cba8 100644 > --- a/drivers/platform/x86/think-lmi.c > +++ b/drivers/platform/x86/think-lmi.c > @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject > *kobj, struct kobj_attribute *a > > /* validate and split from `item,value` -> `value` */ > value = strpbrk(item, ","); > - if (!value || value == item || !strlen(value + 1)) > + if (!value || value == item || !strlen(value + 1)) { > + kfree(item); > return -EINVAL; > + } > > ret = sysfs_emit(buf, "%s\n", value + 1); > kfree(item); > > (I would also object to the use of strlen() here, for it is inherently > insecure > against SEGFAULT in kernel space.) > > I still get: > [root@pc-mtodorov marvin]# uname -rms > Linux 6.3.0-rc4-armin-patch-00025-g3a93e40326c8-dirty x86_64 > [root@pc-mtodorov marvin]# cat /sys/kernel/debug/kmemleak [edited] > unreferenced object 0xffff8eb008ef9260 (size 96): > comm "systemd-udevd", pid 771, jiffies 4294896499 (age 74.880s) > hex dump (first 32 bytes): > 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 SerialPort1Addre > 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 ss,3F8/IRQ4;[Opt > backtrace: > [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 > [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 > [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 > [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 > [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 > [think_lmi] > [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] > [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] > [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] > [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 > [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 > [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 > [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 > [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 > [<ffffffff9f197c62>] driver_attach+0x22/0x30 > [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 > [<ffffffff9f19a0a2>] driver_register+0x62/0x120 > unreferenced object 0xffff8eb018ddbb40 (size 64): > comm "systemd-udevd", pid 771, jiffies 4294896528 (age 74.780s) > hex dump (first 32 bytes): > 55 53 42 50 6f 72 74 41 63 63 65 73 73 2c 45 6e USBPortAccess,En > 61 62 6c 65 64 3b 5b 4f 70 74 69 6f 6e 61 6c 3a abled;[Optional: > backtrace: > [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 > [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 > [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 > [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 > [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 > [think_lmi] > [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] > [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] > [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] > [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 > [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 > [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 > [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 > [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 > [<ffffffff9f197c62>] driver_attach+0x22/0x30 > [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 > [<ffffffff9f19a0a2>] driver_register+0x62/0x120 > unreferenced object 0xffff8eb006fe2b40 (size 64): > comm "systemd-udevd", pid 771, jiffies 4294896542 (age 74.724s) > hex dump (first 32 bytes): > 55 53 42 42 49 4f 53 53 75 70 70 6f 72 74 2c 45 USBBIOSSupport,E > 6e 61 62 6c 65 64 3b 5b 4f 70 74 69 6f 6e 61 6c nabled;[Optional > backtrace: > [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 > [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 > [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 > [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 > [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 > [think_lmi] > [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] > [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] > [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] > [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 > [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 > [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 > [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 > [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 > [<ffffffff9f197c62>] driver_attach+0x22/0x30 > [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 > [<ffffffff9f19a0a2>] driver_register+0x62/0x120 > > There are currently 84 wmi_dev_probe leaks, sized mostly 64 bytes, and > one 96 and two 192 bytes. > > I also cannot figure out the mechanism by which current_value_show() > is called, when it is static? > > Any idea? > > Thanks. > > Best regards, > Mirsad > Can you tell me how many BIOS settings think-lmi provides on your machine? Because according to the stacktrace, the other place where the leak could have occurred is inside tlmi_analyze(), which calls tlmi_setting(). However, i have no idea on how *info is somehow leaked, it has to happen inside the for-loop between the call to tlmi_setting() and strreplace(), because otherwise the strings would not contain the "/" character. Can you check if the problem is somehow solved by applying the following commit from the platform-drivers-x86 for-next branch: da62908efe80 ("platform/x86: think-lmi: Properly interpret return value of tlmi_setting") Also current_value_show() is used by attr_current_val, the __ATTR_RW_MODE() macro arranges for that. Armin Wolf >>>>>>> Why aren't you looking at the wmi.c driver? That should be >>>>>>> where the >>>>>>> issue is, not the driver core, right? >>>>>>> >>>>>>> thanks, >>>>>>> >>>>>>> greg k-h >>>>>> >>>>>> Hi, Mr. Greg, >>>>>> >>>>>> Thanks for the quick reply. >>>>>> >>>>>> I have added CC: for additional developers per >>>>>> drivers/platform/x86/wmi.c, >>>>>> however, this seems to me like hieroglyphs. There is nothing >>>>>> obvious, but >>>>>> I had not noticed it with v6.3-rc3? >>>>>> >>>>>> Maybe, there seems to be something off: >>>>>> >>>>>> 949 static int wmi_dev_probe(struct device *dev) >>>>>> 950 { >>>>>> 951 struct wmi_block *wblock = dev_to_wblock(dev); >>>>>> 952 struct wmi_driver *wdriver = >>>>>> drv_to_wdrv(dev->driver); >>>>>> 953 int ret = 0; >>>>>> 954 char *buf; >>>>>> 955 >>>>>> 956 if (ACPI_FAILURE(wmi_method_enable(wblock, true))) >>>>>> 957 dev_warn(dev, "failed to enable device >>>>>> -- probing anyway\n"); >>>>>> 958 >>>>>> 959 if (wdriver->probe) { >>>>>> 960 ret = wdriver->probe(dev_to_wdev(dev), >>>>>> 961 find_guid_context(wblock, wdriver)); >>>>>> 962 if (ret != 0) >>>>>> 963 goto probe_failure; >>>>>> 964 } >>>>>> 965 >>>>>> 966 /* driver wants a character device made */ >>>>>> 967 if (wdriver->filter_callback) { >>>>>> 968 /* check that required buffer size >>>>>> declared by driver or MOF */ >>>>>> 969 if (!wblock->req_buf_size) { >>>>>> 970 dev_err(&wblock->dev.dev, >>>>>> 971 "Required buffer size >>>>>> not set\n"); >>>>>> 972 ret = -EINVAL; >>>>>> 973 goto probe_failure; >>>>>> 974 } >>>>>> 975 >>>>>> 976 wblock->handler_data = >>>>>> kmalloc(wblock->req_buf_size, >>>>>> 977 GFP_KERNEL); >>>>>> 978 if (!wblock->handler_data) { >>>>>> 979 ret = -ENOMEM; >>>>>> 980 goto probe_failure; >>>>>> 981 } >>>>>> 982 >>>>>> 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", >>>>>> wdriver->driver.name); >>>>>> 984 if (!buf) { >>>>>> 985 ret = -ENOMEM; >>>>>> 986 goto probe_string_failure; >>>>>> 987 } >>>>>> 988 wblock->char_dev.minor = >>>>>> MISC_DYNAMIC_MINOR; >>>>>> 989 wblock->char_dev.name = buf; >>>>>> 990 wblock->char_dev.fops = &wmi_fops; >>>>>> 991 wblock->char_dev.mode = 0444; >>>>>> 992 ret = misc_register(&wblock->char_dev); >>>>>> 993 if (ret) { >>>>>> 994 dev_warn(dev, "failed to >>>>>> register char dev: %d\n", ret); >>>>>> 995 ret = -ENOMEM; >>>>>> 996 goto probe_misc_failure; >>>>>> 997 } >>>>>> 998 } >>>>>> 999 >>>>>> 1000 set_bit(WMI_PROBED, &wblock->flags); >>>>>> 1001 return 0; >>>>>> 1002 >>>>>> 1003 probe_misc_failure: >>>>>> 1004 kfree(buf); >>>>>> 1005 probe_string_failure: >>>>>> 1006 kfree(wblock->handler_data); >>>>>> 1007 probe_failure: >>>>>> 1008 if (ACPI_FAILURE(wmi_method_enable(wblock, >>>>>> false))) >>>>>> 1009 dev_warn(dev, "failed to disable >>>>>> device\n"); >>>>>> >>>>>> >>>>>> char *buf is passed to kfree(buf) uninitialised if >>>>>> wdriver->filter_callback >>>>>> is not set. >>>>>> >>>>>> It seems like a logical error per se, but I don't believe this is >>>>>> the cause >>>>>> of the leak? >>>>> >>>>> CORRECTION: >>>>> >>>>> I overlooked the "return 0" in line 1001. >>>> >>>> Yeah, and the memory looks to be freed properly in the >>>> wmi_dev_remove() >>>> callback, right? >>> >>> It would appear so. To verify that: >>> >>> Alloc: >>> 976 wblock->handler_data = kmalloc(wblock->req_buf_size, >>> GFP_KERNEL); >>> <check> >>> >>> 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", wdriver->driver.name); >>> <check> >>> 989 wblock->char_dev.name = buf; >>> >>> In lines 1022-1023: >>> >>> 1022 kfree(wblock->char_dev.name); >>> 1023 kfree(wblock->handler_data); >>> >>>>> This is why I don't think things should be rushed, but analysed >>>>> with clear and >>>>> cold head. And with as many eyes as possible :) >>>>> >>>>> The driver stuff is my long-term research interest. To state the >>>>> obvious, >>>>> the printing and multimedia education and industry in general >>>>> would benefit from >>>>> the open-source drivers for many instruments that still work, but >>>>> are obsoleted >>>>> by the producer and require unsupported versions of the OS. >>>>> >>>>> Thank you again for reviewing the bug report, however, ATM I do >>>>> not think I have >>>>> what it takes to hunt down the memleak. :-/ >>>> >>>> Do you have a reproducer that you can use to show the problem better? >>> >>> Unfortunately, the problem doesn't seem to appear during the run of >>> a particular >>> test, but immediately on startup of the OS. This makes it awkward to >>> pinpoint the >>> exact service that triggered memory leaks. But they would appear to >>> have to do >>> with the initialisation of the USB devices, wouldn't they? >>> >>> There seem to be strings: >>> >>> "USBPortAccess,Enabled;[Optional:" >>> "USBBIOSSupport,Enabled;[Optional" >>> "USBEnumerationDelay,Disabled;[Op" >>> >>> This seems to be happening during USB initialisation and before any >>> services. >>> But I might as well be wrong. >>> >>>> Or can you test kernel patches to verify the problem is fixed or >>>> not if >>>> we send you patches to test? >>> >>> Certainly, Lord willing, I can test the patches in the same >>> environment that >>> mainfeted the bug (or memleak). >>> >>> Best regards, >>> Mirsad >>> > ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-28 19:55 ` Armin Wolf @ 2023-03-29 8:13 ` Mirsad Goran Todorovac 2023-03-29 13:22 ` [BUG] [BISECTED] " Mirsad Goran Todorovac 0 siblings, 1 reply; 24+ messages in thread From: Mirsad Goran Todorovac @ 2023-03-29 8:13 UTC (permalink / raw) To: Armin Wolf, Greg Kroah-Hartman Cc: Rafael J. Wysocki, linux-kernel, Hans de Goede, Mark Gross, platform-driver-x86, Mark Pearson On 28.3.2023. 21:55, Armin Wolf wrote: > Am 28.03.23 um 21:06 schrieb Mirsad Goran Todorovac: > >> On 3/28/2023 6:53 PM, Armin Wolf wrote: >>> Am 28.03.23 um 14:44 schrieb Mirsad Todorovac: >>> >>>> On 3/28/23 14:17, Greg Kroah-Hartman wrote: >>>>> On Tue, Mar 28, 2023 at 02:08:06PM +0200, Mirsad Todorovac wrote: >>>>>> On 3/28/23 13:59, Mirsad Todorovac wrote: >>>>>> >>>>>>> On 3/28/23 13:28, Greg Kroah-Hartman wrote: >>>>>>>> On Tue, Mar 28, 2023 at 01:13:33PM +0200, Mirsad Todorovac wrote: >>>>>>>>> Hi all, >>>>>>>>> >>>>>>>>> Here is another kernel memory leak report, just as I thought we >>>>>>>>> have done with >>>>>>>>> them by the xhci patch by Mathias. >>>>>>>>> >>>>>>>>> The memory leaks were caught on an AlmaLinux 8.7 (CentOS) fork >>>>>>>>> system, running >>>>>>>>> on a Lenovo desktop box (see lshw.txt) and the newest Linux >>>>>>>>> kernel 6.3-rc4 commit >>>>>>>>> g3a93e40326c8 with Mathias' patch for a xhci systemd-devd >>>>>>>>> triggered leak. >>>>>>>>> >>>>>>>>> See: >>>>>>>>> <20230327095019.1017159-1-mathias.nyman@linux.intel.com> on LKML. >>>>>>>>> >>>>>>>>> This leak is also systemd-devd triggered, except for the >>>>>>>>> memstick_check() leaks >>>>>>>>> which I was unable to bisect due to the box not booting older >>>>>>>>> kernels (work in >>>>>>>>> progress). >>>>>>>>> >>>>>>>>> unreferenced object 0xffff88ad12392710 (size 96): >>>>>>>>> comm "systemd-udevd", pid 735, jiffies 4294896759 (age >>>>>>>>> 2257.568s) >>>>>>>>> hex dump (first 32 bytes): >>>>>>>>> 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 >>>>>>>>> SerialPort1Addre >>>>>>>>> 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 >>>>>>>>> ss,3F8/IRQ4;[Opt >>>>>>>>> backtrace: >>>>>>>>> [<ffffffffae8fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>>>>>> [<ffffffffae902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>>>>>> [<ffffffffae8773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>>>>>> [<ffffffffae866a1a>] kstrdup+0x3a/0x70 >>>>>>>>> [<ffffffffc0d839aa>] >>>>>>>>> tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >>>>>>>>> [<ffffffffc0d83b64>] tlmi_setting.constprop.4+0x54/0x90 >>>>>>>>> [think_lmi] >>>>>>>>> [<ffffffffc0d842b1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>>>>>> [<ffffffffc051dc53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>>>>> >>> Hi, >>> >>> this "SerialPort1Address" string looks like a BIOS setup option, and >>> indeed think_lmi allows for >>> changing BIOS setup options over sysfs. While looking at >>> current_value_show() in think-lmi.c, i noticed >>> that "item" holds a string which is allocated with kstrdup(), so it >>> has to be freed using kfree(). >>> This however does not happen if strbrk() fails, so maybe the memory >>> leak is caused by this? >>> >>> Armin Wolf >> >> Hi Armin, >> >> I tried your suggestion, and though it is an obvious improvement and a >> leak fix, this >> was not the one we were searching for. >> >> I tested the following patch: >> >> diff --git a/drivers/platform/x86/think-lmi.c >> b/drivers/platform/x86/think-lmi.c >> index c816646eb661..1e77ecb0cba8 100644 >> --- a/drivers/platform/x86/think-lmi.c >> +++ b/drivers/platform/x86/think-lmi.c >> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject >> *kobj, struct kobj_attribute *a >> >> /* validate and split from `item,value` -> `value` */ >> value = strpbrk(item, ","); >> - if (!value || value == item || !strlen(value + 1)) >> + if (!value || value == item || !strlen(value + 1)) { >> + kfree(item); >> return -EINVAL; >> + } >> >> ret = sysfs_emit(buf, "%s\n", value + 1); >> kfree(item); >> >> (I would also object to the use of strlen() here, for it is inherently >> insecure >> against SEGFAULT in kernel space.) >> >> I still get: >> [root@pc-mtodorov marvin]# uname -rms >> Linux 6.3.0-rc4-armin-patch-00025-g3a93e40326c8-dirty x86_64 >> [root@pc-mtodorov marvin]# cat /sys/kernel/debug/kmemleak [edited] >> unreferenced object 0xffff8eb008ef9260 (size 96): >> comm "systemd-udevd", pid 771, jiffies 4294896499 (age 74.880s) >> hex dump (first 32 bytes): >> 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 SerialPort1Addre >> 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 ss,3F8/IRQ4;[Opt >> backtrace: >> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >> [think_lmi] >> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >> unreferenced object 0xffff8eb018ddbb40 (size 64): >> comm "systemd-udevd", pid 771, jiffies 4294896528 (age 74.780s) >> hex dump (first 32 bytes): >> 55 53 42 50 6f 72 74 41 63 63 65 73 73 2c 45 6e USBPortAccess,En >> 61 62 6c 65 64 3b 5b 4f 70 74 69 6f 6e 61 6c 3a abled;[Optional: >> backtrace: >> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >> [think_lmi] >> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >> unreferenced object 0xffff8eb006fe2b40 (size 64): >> comm "systemd-udevd", pid 771, jiffies 4294896542 (age 74.724s) >> hex dump (first 32 bytes): >> 55 53 42 42 49 4f 53 53 75 70 70 6f 72 74 2c 45 USBBIOSSupport,E >> 6e 61 62 6c 65 64 3b 5b 4f 70 74 69 6f 6e 61 6c nabled;[Optional >> backtrace: >> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >> [think_lmi] >> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >> >> There are currently 84 wmi_dev_probe leaks, sized mostly 64 bytes, and >> one 96 and two 192 bytes. >> >> I also cannot figure out the mechanism by which current_value_show() >> is called, when it is static? >> >> Any idea? >> >> Thanks. >> >> Best regards, >> Mirsad >> > Can you tell me how many BIOS settings think-lmi provides on your machine? Because according to the stacktrace, > the other place where the leak could have occurred is inside tlmi_analyze(), which calls tlmi_setting(). Yes, Sir! I think these could be the ones you need (totaling 83, which is close to 82 systemd-udevd leaks): [root@pc-mtodorov marvin]# ls -l /sys/devices/virtual/firmware-attributes/thinklmi/attributes | grep ^d drwxr-xr-x 2 root root 0 Mar 29 08:24 AfterPowerLoss drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmDate(MM\DD\YYYY) drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmDayofWeek drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmTime(HH:MM:SS) drwxr-xr-x 2 root root 0 Mar 29 08:24 ASPMSupport drwxr-xr-x 2 root root 0 Mar 29 08:24 AutomaticBootSequence drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtBootDeviceList drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtReboot drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtUnattendedBoot drwxr-xr-x 2 root root 0 Mar 29 08:24 BootMode drwxr-xr-x 2 root root 0 Mar 29 08:24 BootPriority drwxr-xr-x 2 root root 0 Mar 29 08:24 BootUpNum-LockStatus drwxr-xr-x 2 root root 0 Mar 29 08:24 C1ESupport drwxr-xr-x 2 root root 0 Mar 29 08:24 CardReader drwxr-xr-x 2 root root 0 Mar 29 08:24 ClearTCGSecurityFeature drwxr-xr-x 2 root root 0 Mar 29 08:24 ComputraceModuleActivation drwxr-xr-x 2 root root 0 Mar 29 08:24 ConfigurationChangeDetection drwxr-xr-x 2 root root 0 Mar 29 08:24 ConfigureSATAas drwxr-xr-x 2 root root 0 Mar 29 08:24 CoreMulti-Processing drwxr-xr-x 2 root root 0 Mar 29 08:24 CoverTamperDetected drwxr-xr-x 2 root root 0 Mar 29 08:24 CSM drwxr-xr-x 2 root root 0 Mar 29 08:24 CStateSupport drwxr-xr-x 2 root root 0 Mar 29 08:24 DeviceGuard drwxr-xr-x 2 root root 0 Mar 29 08:24 DustShieldAlert drwxr-xr-x 2 root root 0 Mar 29 08:24 EISTSupport drwxr-xr-x 2 root root 0 Mar 29 08:24 EnhancedPowerSavingMode drwxr-xr-x 2 root root 0 Mar 29 08:24 ErrorBootSequence drwxr-xr-x 2 root root 0 Mar 29 08:24 Friday drwxr-xr-x 2 root root 0 Mar 29 08:24 FrontUSBPorts drwxr-xr-x 2 root root 0 Mar 29 08:24 HardDiskPre-delay drwxr-xr-x 2 root root 0 Mar 29 08:24 Intel(R)SGXControl drwxr-xr-x 2 root root 0 Mar 29 08:24 InternalSpeaker drwxr-xr-x 2 root root 0 Mar 29 08:24 Monday drwxr-xr-x 2 root root 0 Mar 29 08:24 OnboardAudioController drwxr-xr-x 2 root root 0 Mar 29 08:24 OnboardEthernetController drwxr-xr-x 2 root root 0 Mar 29 08:24 OptionKeysDisplay drwxr-xr-x 2 root root 0 Mar 29 08:24 OptionKeysDisplayStyle drwxr-xr-x 2 root root 0 Mar 29 08:24 OSOptimizedDefaults drwxr-xr-x 2 root root 0 Mar 29 08:24 PasswordCountExceededError drwxr-xr-x 2 root root 0 Mar 29 08:24 PCIe16xSlotSpeed drwxr-xr-x 2 root root 0 Mar 29 08:24 PCIe1xSlot1Speed drwxr-xr-x 2 root root 0 Mar 29 08:24 PrimaryBootSequence drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEIPV4NetworkStack drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEIPV6NetworkStack drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEOptionROM drwxr-xr-x 2 root root 0 Mar 29 08:24 RearUSBPorts drwxr-xr-x 2 root root 0 Mar 29 08:24 RequireAdmin.Pass.whenFlashing drwxr-xr-x 2 root root 0 Mar 29 08:24 RequireHDPonSystemBoot drwxr-xr-x 2 root root 0 Mar 29 08:24 SATAController drwxr-xr-x 2 root root 0 Mar 29 08:24 SATADrive1 drwxr-xr-x 2 root root 0 Mar 29 08:24 SATADrive2 drwxr-xr-x 2 root root 0 Mar 29 08:24 Saturday drwxr-xr-x 2 root root 0 Mar 29 08:24 SecureBoot drwxr-xr-x 2 root root 0 Mar 29 08:24 SecureRollBackPrevention drwxr-xr-x 2 root root 0 Mar 29 08:24 SecurityChip drwxr-xr-x 2 root root 0 Mar 29 08:24 SelectActiveVideo drwxr-xr-x 2 root root 0 Mar 29 08:24 SerialPort1Address drwxr-xr-x 2 root root 0 Mar 29 08:24 SmartUSBProtection drwxr-xr-x 2 root root 0 Mar 29 08:24 StartupDeviceMenuPrompt drwxr-xr-x 2 root root 0 Mar 29 08:24 StartupSequence drwxr-xr-x 2 root root 0 Mar 29 08:24 Sunday drwxr-xr-x 2 root root 0 Mar 29 08:24 Thursday drwxr-xr-x 2 root root 0 Mar 29 08:24 Tuesday drwxr-xr-x 2 root root 0 Mar 29 08:24 TurboMode drwxr-xr-x 2 root root 0 Mar 29 08:24 USBBIOSSupport drwxr-xr-x 2 root root 0 Mar 29 08:24 USBEnumerationDelay drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort1 drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort2 drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort3 drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort4 drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort5 drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort6 drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort7 drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort8 drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPortAccess drwxr-xr-x 2 root root 0 Mar 29 08:24 UserDefinedAlarmTime(HH:MM:SS) drwxr-xr-x 2 root root 0 Mar 29 08:24 VirtualizationTechnology drwxr-xr-x 2 root root 0 Mar 29 08:24 VTdFeature drwxr-xr-x 2 root root 0 Mar 29 08:24 WakefromSerialPortRing drwxr-xr-x 2 root root 0 Mar 29 08:24 WakeOnLAN drwxr-xr-x 2 root root 0 Mar 29 08:24 WakeUponAlarm drwxr-xr-x 2 root root 0 Mar 29 08:24 Wednesday drwxr-xr-x 2 root root 0 Mar 29 08:24 WindowsUEFIFirmwareUpdate [root@pc-mtodorov marvin]# ls -l /sys/devices/virtual/firmware-attributes/thinklmi/attributes | grep ^d | wc -l 83 [root@pc-mtodorov marvin]# > However, i have no idea on how *info is somehow leaked, it has to happen inside the for-loop tween the call > to tlmi_setting() and strreplace(), because otherwise the strings would not contain the "/" character. I see. It is the line 1404. > Can you check if the problem is somehow solved by applying the following commit from the platform-drivers-x86 > for-next branch: > da62908efe80 ("platform/x86: think-lmi: Properly interpret return value of tlmi_setting") It could possibly be that. But I do not recall seeing these messages in 6.3-rc3 ... ... Unfortunately, the build with Thomas' patch you referred to did not work: unreferenced object 0xffff9dff4d28bbc8 (size 192): comm "systemd-udevd", pid 769, jiffies 4294897473 (age 85.700s) hex dump (first 32 bytes): 50 72 69 6d 61 72 79 42 6f 6f 74 53 65 71 75 65 PrimaryBootSeque 6e 63 65 2c 4d 2e 32 20 44 72 69 76 65 20 31 3a nce,M.2 Drive 1: backtrace: [<ffffffffa48fb26c>] slab_post_alloc_hook+0x8c/0x3e0 [<ffffffffa4902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 [<ffffffffa48773c9>] __kmalloc_node_track_caller+0x59/0x180 [<ffffffffa4866a1a>] kstrdup+0x3a/0x70 [<ffffffffc0c7f9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] [<ffffffffc0c7fb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] [<ffffffffc0c802c1>] tlmi_probe+0x591/0xba0 [think_lmi] [<ffffffffc03c9c53>] wmi_dev_probe+0x163/0x230 [wmi] [<ffffffffa4f987eb>] really_probe+0x17b/0x3d0 [<ffffffffa4f98ad4>] __driver_probe_device+0x84/0x190 [<ffffffffa4f98c14>] driver_probe_device+0x24/0xc0 [<ffffffffa4f98ed2>] __driver_attach+0xc2/0x190 [<ffffffffa4f95ab1>] bus_for_each_dev+0x81/0xd0 [<ffffffffa4f97c62>] driver_attach+0x22/0x30 [<ffffffffa4f97354>] bus_add_driver+0x1b4/0x240 [<ffffffffa4f9a0a2>] driver_register+0x62/0x120 unreferenced object 0xffff9dff4d28a008 (size 192): comm "systemd-udevd", pid 769, jiffies 4294897517 (age 85.540s) hex dump (first 32 bytes): 45 72 72 6f 72 42 6f 6f 74 53 65 71 75 65 6e 63 ErrorBootSequenc 65 2c 4e 65 74 77 6f 72 6b 20 31 3a 4d 2e 32 20 e,Network 1:M.2 backtrace: [<ffffffffa48fb26c>] slab_post_alloc_hook+0x8c/0x3e0 [<ffffffffa4902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 [<ffffffffa48773c9>] __kmalloc_node_track_caller+0x59/0x180 [<ffffffffa4866a1a>] kstrdup+0x3a/0x70 [<ffffffffc0c7f9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] [<ffffffffc0c7fb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] [<ffffffffc0c802c1>] tlmi_probe+0x591/0xba0 [think_lmi] [<ffffffffc03c9c53>] wmi_dev_probe+0x163/0x230 [wmi] [<ffffffffa4f987eb>] really_probe+0x17b/0x3d0 [<ffffffffa4f98ad4>] __driver_probe_device+0x84/0x190 [<ffffffffa4f98c14>] driver_probe_device+0x24/0xc0 [<ffffffffa4f98ed2>] __driver_attach+0xc2/0x190 [<ffffffffa4f95ab1>] bus_for_each_dev+0x81/0xd0 [<ffffffffa4f97c62>] driver_attach+0x22/0x30 [<ffffffffa4f97354>] bus_add_driver+0x1b4/0x240 [<ffffffffa4f9a0a2>] driver_register+0x62/0x120 [root@pc-mtodorov marvin]# uname -rms Linux 6.3.0-rc4-armin+tw-patch-00025-g3a93e40326c8-dirty x86_64 [root@pc-mtodorov marvin]# What was applied is: mtodorov@domac:~/linux/kernel/linux_torvalds$ git diff diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index c816646eb661..9a3015f43aaf 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a /* validate and split from `item,value` -> `value` */ value = strpbrk(item, ","); - if (!value || value == item || !strlen(value + 1)) + if (!value || value == item || !strlen(value + 1)) { + kfree(item); return -EINVAL; + } ret = sysfs_emit(buf, "%s\n", value + 1); kfree(item); @@ -1380,7 +1382,6 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type, static int tlmi_analyze(void) { - acpi_status status; int i, ret; if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && @@ -1417,8 +1418,8 @@ static int tlmi_analyze(void) char *p; tlmi_priv.setting[i] = NULL; - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); - if (ACPI_FAILURE(status)) + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); + if (ret) break; if (!item) break; > Also current_value_show() is used by attr_current_val, the __ATTR_RW_MODE() macro arranges for that. Thanks. In this build: [root@pc-mtodorov marvin]# uname -rms Linux 6.3.0-rc34tests-00001-g6981739a967c x86_64 [root@pc-mtodorov marvin]# ... the bug isn't present, so it might be something added recently: commit 8a02d70679fc1c434401863333c8ea7dbf201494 Author: Mark Pearson <mpearson-lenovo@squebb.ca> Date: Sun Mar 19 20:32:21 2023 -0400 platform/x86: think-lmi: Add possible_values for ThinkStation commit cf337f27f3bfc4aeab4954c468239fd6233c7638 Author: Mark Pearson <mpearson-lenovo@squebb.ca> Date: Sun Mar 19 20:32:20 2023 -0400 platform/x86: think-lmi: only display possible_values if available commit 45e21289bfc6e257885514790a8a8887da822d40 Author: Mark Pearson <mpearson-lenovo@squebb.ca> Date: Sun Mar 19 20:32:19 2023 -0400 platform/x86: think-lmi: use correct possible_values delimiters commit 583329dcf22e568a328a944f20427ccfc95dce01 Author: Mark Pearson <mpearson-lenovo@squebb.ca> Date: Sun Mar 19 20:32:18 2023 -0400 platform/x86: think-lmi: add missing type attribute I have CC:-ed the author of the commits. I can try bisect, but only after my day job. Have a nice day! Best regards, Mirsad > Armin Wolf > >>>>>>>> Why aren't you looking at the wmi.c driver? That should be >>>>>>>> where the >>>>>>>> issue is, not the driver core, right? >>>>>>>> >>>>>>>> thanks, >>>>>>>> >>>>>>>> greg k-h >>>>>>> >>>>>>> Hi, Mr. Greg, >>>>>>> >>>>>>> Thanks for the quick reply. >>>>>>> >>>>>>> I have added CC: for additional developers per >>>>>>> drivers/platform/x86/wmi.c, >>>>>>> however, this seems to me like hieroglyphs. There is nothing >>>>>>> obvious, but >>>>>>> I had not noticed it with v6.3-rc3? >>>>>>> >>>>>>> Maybe, there seems to be something off: >>>>>>> >>>>>>> 949 static int wmi_dev_probe(struct device *dev) >>>>>>> 950 { >>>>>>> 951 struct wmi_block *wblock = dev_to_wblock(dev); >>>>>>> 952 struct wmi_driver *wdriver = >>>>>>> drv_to_wdrv(dev->driver); >>>>>>> 953 int ret = 0; >>>>>>> 954 char *buf; >>>>>>> 955 >>>>>>> 956 if (ACPI_FAILURE(wmi_method_enable(wblock, true))) >>>>>>> 957 dev_warn(dev, "failed to enable device >>>>>>> -- probing anyway\n"); >>>>>>> 958 >>>>>>> 959 if (wdriver->probe) { >>>>>>> 960 ret = wdriver->probe(dev_to_wdev(dev), >>>>>>> 961 find_guid_context(wblock, wdriver)); >>>>>>> 962 if (ret != 0) >>>>>>> 963 goto probe_failure; >>>>>>> 964 } >>>>>>> 965 >>>>>>> 966 /* driver wants a character device made */ >>>>>>> 967 if (wdriver->filter_callback) { >>>>>>> 968 /* check that required buffer size >>>>>>> declared by driver or MOF */ >>>>>>> 969 if (!wblock->req_buf_size) { >>>>>>> 970 dev_err(&wblock->dev.dev, >>>>>>> 971 "Required buffer size >>>>>>> not set\n"); >>>>>>> 972 ret = -EINVAL; >>>>>>> 973 goto probe_failure; >>>>>>> 974 } >>>>>>> 975 >>>>>>> 976 wblock->handler_data = >>>>>>> kmalloc(wblock->req_buf_size, >>>>>>> 977 GFP_KERNEL); >>>>>>> 978 if (!wblock->handler_data) { >>>>>>> 979 ret = -ENOMEM; >>>>>>> 980 goto probe_failure; >>>>>>> 981 } >>>>>>> 982 >>>>>>> 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", >>>>>>> wdriver->driver.name); >>>>>>> 984 if (!buf) { >>>>>>> 985 ret = -ENOMEM; >>>>>>> 986 goto probe_string_failure; >>>>>>> 987 } >>>>>>> 988 wblock->char_dev.minor = >>>>>>> MISC_DYNAMIC_MINOR; >>>>>>> 989 wblock->char_dev.name = buf; >>>>>>> 990 wblock->char_dev.fops = &wmi_fops; >>>>>>> 991 wblock->char_dev.mode = 0444; >>>>>>> 992 ret = misc_register(&wblock->char_dev); >>>>>>> 993 if (ret) { >>>>>>> 994 dev_warn(dev, "failed to >>>>>>> register char dev: %d\n", ret); >>>>>>> 995 ret = -ENOMEM; >>>>>>> 996 goto probe_misc_failure; >>>>>>> 997 } >>>>>>> 998 } >>>>>>> 999 >>>>>>> 1000 set_bit(WMI_PROBED, &wblock->flags); >>>>>>> 1001 return 0; >>>>>>> 1002 >>>>>>> 1003 probe_misc_failure: >>>>>>> 1004 kfree(buf); >>>>>>> 1005 probe_string_failure: >>>>>>> 1006 kfree(wblock->handler_data); >>>>>>> 1007 probe_failure: >>>>>>> 1008 if (ACPI_FAILURE(wmi_method_enable(wblock, >>>>>>> false))) >>>>>>> 1009 dev_warn(dev, "failed to disable >>>>>>> device\n"); >>>>>>> >>>>>>> >>>>>>> char *buf is passed to kfree(buf) uninitialised if >>>>>>> wdriver->filter_callback >>>>>>> is not set. >>>>>>> >>>>>>> It seems like a logical error per se, but I don't believe this is >>>>>>> the cause >>>>>>> of the leak? >>>>>> >>>>>> CORRECTION: >>>>>> >>>>>> I overlooked the "return 0" in line 1001. >>>>> >>>>> Yeah, and the memory looks to be freed properly in the >>>>> wmi_dev_remove() >>>>> callback, right? >>>> >>>> It would appear so. To verify that: >>>> >>>> Alloc: >>>> 976 wblock->handler_data = kmalloc(wblock->req_buf_size, >>>> GFP_KERNEL); >>>> <check> >>>> >>>> 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", wdriver->driver.name); >>>> <check> >>>> 989 wblock->char_dev.name = buf; >>>> >>>> In lines 1022-1023: >>>> >>>> 1022 kfree(wblock->char_dev.name); >>>> 1023 kfree(wblock->handler_data); >>>> >>>>>> This is why I don't think things should be rushed, but analysed >>>>>> with clear and >>>>>> cold head. And with as many eyes as possible :) >>>>>> >>>>>> The driver stuff is my long-term research interest. To state the >>>>>> obvious, >>>>>> the printing and multimedia education and industry in general >>>>>> would benefit from >>>>>> the open-source drivers for many instruments that still work, but >>>>>> are obsoleted >>>>>> by the producer and require unsupported versions of the OS. >>>>>> >>>>>> Thank you again for reviewing the bug report, however, ATM I do >>>>>> not think I have >>>>>> what it takes to hunt down the memleak. :-/ >>>>> >>>>> Do you have a reproducer that you can use to show the problem better? >>>> >>>> Unfortunately, the problem doesn't seem to appear during the run of >>>> a particular >>>> test, but immediately on startup of the OS. This makes it awkward to >>>> pinpoint the >>>> exact service that triggered memory leaks. But they would appear to >>>> have to do >>>> with the initialisation of the USB devices, wouldn't they? >>>> >>>> There seem to be strings: >>>> >>>> "USBPortAccess,Enabled;[Optional:" >>>> "USBBIOSSupport,Enabled;[Optional" >>>> "USBEnumerationDelay,Disabled;[Op" >>>> >>>> This seems to be happening during USB initialisation and before any >>>> services. >>>> But I might as well be wrong. >>>> >>>>> Or can you test kernel patches to verify the problem is fixed or >>>>> not if >>>>> we send you patches to test? >>>> >>>> Certainly, Lord willing, I can test the patches in the same >>>> environment that >>>> mainfeted the bug (or memleak). >>>> >>>> Best regards, >>>> Mirsad >>>> >> -- Mirsad Todorovac System engineer Faculty of Graphic Arts | Academy of Fine Arts University of Zagreb Republic of Croatia, the European Union Sistem inženjer Grafički fakultet | Akademija likovnih umjetnosti Sveučilište u Zagrebu ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [BUG] [BISECTED] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-29 8:13 ` Mirsad Goran Todorovac @ 2023-03-29 13:22 ` Mirsad Goran Todorovac 2023-03-29 13:31 ` [BUG] [BISECTED] [CORRECTION] " Mirsad Goran Todorovac 0 siblings, 1 reply; 24+ messages in thread From: Mirsad Goran Todorovac @ 2023-03-29 13:22 UTC (permalink / raw) To: Armin Wolf, Greg Kroah-Hartman Cc: Rafael J. Wysocki, linux-kernel, Hans de Goede, Mark Gross, platform-driver-x86, Mark Pearson Hi, Armin, Mr. Greg, On 29.3.2023. 10:13, Mirsad Goran Todorovac wrote: > On 28.3.2023. 21:55, Armin Wolf wrote: >> Am 28.03.23 um 21:06 schrieb Mirsad Goran Todorovac: >> >>> On 3/28/2023 6:53 PM, Armin Wolf wrote: >>>> Am 28.03.23 um 14:44 schrieb Mirsad Todorovac: >>>> >>>>> On 3/28/23 14:17, Greg Kroah-Hartman wrote: >>>>>> On Tue, Mar 28, 2023 at 02:08:06PM +0200, Mirsad Todorovac wrote: >>>>>>> On 3/28/23 13:59, Mirsad Todorovac wrote: >>>>>>> >>>>>>>> On 3/28/23 13:28, Greg Kroah-Hartman wrote: >>>>>>>>> On Tue, Mar 28, 2023 at 01:13:33PM +0200, Mirsad Todorovac wrote: >>>>>>>>>> Hi all, >>>>>>>>>> >>>>>>>>>> Here is another kernel memory leak report, just as I thought we >>>>>>>>>> have done with >>>>>>>>>> them by the xhci patch by Mathias. >>>>>>>>>> >>>>>>>>>> The memory leaks were caught on an AlmaLinux 8.7 (CentOS) fork >>>>>>>>>> system, running >>>>>>>>>> on a Lenovo desktop box (see lshw.txt) and the newest Linux >>>>>>>>>> kernel 6.3-rc4 commit >>>>>>>>>> g3a93e40326c8 with Mathias' patch for a xhci systemd-devd >>>>>>>>>> triggered leak. >>>>>>>>>> >>>>>>>>>> See: >>>>>>>>>> <20230327095019.1017159-1-mathias.nyman@linux.intel.com> on LKML. >>>>>>>>>> >>>>>>>>>> This leak is also systemd-devd triggered, except for the >>>>>>>>>> memstick_check() leaks >>>>>>>>>> which I was unable to bisect due to the box not booting older >>>>>>>>>> kernels (work in >>>>>>>>>> progress). >>>>>>>>>> >>>>>>>>>> unreferenced object 0xffff88ad12392710 (size 96): >>>>>>>>>> comm "systemd-udevd", pid 735, jiffies 4294896759 (age >>>>>>>>>> 2257.568s) >>>>>>>>>> hex dump (first 32 bytes): >>>>>>>>>> 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 >>>>>>>>>> SerialPort1Addre >>>>>>>>>> 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 >>>>>>>>>> ss,3F8/IRQ4;[Opt >>>>>>>>>> backtrace: >>>>>>>>>> [<ffffffffae8fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>>>>>>> [<ffffffffae902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>>>>>>> [<ffffffffae8773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>>>>>>> [<ffffffffae866a1a>] kstrdup+0x3a/0x70 >>>>>>>>>> [<ffffffffc0d839aa>] >>>>>>>>>> tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >>>>>>>>>> [<ffffffffc0d83b64>] tlmi_setting.constprop.4+0x54/0x90 >>>>>>>>>> [think_lmi] >>>>>>>>>> [<ffffffffc0d842b1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>>>>>>> [<ffffffffc051dc53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>>>>>> >>>> Hi, >>>> >>>> this "SerialPort1Address" string looks like a BIOS setup option, and >>>> indeed think_lmi allows for >>>> changing BIOS setup options over sysfs. While looking at >>>> current_value_show() in think-lmi.c, i noticed >>>> that "item" holds a string which is allocated with kstrdup(), so it >>>> has to be freed using kfree(). >>>> This however does not happen if strbrk() fails, so maybe the memory >>>> leak is caused by this? >>>> >>>> Armin Wolf >>> >>> Hi Armin, >>> >>> I tried your suggestion, and though it is an obvious improvement and a >>> leak fix, this >>> was not the one we were searching for. >>> >>> I tested the following patch: >>> >>> diff --git a/drivers/platform/x86/think-lmi.c >>> b/drivers/platform/x86/think-lmi.c >>> index c816646eb661..1e77ecb0cba8 100644 >>> --- a/drivers/platform/x86/think-lmi.c >>> +++ b/drivers/platform/x86/think-lmi.c >>> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject >>> *kobj, struct kobj_attribute *a >>> >>> /* validate and split from `item,value` -> `value` */ >>> value = strpbrk(item, ","); >>> - if (!value || value == item || !strlen(value + 1)) >>> + if (!value || value == item || !strlen(value + 1)) { >>> + kfree(item); >>> return -EINVAL; >>> + } >>> >>> ret = sysfs_emit(buf, "%s\n", value + 1); >>> kfree(item); >>> >>> (I would also object to the use of strlen() here, for it is inherently >>> insecure >>> against SEGFAULT in kernel space.) >>> >>> I still get: >>> [root@pc-mtodorov marvin]# uname -rms >>> Linux 6.3.0-rc4-armin-patch-00025-g3a93e40326c8-dirty x86_64 >>> [root@pc-mtodorov marvin]# cat /sys/kernel/debug/kmemleak [edited] >>> unreferenced object 0xffff8eb008ef9260 (size 96): >>> comm "systemd-udevd", pid 771, jiffies 4294896499 (age 74.880s) >>> hex dump (first 32 bytes): >>> 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 SerialPort1Addre >>> 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 ss,3F8/IRQ4;[Opt >>> backtrace: >>> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >>> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >>> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >>> [think_lmi] >>> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >>> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >>> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >>> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >>> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >>> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >>> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >>> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >>> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >>> unreferenced object 0xffff8eb018ddbb40 (size 64): >>> comm "systemd-udevd", pid 771, jiffies 4294896528 (age 74.780s) >>> hex dump (first 32 bytes): >>> 55 53 42 50 6f 72 74 41 63 63 65 73 73 2c 45 6e USBPortAccess,En >>> 61 62 6c 65 64 3b 5b 4f 70 74 69 6f 6e 61 6c 3a abled;[Optional: >>> backtrace: >>> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >>> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >>> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >>> [think_lmi] >>> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >>> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >>> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >>> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >>> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >>> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >>> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >>> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >>> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >>> unreferenced object 0xffff8eb006fe2b40 (size 64): >>> comm "systemd-udevd", pid 771, jiffies 4294896542 (age 74.724s) >>> hex dump (first 32 bytes): >>> 55 53 42 42 49 4f 53 53 75 70 70 6f 72 74 2c 45 USBBIOSSupport,E >>> 6e 61 62 6c 65 64 3b 5b 4f 70 74 69 6f 6e 61 6c nabled;[Optional >>> backtrace: >>> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >>> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >>> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >>> [think_lmi] >>> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >>> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >>> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >>> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >>> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >>> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >>> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >>> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >>> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >>> >>> There are currently 84 wmi_dev_probe leaks, sized mostly 64 bytes, and >>> one 96 and two 192 bytes. >>> >>> I also cannot figure out the mechanism by which current_value_show() >>> is called, when it is static? >>> >>> Any idea? >>> >>> Thanks. >>> >>> Best regards, >>> Mirsad >>> >> Can you tell me how many BIOS settings think-lmi provides on your machine? Because according to the stacktrace, >> the other place where the leak could have occurred is inside tlmi_analyze(), which calls tlmi_setting(). > > Yes, Sir! > > I think these could be the ones you need (totaling 83, which is close to 82 systemd-udevd leaks): > > [root@pc-mtodorov marvin]# ls -l /sys/devices/virtual/firmware-attributes/thinklmi/attributes | grep ^d > drwxr-xr-x 2 root root 0 Mar 29 08:24 AfterPowerLoss > drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmDate(MM\DD\YYYY) > drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmDayofWeek > drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmTime(HH:MM:SS) > drwxr-xr-x 2 root root 0 Mar 29 08:24 ASPMSupport > drwxr-xr-x 2 root root 0 Mar 29 08:24 AutomaticBootSequence > drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtBootDeviceList > drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtReboot > drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtUnattendedBoot > drwxr-xr-x 2 root root 0 Mar 29 08:24 BootMode > drwxr-xr-x 2 root root 0 Mar 29 08:24 BootPriority > drwxr-xr-x 2 root root 0 Mar 29 08:24 BootUpNum-LockStatus > drwxr-xr-x 2 root root 0 Mar 29 08:24 C1ESupport > drwxr-xr-x 2 root root 0 Mar 29 08:24 CardReader > drwxr-xr-x 2 root root 0 Mar 29 08:24 ClearTCGSecurityFeature > drwxr-xr-x 2 root root 0 Mar 29 08:24 ComputraceModuleActivation > drwxr-xr-x 2 root root 0 Mar 29 08:24 ConfigurationChangeDetection > drwxr-xr-x 2 root root 0 Mar 29 08:24 ConfigureSATAas > drwxr-xr-x 2 root root 0 Mar 29 08:24 CoreMulti-Processing > drwxr-xr-x 2 root root 0 Mar 29 08:24 CoverTamperDetected > drwxr-xr-x 2 root root 0 Mar 29 08:24 CSM > drwxr-xr-x 2 root root 0 Mar 29 08:24 CStateSupport > drwxr-xr-x 2 root root 0 Mar 29 08:24 DeviceGuard > drwxr-xr-x 2 root root 0 Mar 29 08:24 DustShieldAlert > drwxr-xr-x 2 root root 0 Mar 29 08:24 EISTSupport > drwxr-xr-x 2 root root 0 Mar 29 08:24 EnhancedPowerSavingMode > drwxr-xr-x 2 root root 0 Mar 29 08:24 ErrorBootSequence > drwxr-xr-x 2 root root 0 Mar 29 08:24 Friday > drwxr-xr-x 2 root root 0 Mar 29 08:24 FrontUSBPorts > drwxr-xr-x 2 root root 0 Mar 29 08:24 HardDiskPre-delay > drwxr-xr-x 2 root root 0 Mar 29 08:24 Intel(R)SGXControl > drwxr-xr-x 2 root root 0 Mar 29 08:24 InternalSpeaker > drwxr-xr-x 2 root root 0 Mar 29 08:24 Monday > drwxr-xr-x 2 root root 0 Mar 29 08:24 OnboardAudioController > drwxr-xr-x 2 root root 0 Mar 29 08:24 OnboardEthernetController > drwxr-xr-x 2 root root 0 Mar 29 08:24 OptionKeysDisplay > drwxr-xr-x 2 root root 0 Mar 29 08:24 OptionKeysDisplayStyle > drwxr-xr-x 2 root root 0 Mar 29 08:24 OSOptimizedDefaults > drwxr-xr-x 2 root root 0 Mar 29 08:24 PasswordCountExceededError > drwxr-xr-x 2 root root 0 Mar 29 08:24 PCIe16xSlotSpeed > drwxr-xr-x 2 root root 0 Mar 29 08:24 PCIe1xSlot1Speed > drwxr-xr-x 2 root root 0 Mar 29 08:24 PrimaryBootSequence > drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEIPV4NetworkStack > drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEIPV6NetworkStack > drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEOptionROM > drwxr-xr-x 2 root root 0 Mar 29 08:24 RearUSBPorts > drwxr-xr-x 2 root root 0 Mar 29 08:24 RequireAdmin.Pass.whenFlashing > drwxr-xr-x 2 root root 0 Mar 29 08:24 RequireHDPonSystemBoot > drwxr-xr-x 2 root root 0 Mar 29 08:24 SATAController > drwxr-xr-x 2 root root 0 Mar 29 08:24 SATADrive1 > drwxr-xr-x 2 root root 0 Mar 29 08:24 SATADrive2 > drwxr-xr-x 2 root root 0 Mar 29 08:24 Saturday > drwxr-xr-x 2 root root 0 Mar 29 08:24 SecureBoot > drwxr-xr-x 2 root root 0 Mar 29 08:24 SecureRollBackPrevention > drwxr-xr-x 2 root root 0 Mar 29 08:24 SecurityChip > drwxr-xr-x 2 root root 0 Mar 29 08:24 SelectActiveVideo > drwxr-xr-x 2 root root 0 Mar 29 08:24 SerialPort1Address > drwxr-xr-x 2 root root 0 Mar 29 08:24 SmartUSBProtection > drwxr-xr-x 2 root root 0 Mar 29 08:24 StartupDeviceMenuPrompt > drwxr-xr-x 2 root root 0 Mar 29 08:24 StartupSequence > drwxr-xr-x 2 root root 0 Mar 29 08:24 Sunday > drwxr-xr-x 2 root root 0 Mar 29 08:24 Thursday > drwxr-xr-x 2 root root 0 Mar 29 08:24 Tuesday > drwxr-xr-x 2 root root 0 Mar 29 08:24 TurboMode > drwxr-xr-x 2 root root 0 Mar 29 08:24 USBBIOSSupport > drwxr-xr-x 2 root root 0 Mar 29 08:24 USBEnumerationDelay > drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort1 > drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort2 > drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort3 > drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort4 > drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort5 > drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort6 > drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort7 > drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort8 > drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPortAccess > drwxr-xr-x 2 root root 0 Mar 29 08:24 UserDefinedAlarmTime(HH:MM:SS) > drwxr-xr-x 2 root root 0 Mar 29 08:24 VirtualizationTechnology > drwxr-xr-x 2 root root 0 Mar 29 08:24 VTdFeature > drwxr-xr-x 2 root root 0 Mar 29 08:24 WakefromSerialPortRing > drwxr-xr-x 2 root root 0 Mar 29 08:24 WakeOnLAN > drwxr-xr-x 2 root root 0 Mar 29 08:24 WakeUponAlarm > drwxr-xr-x 2 root root 0 Mar 29 08:24 Wednesday > drwxr-xr-x 2 root root 0 Mar 29 08:24 WindowsUEFIFirmwareUpdate > [root@pc-mtodorov marvin]# ls -l /sys/devices/virtual/firmware-attributes/thinklmi/attributes | grep ^d | wc -l > 83 > [root@pc-mtodorov marvin]# > >> However, i have no idea on how *info is somehow leaked, it has to happen inside the for-loop tween the call >> to tlmi_setting() and strreplace(), because otherwise the strings would not contain the "/" character. > > I see. It is the line 1404. > >> Can you check if the problem is somehow solved by applying the following commit from the platform-drivers-x86 >> for-next branch: >> da62908efe80 ("platform/x86: think-lmi: Properly interpret return value of tlmi_setting") > > It could possibly be that. But I do not recall seeing these messages in 6.3-rc3 ... > > ... > > Unfortunately, the build with Thomas' patch you referred to did not work: > > unreferenced object 0xffff9dff4d28bbc8 (size 192): > comm "systemd-udevd", pid 769, jiffies 4294897473 (age 85.700s) > hex dump (first 32 bytes): > 50 72 69 6d 61 72 79 42 6f 6f 74 53 65 71 75 65 PrimaryBootSeque > 6e 63 65 2c 4d 2e 32 20 44 72 69 76 65 20 31 3a nce,M.2 Drive 1: > backtrace: > [<ffffffffa48fb26c>] slab_post_alloc_hook+0x8c/0x3e0 > [<ffffffffa4902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 > [<ffffffffa48773c9>] __kmalloc_node_track_caller+0x59/0x180 > [<ffffffffa4866a1a>] kstrdup+0x3a/0x70 > [<ffffffffc0c7f9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] > [<ffffffffc0c7fb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] > [<ffffffffc0c802c1>] tlmi_probe+0x591/0xba0 [think_lmi] > [<ffffffffc03c9c53>] wmi_dev_probe+0x163/0x230 [wmi] > [<ffffffffa4f987eb>] really_probe+0x17b/0x3d0 > [<ffffffffa4f98ad4>] __driver_probe_device+0x84/0x190 > [<ffffffffa4f98c14>] driver_probe_device+0x24/0xc0 > [<ffffffffa4f98ed2>] __driver_attach+0xc2/0x190 > [<ffffffffa4f95ab1>] bus_for_each_dev+0x81/0xd0 > [<ffffffffa4f97c62>] driver_attach+0x22/0x30 > [<ffffffffa4f97354>] bus_add_driver+0x1b4/0x240 > [<ffffffffa4f9a0a2>] driver_register+0x62/0x120 > unreferenced object 0xffff9dff4d28a008 (size 192): > comm "systemd-udevd", pid 769, jiffies 4294897517 (age 85.540s) > hex dump (first 32 bytes): > 45 72 72 6f 72 42 6f 6f 74 53 65 71 75 65 6e 63 ErrorBootSequenc > 65 2c 4e 65 74 77 6f 72 6b 20 31 3a 4d 2e 32 20 e,Network 1:M.2 > backtrace: > [<ffffffffa48fb26c>] slab_post_alloc_hook+0x8c/0x3e0 > [<ffffffffa4902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 > [<ffffffffa48773c9>] __kmalloc_node_track_caller+0x59/0x180 > [<ffffffffa4866a1a>] kstrdup+0x3a/0x70 > [<ffffffffc0c7f9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] > [<ffffffffc0c7fb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] > [<ffffffffc0c802c1>] tlmi_probe+0x591/0xba0 [think_lmi] > [<ffffffffc03c9c53>] wmi_dev_probe+0x163/0x230 [wmi] > [<ffffffffa4f987eb>] really_probe+0x17b/0x3d0 > [<ffffffffa4f98ad4>] __driver_probe_device+0x84/0x190 > [<ffffffffa4f98c14>] driver_probe_device+0x24/0xc0 > [<ffffffffa4f98ed2>] __driver_attach+0xc2/0x190 > [<ffffffffa4f95ab1>] bus_for_each_dev+0x81/0xd0 > [<ffffffffa4f97c62>] driver_attach+0x22/0x30 > [<ffffffffa4f97354>] bus_add_driver+0x1b4/0x240 > [<ffffffffa4f9a0a2>] driver_register+0x62/0x120 > [root@pc-mtodorov marvin]# uname -rms > Linux 6.3.0-rc4-armin+tw-patch-00025-g3a93e40326c8-dirty x86_64 > [root@pc-mtodorov marvin]# > > What was applied is: > > mtodorov@domac:~/linux/kernel/linux_torvalds$ git diff > diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c > index c816646eb661..9a3015f43aaf 100644 > --- a/drivers/platform/x86/think-lmi.c > +++ b/drivers/platform/x86/think-lmi.c > @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a > > /* validate and split from `item,value` -> `value` */ > value = strpbrk(item, ","); > - if (!value || value == item || !strlen(value + 1)) > + if (!value || value == item || !strlen(value + 1)) { > + kfree(item); > return -EINVAL; > + } > > ret = sysfs_emit(buf, "%s\n", value + 1); > kfree(item); > @@ -1380,7 +1382,6 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type, > > static int tlmi_analyze(void) > { > - acpi_status status; > int i, ret; > > if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && > @@ -1417,8 +1418,8 @@ static int tlmi_analyze(void) > char *p; > > tlmi_priv.setting[i] = NULL; > - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); > - if (ACPI_FAILURE(status)) > + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); > + if (ret) > break; > if (!item) > break; > > >> Also current_value_show() is used by attr_current_val, the __ATTR_RW_MODE() macro arranges for that. > > Thanks. > > In this build: > > [root@pc-mtodorov marvin]# uname -rms > Linux 6.3.0-rc34tests-00001-g6981739a967c x86_64 > [root@pc-mtodorov marvin]# > > ... the bug isn't present, so it might be something added recently: > > commit 8a02d70679fc1c434401863333c8ea7dbf201494 > Author: Mark Pearson <mpearson-lenovo@squebb.ca> > Date: Sun Mar 19 20:32:21 2023 -0400 > > platform/x86: think-lmi: Add possible_values for ThinkStation > > commit cf337f27f3bfc4aeab4954c468239fd6233c7638 > Author: Mark Pearson <mpearson-lenovo@squebb.ca> > Date: Sun Mar 19 20:32:20 2023 -0400 > > platform/x86: think-lmi: only display possible_values if available > > commit 45e21289bfc6e257885514790a8a8887da822d40 > Author: Mark Pearson <mpearson-lenovo@squebb.ca> > Date: Sun Mar 19 20:32:19 2023 -0400 > > platform/x86: think-lmi: use correct possible_values delimiters > > commit 583329dcf22e568a328a944f20427ccfc95dce01 > Author: Mark Pearson <mpearson-lenovo@squebb.ca> > Date: Sun Mar 19 20:32:18 2023 -0400 > > platform/x86: think-lmi: add missing type attribute > > I have CC:-ed the author of the commits. > > I can try bisect, but only after my day job. I seem to have been right about the culprit commit. Here is the bisect log: mtodorov@domac:~/linux/kernel/linux_torvalds$ git bisect log git bisect start '--' './drivers/platform/x86' # good: [caa0708a81d6a2217c942959ef40d515ec1d3108] bootconfig: Change message if no bootconfig with CONFIG_BOOT_CONFIG_FORCE=y git bisect good caa0708a81d6a2217c942959ef40d515ec1d3108 # bad: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation git bisect bad 8a02d70679fc1c434401863333c8ea7dbf201494 # good: [1a0009abfa7893b9cfcd3884658af1cbee6b26ce] platform: mellanox: mlx-platform: Initialize shift variable to 0 git bisect good 1a0009abfa7893b9cfcd3884658af1cbee6b26ce # good: [b7c994f8c35e916e27c60803bb21457bc1373500] platform/x86 (gigabyte-wmi): Add support for A320M-S2H V2 git bisect good b7c994f8c35e916e27c60803bb21457bc1373500 # good: [45e21289bfc6e257885514790a8a8887da822d40] platform/x86: think-lmi: use correct possible_values delimiters git bisect good 45e21289bfc6e257885514790a8a8887da822d40 # good: [cf337f27f3bfc4aeab4954c468239fd6233c7638] platform/x86: think-lmi: only display possible_values if available git bisect good cf337f27f3bfc4aeab4954c468239fd6233c7638 # first bad commit: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation mtodorov@domac:~/linux/kernel/linux_torvalds$ Please see below. Apparently, this commit broke something on my Lenovo box: diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index e190fec26021..3f0641360251 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -941,9 +941,6 @@ static ssize_t possible_values_show(struct kobject *kobj, struct kobj_attribute { struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); - if (!tlmi_priv.can_get_bios_selections) - return -EOPNOTSUPP; - return sysfs_emit(buf, "%s\n", setting->possible_values); } @@ -1052,6 +1049,18 @@ static struct kobj_attribute attr_current_val = __ATTR_RW_MODE(current_value, 06 static struct kobj_attribute attr_type = __ATTR_RO(type); +static umode_t attr_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); + + /* We don't want to display possible_values attributes if not available */ + if ((attr == &attr_possible_values.attr) && (!setting->possible_values)) + return 0; + + return attr->mode; +} + static struct attribute *tlmi_attrs[] = { &attr_displ_name.attr, &attr_current_val.attr, @@ -1061,6 +1070,7 @@ static struct attribute *tlmi_attrs[] = { }; static const struct attribute_group tlmi_attr_group = { + .is_visible = attr_is_visible, .attrs = tlmi_attrs, }; Hope this helps narrow down the problem. Best regards, Mirsad >>>>>>>>> Why aren't you looking at the wmi.c driver? That should be >>>>>>>>> where the >>>>>>>>> issue is, not the driver core, right? >>>>>>>>> >>>>>>>>> thanks, >>>>>>>>> >>>>>>>>> greg k-h >>>>>>>> >>>>>>>> Hi, Mr. Greg, >>>>>>>> >>>>>>>> Thanks for the quick reply. >>>>>>>> >>>>>>>> I have added CC: for additional developers per >>>>>>>> drivers/platform/x86/wmi.c, >>>>>>>> however, this seems to me like hieroglyphs. There is nothing >>>>>>>> obvious, but >>>>>>>> I had not noticed it with v6.3-rc3? >>>>>>>> >>>>>>>> Maybe, there seems to be something off: >>>>>>>> >>>>>>>> 949 static int wmi_dev_probe(struct device *dev) >>>>>>>> 950 { >>>>>>>> 951 struct wmi_block *wblock = dev_to_wblock(dev); >>>>>>>> 952 struct wmi_driver *wdriver = >>>>>>>> drv_to_wdrv(dev->driver); >>>>>>>> 953 int ret = 0; >>>>>>>> 954 char *buf; >>>>>>>> 955 >>>>>>>> 956 if (ACPI_FAILURE(wmi_method_enable(wblock, true))) >>>>>>>> 957 dev_warn(dev, "failed to enable device >>>>>>>> -- probing anyway\n"); >>>>>>>> 958 >>>>>>>> 959 if (wdriver->probe) { >>>>>>>> 960 ret = wdriver->probe(dev_to_wdev(dev), >>>>>>>> 961 find_guid_context(wblock, wdriver)); >>>>>>>> 962 if (ret != 0) >>>>>>>> 963 goto probe_failure; >>>>>>>> 964 } >>>>>>>> 965 >>>>>>>> 966 /* driver wants a character device made */ >>>>>>>> 967 if (wdriver->filter_callback) { >>>>>>>> 968 /* check that required buffer size >>>>>>>> declared by driver or MOF */ >>>>>>>> 969 if (!wblock->req_buf_size) { >>>>>>>> 970 dev_err(&wblock->dev.dev, >>>>>>>> 971 "Required buffer size >>>>>>>> not set\n"); >>>>>>>> 972 ret = -EINVAL; >>>>>>>> 973 goto probe_failure; >>>>>>>> 974 } >>>>>>>> 975 >>>>>>>> 976 wblock->handler_data = >>>>>>>> kmalloc(wblock->req_buf_size, >>>>>>>> 977 GFP_KERNEL); >>>>>>>> 978 if (!wblock->handler_data) { >>>>>>>> 979 ret = -ENOMEM; >>>>>>>> 980 goto probe_failure; >>>>>>>> 981 } >>>>>>>> 982 >>>>>>>> 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", >>>>>>>> wdriver->driver.name); >>>>>>>> 984 if (!buf) { >>>>>>>> 985 ret = -ENOMEM; >>>>>>>> 986 goto probe_string_failure; >>>>>>>> 987 } >>>>>>>> 988 wblock->char_dev.minor = >>>>>>>> MISC_DYNAMIC_MINOR; >>>>>>>> 989 wblock->char_dev.name = buf; >>>>>>>> 990 wblock->char_dev.fops = &wmi_fops; >>>>>>>> 991 wblock->char_dev.mode = 0444; >>>>>>>> 992 ret = misc_register(&wblock->char_dev); >>>>>>>> 993 if (ret) { >>>>>>>> 994 dev_warn(dev, "failed to >>>>>>>> register char dev: %d\n", ret); >>>>>>>> 995 ret = -ENOMEM; >>>>>>>> 996 goto probe_misc_failure; >>>>>>>> 997 } >>>>>>>> 998 } >>>>>>>> 999 >>>>>>>> 1000 set_bit(WMI_PROBED, &wblock->flags); >>>>>>>> 1001 return 0; >>>>>>>> 1002 >>>>>>>> 1003 probe_misc_failure: >>>>>>>> 1004 kfree(buf); >>>>>>>> 1005 probe_string_failure: >>>>>>>> 1006 kfree(wblock->handler_data); >>>>>>>> 1007 probe_failure: >>>>>>>> 1008 if (ACPI_FAILURE(wmi_method_enable(wblock, >>>>>>>> false))) >>>>>>>> 1009 dev_warn(dev, "failed to disable >>>>>>>> device\n"); >>>>>>>> >>>>>>>> >>>>>>>> char *buf is passed to kfree(buf) uninitialised if >>>>>>>> wdriver->filter_callback >>>>>>>> is not set. >>>>>>>> >>>>>>>> It seems like a logical error per se, but I don't believe this is >>>>>>>> the cause >>>>>>>> of the leak? >>>>>>> >>>>>>> CORRECTION: >>>>>>> >>>>>>> I overlooked the "return 0" in line 1001. >>>>>> >>>>>> Yeah, and the memory looks to be freed properly in the >>>>>> wmi_dev_remove() >>>>>> callback, right? >>>>> >>>>> It would appear so. To verify that: >>>>> >>>>> Alloc: >>>>> 976 wblock->handler_data = kmalloc(wblock->req_buf_size, >>>>> GFP_KERNEL); >>>>> <check> >>>>> >>>>> 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", wdriver->driver.name); >>>>> <check> >>>>> 989 wblock->char_dev.name = buf; >>>>> >>>>> In lines 1022-1023: >>>>> >>>>> 1022 kfree(wblock->char_dev.name); >>>>> 1023 kfree(wblock->handler_data); >>>>> >>>>>>> This is why I don't think things should be rushed, but analysed >>>>>>> with clear and >>>>>>> cold head. And with as many eyes as possible :) >>>>>>> >>>>>>> The driver stuff is my long-term research interest. To state the >>>>>>> obvious, >>>>>>> the printing and multimedia education and industry in general >>>>>>> would benefit from >>>>>>> the open-source drivers for many instruments that still work, but >>>>>>> are obsoleted >>>>>>> by the producer and require unsupported versions of the OS. >>>>>>> >>>>>>> Thank you again for reviewing the bug report, however, ATM I do >>>>>>> not think I have >>>>>>> what it takes to hunt down the memleak. :-/ >>>>>> >>>>>> Do you have a reproducer that you can use to show the problem better? >>>>> >>>>> Unfortunately, the problem doesn't seem to appear during the run of >>>>> a particular >>>>> test, but immediately on startup of the OS. This makes it awkward to >>>>> pinpoint the >>>>> exact service that triggered memory leaks. But they would appear to >>>>> have to do >>>>> with the initialisation of the USB devices, wouldn't they? >>>>> >>>>> There seem to be strings: >>>>> >>>>> "USBPortAccess,Enabled;[Optional:" >>>>> "USBBIOSSupport,Enabled;[Optional" >>>>> "USBEnumerationDelay,Disabled;[Op" >>>>> >>>>> This seems to be happening during USB initialisation and before any >>>>> services. >>>>> But I might as well be wrong. >>>>> >>>>>> Or can you test kernel patches to verify the problem is fixed or >>>>>> not if >>>>>> we send you patches to test? >>>>> >>>>> Certainly, Lord willing, I can test the patches in the same >>>>> environment that >>>>> mainfeted the bug (or memleak). -- Mirsad Todorovac System engineer Faculty of Graphic Arts | Academy of Fine Arts University of Zagreb Republic of Croatia, the European Union Sistem inženjer Grafički fakultet | Akademija likovnih umjetnosti Sveučilište u Zagrebu ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [BUG] [BISECTED] [CORRECTION] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-29 13:22 ` [BUG] [BISECTED] " Mirsad Goran Todorovac @ 2023-03-29 13:31 ` Mirsad Goran Todorovac 2023-03-29 13:35 ` Thomas Weißschuh 0 siblings, 1 reply; 24+ messages in thread From: Mirsad Goran Todorovac @ 2023-03-29 13:31 UTC (permalink / raw) To: Armin Wolf, Greg Kroah-Hartman Cc: Rafael J. Wysocki, linux-kernel, Hans de Goede, Mark Gross, platform-driver-x86, Mark Pearson Hi, again, NOTE: I forgot to rewind to the first bad commit. So please ignore the previous email. On 29.3.2023. 15:22, Mirsad Goran Todorovac wrote: > Hi, Armin, Mr. Greg, > > On 29.3.2023. 10:13, Mirsad Goran Todorovac wrote: >> On 28.3.2023. 21:55, Armin Wolf wrote: >>> Am 28.03.23 um 21:06 schrieb Mirsad Goran Todorovac: >>> >>>> On 3/28/2023 6:53 PM, Armin Wolf wrote: >>>>> Am 28.03.23 um 14:44 schrieb Mirsad Todorovac: >>>>> >>>>>> On 3/28/23 14:17, Greg Kroah-Hartman wrote: >>>>>>> On Tue, Mar 28, 2023 at 02:08:06PM +0200, Mirsad Todorovac wrote: >>>>>>>> On 3/28/23 13:59, Mirsad Todorovac wrote: >>>>>>>> >>>>>>>>> On 3/28/23 13:28, Greg Kroah-Hartman wrote: >>>>>>>>>> On Tue, Mar 28, 2023 at 01:13:33PM +0200, Mirsad Todorovac wrote: >>>>>>>>>>> Hi all, >>>>>>>>>>> >>>>>>>>>>> Here is another kernel memory leak report, just as I thought we >>>>>>>>>>> have done with >>>>>>>>>>> them by the xhci patch by Mathias. >>>>>>>>>>> >>>>>>>>>>> The memory leaks were caught on an AlmaLinux 8.7 (CentOS) fork >>>>>>>>>>> system, running >>>>>>>>>>> on a Lenovo desktop box (see lshw.txt) and the newest Linux >>>>>>>>>>> kernel 6.3-rc4 commit >>>>>>>>>>> g3a93e40326c8 with Mathias' patch for a xhci systemd-devd >>>>>>>>>>> triggered leak. >>>>>>>>>>> >>>>>>>>>>> See: >>>>>>>>>>> <20230327095019.1017159-1-mathias.nyman@linux.intel.com> on LKML. >>>>>>>>>>> >>>>>>>>>>> This leak is also systemd-devd triggered, except for the >>>>>>>>>>> memstick_check() leaks >>>>>>>>>>> which I was unable to bisect due to the box not booting older >>>>>>>>>>> kernels (work in >>>>>>>>>>> progress). >>>>>>>>>>> >>>>>>>>>>> unreferenced object 0xffff88ad12392710 (size 96): >>>>>>>>>>> comm "systemd-udevd", pid 735, jiffies 4294896759 (age >>>>>>>>>>> 2257.568s) >>>>>>>>>>> hex dump (first 32 bytes): >>>>>>>>>>> 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 >>>>>>>>>>> SerialPort1Addre >>>>>>>>>>> 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 >>>>>>>>>>> ss,3F8/IRQ4;[Opt >>>>>>>>>>> backtrace: >>>>>>>>>>> [<ffffffffae8fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>>>>>>>> [<ffffffffae902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>>>>>>>> [<ffffffffae8773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>>>>>>>> [<ffffffffae866a1a>] kstrdup+0x3a/0x70 >>>>>>>>>>> [<ffffffffc0d839aa>] >>>>>>>>>>> tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >>>>>>>>>>> [<ffffffffc0d83b64>] tlmi_setting.constprop.4+0x54/0x90 >>>>>>>>>>> [think_lmi] >>>>>>>>>>> [<ffffffffc0d842b1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>>>>>>>> [<ffffffffc051dc53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>>>>>>> >>>>> Hi, >>>>> >>>>> this "SerialPort1Address" string looks like a BIOS setup option, and >>>>> indeed think_lmi allows for >>>>> changing BIOS setup options over sysfs. While looking at >>>>> current_value_show() in think-lmi.c, i noticed >>>>> that "item" holds a string which is allocated with kstrdup(), so it >>>>> has to be freed using kfree(). >>>>> This however does not happen if strbrk() fails, so maybe the memory >>>>> leak is caused by this? >>>>> >>>>> Armin Wolf >>>> >>>> Hi Armin, >>>> >>>> I tried your suggestion, and though it is an obvious improvement and a >>>> leak fix, this >>>> was not the one we were searching for. >>>> >>>> I tested the following patch: >>>> >>>> diff --git a/drivers/platform/x86/think-lmi.c >>>> b/drivers/platform/x86/think-lmi.c >>>> index c816646eb661..1e77ecb0cba8 100644 >>>> --- a/drivers/platform/x86/think-lmi.c >>>> +++ b/drivers/platform/x86/think-lmi.c >>>> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject >>>> *kobj, struct kobj_attribute *a >>>> >>>> /* validate and split from `item,value` -> `value` */ >>>> value = strpbrk(item, ","); >>>> - if (!value || value == item || !strlen(value + 1)) >>>> + if (!value || value == item || !strlen(value + 1)) { >>>> + kfree(item); >>>> return -EINVAL; >>>> + } >>>> >>>> ret = sysfs_emit(buf, "%s\n", value + 1); >>>> kfree(item); >>>> >>>> (I would also object to the use of strlen() here, for it is inherently >>>> insecure >>>> against SEGFAULT in kernel space.) >>>> >>>> I still get: >>>> [root@pc-mtodorov marvin]# uname -rms >>>> Linux 6.3.0-rc4-armin-patch-00025-g3a93e40326c8-dirty x86_64 >>>> [root@pc-mtodorov marvin]# cat /sys/kernel/debug/kmemleak [edited] >>>> unreferenced object 0xffff8eb008ef9260 (size 96): >>>> comm "systemd-udevd", pid 771, jiffies 4294896499 (age 74.880s) >>>> hex dump (first 32 bytes): >>>> 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 SerialPort1Addre >>>> 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 ss,3F8/IRQ4;[Opt >>>> backtrace: >>>> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >>>> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >>>> [think_lmi] >>>> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >>>> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >>>> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >>>> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >>>> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >>>> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >>>> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >>>> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >>>> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >>>> unreferenced object 0xffff8eb018ddbb40 (size 64): >>>> comm "systemd-udevd", pid 771, jiffies 4294896528 (age 74.780s) >>>> hex dump (first 32 bytes): >>>> 55 53 42 50 6f 72 74 41 63 63 65 73 73 2c 45 6e USBPortAccess,En >>>> 61 62 6c 65 64 3b 5b 4f 70 74 69 6f 6e 61 6c 3a abled;[Optional: >>>> backtrace: >>>> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >>>> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >>>> [think_lmi] >>>> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >>>> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >>>> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >>>> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >>>> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >>>> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >>>> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >>>> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >>>> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >>>> unreferenced object 0xffff8eb006fe2b40 (size 64): >>>> comm "systemd-udevd", pid 771, jiffies 4294896542 (age 74.724s) >>>> hex dump (first 32 bytes): >>>> 55 53 42 42 49 4f 53 53 75 70 70 6f 72 74 2c 45 USBBIOSSupport,E >>>> 6e 61 62 6c 65 64 3b 5b 4f 70 74 69 6f 6e 61 6c nabled;[Optional >>>> backtrace: >>>> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >>>> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >>>> [think_lmi] >>>> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >>>> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >>>> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >>>> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >>>> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >>>> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >>>> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >>>> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >>>> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >>>> >>>> There are currently 84 wmi_dev_probe leaks, sized mostly 64 bytes, and >>>> one 96 and two 192 bytes. >>>> >>>> I also cannot figure out the mechanism by which current_value_show() >>>> is called, when it is static? >>>> >>>> Any idea? >>>> >>>> Thanks. >>>> >>>> Best regards, >>>> Mirsad >>>> >>> Can you tell me how many BIOS settings think-lmi provides on your machine? Because according to the stacktrace, >>> the other place where the leak could have occurred is inside tlmi_analyze(), which calls tlmi_setting(). >> >> Yes, Sir! >> >> I think these could be the ones you need (totaling 83, which is close to 82 systemd-udevd leaks): >> >> [root@pc-mtodorov marvin]# ls -l /sys/devices/virtual/firmware-attributes/thinklmi/attributes | grep ^d >> drwxr-xr-x 2 root root 0 Mar 29 08:24 AfterPowerLoss >> drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmDate(MM\DD\YYYY) >> drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmDayofWeek >> drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmTime(HH:MM:SS) >> drwxr-xr-x 2 root root 0 Mar 29 08:24 ASPMSupport >> drwxr-xr-x 2 root root 0 Mar 29 08:24 AutomaticBootSequence >> drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtBootDeviceList >> drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtReboot >> drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtUnattendedBoot >> drwxr-xr-x 2 root root 0 Mar 29 08:24 BootMode >> drwxr-xr-x 2 root root 0 Mar 29 08:24 BootPriority >> drwxr-xr-x 2 root root 0 Mar 29 08:24 BootUpNum-LockStatus >> drwxr-xr-x 2 root root 0 Mar 29 08:24 C1ESupport >> drwxr-xr-x 2 root root 0 Mar 29 08:24 CardReader >> drwxr-xr-x 2 root root 0 Mar 29 08:24 ClearTCGSecurityFeature >> drwxr-xr-x 2 root root 0 Mar 29 08:24 ComputraceModuleActivation >> drwxr-xr-x 2 root root 0 Mar 29 08:24 ConfigurationChangeDetection >> drwxr-xr-x 2 root root 0 Mar 29 08:24 ConfigureSATAas >> drwxr-xr-x 2 root root 0 Mar 29 08:24 CoreMulti-Processing >> drwxr-xr-x 2 root root 0 Mar 29 08:24 CoverTamperDetected >> drwxr-xr-x 2 root root 0 Mar 29 08:24 CSM >> drwxr-xr-x 2 root root 0 Mar 29 08:24 CStateSupport >> drwxr-xr-x 2 root root 0 Mar 29 08:24 DeviceGuard >> drwxr-xr-x 2 root root 0 Mar 29 08:24 DustShieldAlert >> drwxr-xr-x 2 root root 0 Mar 29 08:24 EISTSupport >> drwxr-xr-x 2 root root 0 Mar 29 08:24 EnhancedPowerSavingMode >> drwxr-xr-x 2 root root 0 Mar 29 08:24 ErrorBootSequence >> drwxr-xr-x 2 root root 0 Mar 29 08:24 Friday >> drwxr-xr-x 2 root root 0 Mar 29 08:24 FrontUSBPorts >> drwxr-xr-x 2 root root 0 Mar 29 08:24 HardDiskPre-delay >> drwxr-xr-x 2 root root 0 Mar 29 08:24 Intel(R)SGXControl >> drwxr-xr-x 2 root root 0 Mar 29 08:24 InternalSpeaker >> drwxr-xr-x 2 root root 0 Mar 29 08:24 Monday >> drwxr-xr-x 2 root root 0 Mar 29 08:24 OnboardAudioController >> drwxr-xr-x 2 root root 0 Mar 29 08:24 OnboardEthernetController >> drwxr-xr-x 2 root root 0 Mar 29 08:24 OptionKeysDisplay >> drwxr-xr-x 2 root root 0 Mar 29 08:24 OptionKeysDisplayStyle >> drwxr-xr-x 2 root root 0 Mar 29 08:24 OSOptimizedDefaults >> drwxr-xr-x 2 root root 0 Mar 29 08:24 PasswordCountExceededError >> drwxr-xr-x 2 root root 0 Mar 29 08:24 PCIe16xSlotSpeed >> drwxr-xr-x 2 root root 0 Mar 29 08:24 PCIe1xSlot1Speed >> drwxr-xr-x 2 root root 0 Mar 29 08:24 PrimaryBootSequence >> drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEIPV4NetworkStack >> drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEIPV6NetworkStack >> drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEOptionROM >> drwxr-xr-x 2 root root 0 Mar 29 08:24 RearUSBPorts >> drwxr-xr-x 2 root root 0 Mar 29 08:24 RequireAdmin.Pass.whenFlashing >> drwxr-xr-x 2 root root 0 Mar 29 08:24 RequireHDPonSystemBoot >> drwxr-xr-x 2 root root 0 Mar 29 08:24 SATAController >> drwxr-xr-x 2 root root 0 Mar 29 08:24 SATADrive1 >> drwxr-xr-x 2 root root 0 Mar 29 08:24 SATADrive2 >> drwxr-xr-x 2 root root 0 Mar 29 08:24 Saturday >> drwxr-xr-x 2 root root 0 Mar 29 08:24 SecureBoot >> drwxr-xr-x 2 root root 0 Mar 29 08:24 SecureRollBackPrevention >> drwxr-xr-x 2 root root 0 Mar 29 08:24 SecurityChip >> drwxr-xr-x 2 root root 0 Mar 29 08:24 SelectActiveVideo >> drwxr-xr-x 2 root root 0 Mar 29 08:24 SerialPort1Address >> drwxr-xr-x 2 root root 0 Mar 29 08:24 SmartUSBProtection >> drwxr-xr-x 2 root root 0 Mar 29 08:24 StartupDeviceMenuPrompt >> drwxr-xr-x 2 root root 0 Mar 29 08:24 StartupSequence >> drwxr-xr-x 2 root root 0 Mar 29 08:24 Sunday >> drwxr-xr-x 2 root root 0 Mar 29 08:24 Thursday >> drwxr-xr-x 2 root root 0 Mar 29 08:24 Tuesday >> drwxr-xr-x 2 root root 0 Mar 29 08:24 TurboMode >> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBBIOSSupport >> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBEnumerationDelay >> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort1 >> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort2 >> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort3 >> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort4 >> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort5 >> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort6 >> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort7 >> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort8 >> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPortAccess >> drwxr-xr-x 2 root root 0 Mar 29 08:24 UserDefinedAlarmTime(HH:MM:SS) >> drwxr-xr-x 2 root root 0 Mar 29 08:24 VirtualizationTechnology >> drwxr-xr-x 2 root root 0 Mar 29 08:24 VTdFeature >> drwxr-xr-x 2 root root 0 Mar 29 08:24 WakefromSerialPortRing >> drwxr-xr-x 2 root root 0 Mar 29 08:24 WakeOnLAN >> drwxr-xr-x 2 root root 0 Mar 29 08:24 WakeUponAlarm >> drwxr-xr-x 2 root root 0 Mar 29 08:24 Wednesday >> drwxr-xr-x 2 root root 0 Mar 29 08:24 WindowsUEFIFirmwareUpdate >> [root@pc-mtodorov marvin]# ls -l /sys/devices/virtual/firmware-attributes/thinklmi/attributes | grep ^d | wc -l >> 83 >> [root@pc-mtodorov marvin]# >> >>> However, i have no idea on how *info is somehow leaked, it has to happen inside the for-loop tween the call >>> to tlmi_setting() and strreplace(), because otherwise the strings would not contain the "/" character. >> >> I see. It is the line 1404. >> >>> Can you check if the problem is somehow solved by applying the following commit from the platform-drivers-x86 >>> for-next branch: >>> da62908efe80 ("platform/x86: think-lmi: Properly interpret return value of tlmi_setting") >> >> It could possibly be that. But I do not recall seeing these messages in 6.3-rc3 ... >> >> ... >> >> Unfortunately, the build with Thomas' patch you referred to did not work: >> >> unreferenced object 0xffff9dff4d28bbc8 (size 192): >> comm "systemd-udevd", pid 769, jiffies 4294897473 (age 85.700s) >> hex dump (first 32 bytes): >> 50 72 69 6d 61 72 79 42 6f 6f 74 53 65 71 75 65 PrimaryBootSeque >> 6e 63 65 2c 4d 2e 32 20 44 72 69 76 65 20 31 3a nce,M.2 Drive 1: >> backtrace: >> [<ffffffffa48fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >> [<ffffffffa4902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >> [<ffffffffa48773c9>] __kmalloc_node_track_caller+0x59/0x180 >> [<ffffffffa4866a1a>] kstrdup+0x3a/0x70 >> [<ffffffffc0c7f9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >> [<ffffffffc0c7fb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >> [<ffffffffc0c802c1>] tlmi_probe+0x591/0xba0 [think_lmi] >> [<ffffffffc03c9c53>] wmi_dev_probe+0x163/0x230 [wmi] >> [<ffffffffa4f987eb>] really_probe+0x17b/0x3d0 >> [<ffffffffa4f98ad4>] __driver_probe_device+0x84/0x190 >> [<ffffffffa4f98c14>] driver_probe_device+0x24/0xc0 >> [<ffffffffa4f98ed2>] __driver_attach+0xc2/0x190 >> [<ffffffffa4f95ab1>] bus_for_each_dev+0x81/0xd0 >> [<ffffffffa4f97c62>] driver_attach+0x22/0x30 >> [<ffffffffa4f97354>] bus_add_driver+0x1b4/0x240 >> [<ffffffffa4f9a0a2>] driver_register+0x62/0x120 >> unreferenced object 0xffff9dff4d28a008 (size 192): >> comm "systemd-udevd", pid 769, jiffies 4294897517 (age 85.540s) >> hex dump (first 32 bytes): >> 45 72 72 6f 72 42 6f 6f 74 53 65 71 75 65 6e 63 ErrorBootSequenc >> 65 2c 4e 65 74 77 6f 72 6b 20 31 3a 4d 2e 32 20 e,Network 1:M.2 >> backtrace: >> [<ffffffffa48fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >> [<ffffffffa4902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >> [<ffffffffa48773c9>] __kmalloc_node_track_caller+0x59/0x180 >> [<ffffffffa4866a1a>] kstrdup+0x3a/0x70 >> [<ffffffffc0c7f9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >> [<ffffffffc0c7fb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >> [<ffffffffc0c802c1>] tlmi_probe+0x591/0xba0 [think_lmi] >> [<ffffffffc03c9c53>] wmi_dev_probe+0x163/0x230 [wmi] >> [<ffffffffa4f987eb>] really_probe+0x17b/0x3d0 >> [<ffffffffa4f98ad4>] __driver_probe_device+0x84/0x190 >> [<ffffffffa4f98c14>] driver_probe_device+0x24/0xc0 >> [<ffffffffa4f98ed2>] __driver_attach+0xc2/0x190 >> [<ffffffffa4f95ab1>] bus_for_each_dev+0x81/0xd0 >> [<ffffffffa4f97c62>] driver_attach+0x22/0x30 >> [<ffffffffa4f97354>] bus_add_driver+0x1b4/0x240 >> [<ffffffffa4f9a0a2>] driver_register+0x62/0x120 >> [root@pc-mtodorov marvin]# uname -rms >> Linux 6.3.0-rc4-armin+tw-patch-00025-g3a93e40326c8-dirty x86_64 >> [root@pc-mtodorov marvin]# >> >> What was applied is: >> >> mtodorov@domac:~/linux/kernel/linux_torvalds$ git diff >> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >> index c816646eb661..9a3015f43aaf 100644 >> --- a/drivers/platform/x86/think-lmi.c >> +++ b/drivers/platform/x86/think-lmi.c >> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a >> >> /* validate and split from `item,value` -> `value` */ >> value = strpbrk(item, ","); >> - if (!value || value == item || !strlen(value + 1)) >> + if (!value || value == item || !strlen(value + 1)) { >> + kfree(item); >> return -EINVAL; >> + } >> >> ret = sysfs_emit(buf, "%s\n", value + 1); >> kfree(item); >> @@ -1380,7 +1382,6 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type, >> >> static int tlmi_analyze(void) >> { >> - acpi_status status; >> int i, ret; >> >> if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && >> @@ -1417,8 +1418,8 @@ static int tlmi_analyze(void) >> char *p; >> >> tlmi_priv.setting[i] = NULL; >> - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >> - if (ACPI_FAILURE(status)) >> + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >> + if (ret) >> break; >> if (!item) >> break; >> >> >>> Also current_value_show() is used by attr_current_val, the __ATTR_RW_MODE() macro arranges for that. >> >> Thanks. >> >> In this build: >> >> [root@pc-mtodorov marvin]# uname -rms >> Linux 6.3.0-rc34tests-00001-g6981739a967c x86_64 >> [root@pc-mtodorov marvin]# >> >> ... the bug isn't present, so it might be something added recently: >> >> commit 8a02d70679fc1c434401863333c8ea7dbf201494 >> Author: Mark Pearson <mpearson-lenovo@squebb.ca> >> Date: Sun Mar 19 20:32:21 2023 -0400 >> >> platform/x86: think-lmi: Add possible_values for ThinkStation >> >> commit cf337f27f3bfc4aeab4954c468239fd6233c7638 >> Author: Mark Pearson <mpearson-lenovo@squebb.ca> >> Date: Sun Mar 19 20:32:20 2023 -0400 >> >> platform/x86: think-lmi: only display possible_values if available >> >> commit 45e21289bfc6e257885514790a8a8887da822d40 >> Author: Mark Pearson <mpearson-lenovo@squebb.ca> >> Date: Sun Mar 19 20:32:19 2023 -0400 >> >> platform/x86: think-lmi: use correct possible_values delimiters >> >> commit 583329dcf22e568a328a944f20427ccfc95dce01 >> Author: Mark Pearson <mpearson-lenovo@squebb.ca> >> Date: Sun Mar 19 20:32:18 2023 -0400 >> >> platform/x86: think-lmi: add missing type attribute >> >> I have CC:-ed the author of the commits. >> >> I can try bisect, but only after my day job. > > I seem to have been right about the culprit commit. > > Here is the bisect log: > > mtodorov@domac:~/linux/kernel/linux_torvalds$ git bisect log > git bisect start '--' './drivers/platform/x86' > # good: [caa0708a81d6a2217c942959ef40d515ec1d3108] bootconfig: Change message if no bootconfig with CONFIG_BOOT_CONFIG_FORCE=y > git bisect good caa0708a81d6a2217c942959ef40d515ec1d3108 > # bad: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation > git bisect bad 8a02d70679fc1c434401863333c8ea7dbf201494 > # good: [1a0009abfa7893b9cfcd3884658af1cbee6b26ce] platform: mellanox: mlx-platform: Initialize shift variable to 0 > git bisect good 1a0009abfa7893b9cfcd3884658af1cbee6b26ce > # good: [b7c994f8c35e916e27c60803bb21457bc1373500] platform/x86 (gigabyte-wmi): Add support for A320M-S2H V2 > git bisect good b7c994f8c35e916e27c60803bb21457bc1373500 > # good: [45e21289bfc6e257885514790a8a8887da822d40] platform/x86: think-lmi: use correct possible_values delimiters > git bisect good 45e21289bfc6e257885514790a8a8887da822d40 > # good: [cf337f27f3bfc4aeab4954c468239fd6233c7638] platform/x86: think-lmi: only display possible_values if available > git bisect good cf337f27f3bfc4aeab4954c468239fd6233c7638 > # first bad commit: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation > mtodorov@domac:~/linux/kernel/linux_torvalds$ > > Please see below. > > Apparently, this commit broke something on my Lenovo box: > > diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c > index e190fec26021..3f0641360251 100644 > --- a/drivers/platform/x86/think-lmi.c > +++ b/drivers/platform/x86/think-lmi.c > @@ -941,9 +941,6 @@ static ssize_t possible_values_show(struct kobject *kobj, struct kobj_attribute > { > struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); > > - if (!tlmi_priv.can_get_bios_selections) > - return -EOPNOTSUPP; > - > return sysfs_emit(buf, "%s\n", setting->possible_values); > } > > @@ -1052,6 +1049,18 @@ static struct kobj_attribute attr_current_val = __ATTR_RW_MODE(current_value, 06 > > static struct kobj_attribute attr_type = __ATTR_RO(type); > > +static umode_t attr_is_visible(struct kobject *kobj, > + struct attribute *attr, int n) > +{ > + struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); > + > + /* We don't want to display possible_values attributes if not available */ > + if ((attr == &attr_possible_values.attr) && (!setting->possible_values)) > + return 0; > + > + return attr->mode; > +} > + > static struct attribute *tlmi_attrs[] = { > &attr_displ_name.attr, > &attr_current_val.attr, > @@ -1061,6 +1070,7 @@ static struct attribute *tlmi_attrs[] = { > }; > > static const struct attribute_group tlmi_attr_group = { > + .is_visible = attr_is_visible, > .attrs = tlmi_attrs, > }; > > Hope this helps narrow down the problem. > > Best regards, > Mirsad > >>>>>>>>>> Why aren't you looking at the wmi.c driver? That should be >>>>>>>>>> where the >>>>>>>>>> issue is, not the driver core, right? >>>>>>>>>> >>>>>>>>>> thanks, >>>>>>>>>> >>>>>>>>>> greg k-h >>>>>>>>> >>>>>>>>> Hi, Mr. Greg, >>>>>>>>> >>>>>>>>> Thanks for the quick reply. >>>>>>>>> >>>>>>>>> I have added CC: for additional developers per >>>>>>>>> drivers/platform/x86/wmi.c, >>>>>>>>> however, this seems to me like hieroglyphs. There is nothing >>>>>>>>> obvious, but >>>>>>>>> I had not noticed it with v6.3-rc3? >>>>>>>>> >>>>>>>>> Maybe, there seems to be something off: >>>>>>>>> >>>>>>>>> 949 static int wmi_dev_probe(struct device *dev) >>>>>>>>> 950 { >>>>>>>>> 951 struct wmi_block *wblock = dev_to_wblock(dev); >>>>>>>>> 952 struct wmi_driver *wdriver = >>>>>>>>> drv_to_wdrv(dev->driver); >>>>>>>>> 953 int ret = 0; >>>>>>>>> 954 char *buf; >>>>>>>>> 955 >>>>>>>>> 956 if (ACPI_FAILURE(wmi_method_enable(wblock, true))) >>>>>>>>> 957 dev_warn(dev, "failed to enable device >>>>>>>>> -- probing anyway\n"); >>>>>>>>> 958 >>>>>>>>> 959 if (wdriver->probe) { >>>>>>>>> 960 ret = wdriver->probe(dev_to_wdev(dev), >>>>>>>>> 961 find_guid_context(wblock, wdriver)); >>>>>>>>> 962 if (ret != 0) >>>>>>>>> 963 goto probe_failure; >>>>>>>>> 964 } >>>>>>>>> 965 >>>>>>>>> 966 /* driver wants a character device made */ >>>>>>>>> 967 if (wdriver->filter_callback) { >>>>>>>>> 968 /* check that required buffer size >>>>>>>>> declared by driver or MOF */ >>>>>>>>> 969 if (!wblock->req_buf_size) { >>>>>>>>> 970 dev_err(&wblock->dev.dev, >>>>>>>>> 971 "Required buffer size >>>>>>>>> not set\n"); >>>>>>>>> 972 ret = -EINVAL; >>>>>>>>> 973 goto probe_failure; >>>>>>>>> 974 } >>>>>>>>> 975 >>>>>>>>> 976 wblock->handler_data = >>>>>>>>> kmalloc(wblock->req_buf_size, >>>>>>>>> 977 GFP_KERNEL); >>>>>>>>> 978 if (!wblock->handler_data) { >>>>>>>>> 979 ret = -ENOMEM; >>>>>>>>> 980 goto probe_failure; >>>>>>>>> 981 } >>>>>>>>> 982 >>>>>>>>> 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", >>>>>>>>> wdriver->driver.name); >>>>>>>>> 984 if (!buf) { >>>>>>>>> 985 ret = -ENOMEM; >>>>>>>>> 986 goto probe_string_failure; >>>>>>>>> 987 } >>>>>>>>> 988 wblock->char_dev.minor = >>>>>>>>> MISC_DYNAMIC_MINOR; >>>>>>>>> 989 wblock->char_dev.name = buf; >>>>>>>>> 990 wblock->char_dev.fops = &wmi_fops; >>>>>>>>> 991 wblock->char_dev.mode = 0444; >>>>>>>>> 992 ret = misc_register(&wblock->char_dev); >>>>>>>>> 993 if (ret) { >>>>>>>>> 994 dev_warn(dev, "failed to >>>>>>>>> register char dev: %d\n", ret); >>>>>>>>> 995 ret = -ENOMEM; >>>>>>>>> 996 goto probe_misc_failure; >>>>>>>>> 997 } >>>>>>>>> 998 } >>>>>>>>> 999 >>>>>>>>> 1000 set_bit(WMI_PROBED, &wblock->flags); >>>>>>>>> 1001 return 0; >>>>>>>>> 1002 >>>>>>>>> 1003 probe_misc_failure: >>>>>>>>> 1004 kfree(buf); >>>>>>>>> 1005 probe_string_failure: >>>>>>>>> 1006 kfree(wblock->handler_data); >>>>>>>>> 1007 probe_failure: >>>>>>>>> 1008 if (ACPI_FAILURE(wmi_method_enable(wblock, >>>>>>>>> false))) >>>>>>>>> 1009 dev_warn(dev, "failed to disable >>>>>>>>> device\n"); >>>>>>>>> >>>>>>>>> >>>>>>>>> char *buf is passed to kfree(buf) uninitialised if >>>>>>>>> wdriver->filter_callback >>>>>>>>> is not set. >>>>>>>>> >>>>>>>>> It seems like a logical error per se, but I don't believe this is >>>>>>>>> the cause >>>>>>>>> of the leak? >>>>>>>> >>>>>>>> CORRECTION: >>>>>>>> >>>>>>>> I overlooked the "return 0" in line 1001. >>>>>>> >>>>>>> Yeah, and the memory looks to be freed properly in the >>>>>>> wmi_dev_remove() >>>>>>> callback, right? >>>>>> >>>>>> It would appear so. To verify that: >>>>>> >>>>>> Alloc: >>>>>> 976 wblock->handler_data = kmalloc(wblock->req_buf_size, >>>>>> GFP_KERNEL); >>>>>> <check> >>>>>> >>>>>> 983 buf = kasprintf(GFP_KERNEL, "wmi/%s", wdriver->driver.name); >>>>>> <check> >>>>>> 989 wblock->char_dev.name = buf; >>>>>> >>>>>> In lines 1022-1023: >>>>>> >>>>>> 1022 kfree(wblock->char_dev.name); >>>>>> 1023 kfree(wblock->handler_data); >>>>>> >>>>>>>> This is why I don't think things should be rushed, but analysed >>>>>>>> with clear and >>>>>>>> cold head. And with as many eyes as possible :) >>>>>>>> >>>>>>>> The driver stuff is my long-term research interest. To state the >>>>>>>> obvious, >>>>>>>> the printing and multimedia education and industry in general >>>>>>>> would benefit from >>>>>>>> the open-source drivers for many instruments that still work, but >>>>>>>> are obsoleted >>>>>>>> by the producer and require unsupported versions of the OS. >>>>>>>> >>>>>>>> Thank you again for reviewing the bug report, however, ATM I do >>>>>>>> not think I have >>>>>>>> what it takes to hunt down the memleak. :-/ >>>>>>> >>>>>>> Do you have a reproducer that you can use to show the problem better? >>>>>> >>>>>> Unfortunately, the problem doesn't seem to appear during the run of >>>>>> a particular >>>>>> test, but immediately on startup of the OS. This makes it awkward to >>>>>> pinpoint the >>>>>> exact service that triggered memory leaks. But they would appear to >>>>>> have to do >>>>>> with the initialisation of the USB devices, wouldn't they? >>>>>> >>>>>> There seem to be strings: >>>>>> >>>>>> "USBPortAccess,Enabled;[Optional:" >>>>>> "USBBIOSSupport,Enabled;[Optional" >>>>>> "USBEnumerationDelay,Disabled;[Op" >>>>>> >>>>>> This seems to be happening during USB initialisation and before any >>>>>> services. >>>>>> But I might as well be wrong. >>>>>> >>>>>>> Or can you test kernel patches to verify the problem is fixed or >>>>>>> not if >>>>>>> we send you patches to test? >>>>>> >>>>>> Certainly, Lord willing, I can test the patches in the same >>>>>> environment that >>>>>> mainfeted the bug (or memleak). mtodorov@domac:~/linux/kernel/linux_torvalds$ git bisect log git bisect start '--' './drivers/platform/x86' # good: [caa0708a81d6a2217c942959ef40d515ec1d3108] bootconfig: Change message if no bootconfig with CONFIG_BOOT_CONFIG_FORCE=y git bisect good caa0708a81d6a2217c942959ef40d515ec1d3108 # bad: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation git bisect bad 8a02d70679fc1c434401863333c8ea7dbf201494 # good: [1a0009abfa7893b9cfcd3884658af1cbee6b26ce] platform: mellanox: mlx-platform: Initialize shift variable to 0 git bisect good 1a0009abfa7893b9cfcd3884658af1cbee6b26ce # good: [b7c994f8c35e916e27c60803bb21457bc1373500] platform/x86 (gigabyte-wmi): Add support for A320M-S2H V2 git bisect good b7c994f8c35e916e27c60803bb21457bc1373500 # good: [45e21289bfc6e257885514790a8a8887da822d40] platform/x86: think-lmi: use correct possible_values delimiters git bisect good 45e21289bfc6e257885514790a8a8887da822d40 # good: [cf337f27f3bfc4aeab4954c468239fd6233c7638] platform/x86: think-lmi: only display possible_values if available git bisect good cf337f27f3bfc4aeab4954c468239fd6233c7638 # first bad commit: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation mtodorov@domac:~/linux/kernel/linux_torvalds$ So the commit that triggered the bug on the Lenovo desktop box was: diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index 3f0641360251..c816646eb661 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -1450,6 +1450,26 @@ static int tlmi_analyze(void) if (ret || !setting->possible_values) pr_info("Error retrieving possible values for %d : %s\n", i, setting->display_name); + } else { + /* + * Older Thinkstations don't support the bios_selections API. + * Instead they store this as a [Optional:Option1,Option2] section of the + * name string. + * Try and pull that out if it's available. + */ + char *item, *optstart, *optend; + + if (!tlmi_setting(setting->index, &item, LENOVO_BIOS_SETTING_GUID)) { + optstart = strstr(item, "[Optional:"); + if (optstart) { + optstart += strlen("[Optional:"); + optend = strstr(optstart, "]"); + if (optend) + setting->possible_values = + kstrndup(optstart, optend - optstart, + GFP_KERNEL); + } + } } /* * firmware-attributes requires that possible_values are separated by ';' but Thousand apologies, once again. Best regards, Mirsad -- Mirsad Todorovac System engineer Faculty of Graphic Arts | Academy of Fine Arts University of Zagreb Republic of Croatia, the European Union Sistem inženjer Grafički fakultet | Akademija likovnih umjetnosti Sveučilište u Zagrebu ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [BUG] [BISECTED] [CORRECTION] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-29 13:31 ` [BUG] [BISECTED] [CORRECTION] " Mirsad Goran Todorovac @ 2023-03-29 13:35 ` Thomas Weißschuh 2023-03-29 14:18 ` Mirsad Goran Todorovac 0 siblings, 1 reply; 24+ messages in thread From: Thomas Weißschuh @ 2023-03-29 13:35 UTC (permalink / raw) To: Mirsad Goran Todorovac Cc: Armin Wolf, Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, Hans de Goede, Mark Gross, platform-driver-x86, Mark Pearson Mar 29, 2023 08:31:31 Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>: > Hi, again, > > NOTE: I forgot to rewind to the first bad commit. So please ignore > the previous email. > > On 29.3.2023. 15:22, Mirsad Goran Todorovac wrote: >> Hi, Armin, Mr. Greg, >> On 29.3.2023. 10:13, Mirsad Goran Todorovac wrote: >>> On 28.3.2023. 21:55, Armin Wolf wrote: >>>> Am 28.03.23 um 21:06 schrieb Mirsad Goran Todorovac: >>>> >>>>> On 3/28/2023 6:53 PM, Armin Wolf wrote: >>>>>> … >>>>> >>>>> Hi Armin, >>>>> >>>>> I tried your suggestion, and though it is an obvious improvement and a >>>>> leak fix, this >>>>> was not the one we were searching for. >>>>> >>>>> I tested the following patch: >>>>> >>>>> diff --git a/drivers/platform/x86/think-lmi.c >>>>> b/drivers/platform/x86/think-lmi.c >>>>> index c816646eb661..1e77ecb0cba8 100644 >>>>> --- a/drivers/platform/x86/think-lmi.c >>>>> +++ b/drivers/platform/x86/think-lmi.c >>>>> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject >>>>> *kobj, struct kobj_attribute *a >>>>> >>>>> /* validate and split from `item,value` -> `value` */ >>>>> value = strpbrk(item, ","); >>>>> - if (!value || value == item || !strlen(value + 1)) >>>>> + if (!value || value == item || !strlen(value + 1)) { >>>>> + kfree(item); >>>>> return -EINVAL; >>>>> + } >>>>> >>>>> ret = sysfs_emit(buf, "%s\n", value + 1); >>>>> kfree(item); >>>>> >>>>> (I would also object to the use of strlen() here, for it is inherently >>>>> insecure >>>>> against SEGFAULT in kernel space.) >>>>> >>>>> I still get: >>>>> [root@pc-mtodorov marvin]# uname -rms >>>>> Linux 6.3.0-rc4-armin-patch-00025-g3a93e40326c8-dirty x86_64 >>>>> [root@pc-mtodorov marvin]# cat /sys/kernel/debug/kmemleak [edited] >>>>> unreferenced object 0xffff8eb008ef9260 (size 96): >>>>> comm "systemd-udevd", pid 771, jiffies 4294896499 (age 74.880s) >>>>> hex dump (first 32 bytes): >>>>> 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 SerialPort1Addre >>>>> 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 ss,3F8/IRQ4;[Opt >>>>> backtrace: >>>>> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >>>>> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >>>>> [think_lmi] >>>>> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>>> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >>>>> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >>>>> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >>>>> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >>>>> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >>>>> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >>>>> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >>>>> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >>>>> unreferenced object 0xffff8eb018ddbb40 (size 64): >>>>> comm "systemd-udevd", pid 771, jiffies 4294896528 (age 74.780s) >>>>> hex dump (first 32 bytes): >>>>> 55 53 42 50 6f 72 74 41 63 63 65 73 73 2c 45 6e USBPortAccess,En >>>>> 61 62 6c 65 64 3b 5b 4f 70 74 69 6f 6e 61 6c 3a abled;[Optional: >>>>> backtrace: >>>>> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >>>>> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >>>>> [think_lmi] >>>>> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>>> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >>>>> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >>>>> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >>>>> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >>>>> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >>>>> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >>>>> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >>>>> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >>>>> unreferenced object 0xffff8eb006fe2b40 (size 64): >>>>> comm "systemd-udevd", pid 771, jiffies 4294896542 (age 74.724s) >>>>> hex dump (first 32 bytes): >>>>> 55 53 42 42 49 4f 53 53 75 70 70 6f 72 74 2c 45 USBBIOSSupport,E >>>>> 6e 61 62 6c 65 64 3b 5b 4f 70 74 69 6f 6e 61 6c nabled;[Optional >>>>> backtrace: >>>>> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >>>>> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >>>>> [think_lmi] >>>>> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>>> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >>>>> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >>>>> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >>>>> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >>>>> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >>>>> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >>>>> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >>>>> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >>>>> >>>>> There are currently 84 wmi_dev_probe leaks, sized mostly 64 bytes, and >>>>> one 96 and two 192 bytes. >>>>> >>>>> I also cannot figure out the mechanism by which current_value_show() >>>>> is called, when it is static? >>>>> >>>>> Any idea? >>>>> >>>>> Thanks. >>>>> >>>>> Best regards, >>>>> Mirsad >>>>> >>>> Can you tell me how many BIOS settings think-lmi provides on your machine? Because according to the stacktrace, >>>> the other place where the leak could have occurred is inside tlmi_analyze(), which calls tlmi_setting(). >>> >>> Yes, Sir! >>> >>> I think these could be the ones you need (totaling 83, which is close to 82 systemd-udevd leaks): >>> >>> [root@pc-mtodorov marvin]# ls -l /sys/devices/virtual/firmware-attributes/thinklmi/attributes | grep ^d >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 AfterPowerLoss >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmDate(MM\DD\YYYY) >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmDayofWeek >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmTime(HH:MM:SS) >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ASPMSupport >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 AutomaticBootSequence >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtBootDeviceList >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtReboot >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtUnattendedBoot >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BootMode >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BootPriority >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BootUpNum-LockStatus >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 C1ESupport >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 CardReader >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ClearTCGSecurityFeature >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ComputraceModuleActivation >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ConfigurationChangeDetection >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ConfigureSATAas >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 CoreMulti-Processing >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 CoverTamperDetected >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 CSM >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 CStateSupport >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 DeviceGuard >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 DustShieldAlert >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 EISTSupport >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 EnhancedPowerSavingMode >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ErrorBootSequence >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Friday >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 FrontUSBPorts >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 HardDiskPre-delay >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Intel(R)SGXControl >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 InternalSpeaker >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Monday >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 OnboardAudioController >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 OnboardEthernetController >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 OptionKeysDisplay >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 OptionKeysDisplayStyle >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 OSOptimizedDefaults >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PasswordCountExceededError >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PCIe16xSlotSpeed >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PCIe1xSlot1Speed >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PrimaryBootSequence >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEIPV4NetworkStack >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEIPV6NetworkStack >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEOptionROM >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 RearUSBPorts >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 RequireAdmin.Pass.whenFlashing >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 RequireHDPonSystemBoot >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SATAController >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SATADrive1 >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SATADrive2 >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Saturday >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SecureBoot >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SecureRollBackPrevention >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SecurityChip >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SelectActiveVideo >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SerialPort1Address >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SmartUSBProtection >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 StartupDeviceMenuPrompt >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 StartupSequence >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Sunday >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Thursday >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Tuesday >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 TurboMode >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBBIOSSupport >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBEnumerationDelay >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort1 >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort2 >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort3 >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort4 >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort5 >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort6 >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort7 >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort8 >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPortAccess >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 UserDefinedAlarmTime(HH:MM:SS) >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 VirtualizationTechnology >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 VTdFeature >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 WakefromSerialPortRing >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 WakeOnLAN >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 WakeUponAlarm >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Wednesday >>> drwxr-xr-x 2 root root 0 Mar 29 08:24 WindowsUEFIFirmwareUpdate >>> [root@pc-mtodorov marvin]# ls -l /sys/devices/virtual/firmware-attributes/thinklmi/attributes | grep ^d | wc -l >>> 83 >>> [root@pc-mtodorov marvin]# >>> >>>> However, i have no idea on how *info is somehow leaked, it has to happen inside the for-loop tween the call >>>> to tlmi_setting() and strreplace(), because otherwise the strings would not contain the "/" character. >>> >>> I see. It is the line 1404. >>> >>>> Can you check if the problem is somehow solved by applying the following commit from the platform-drivers-x86 >>>> for-next branch: >>>> da62908efe80 ("platform/x86: think-lmi: Properly interpret return value of tlmi_setting") >>> >>> It could possibly be that. But I do not recall seeing these messages in 6.3-rc3 ... >>> >>> ... >>> >>> Unfortunately, the build with Thomas' patch you referred to did not work: >>> >>> unreferenced object 0xffff9dff4d28bbc8 (size 192): >>> comm "systemd-udevd", pid 769, jiffies 4294897473 (age 85.700s) >>> hex dump (first 32 bytes): >>> 50 72 69 6d 61 72 79 42 6f 6f 74 53 65 71 75 65 PrimaryBootSeque >>> 6e 63 65 2c 4d 2e 32 20 44 72 69 76 65 20 31 3a nce,M.2 Drive 1: >>> backtrace: >>> [<ffffffffa48fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>> [<ffffffffa4902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>> [<ffffffffa48773c9>] __kmalloc_node_track_caller+0x59/0x180 >>> [<ffffffffa4866a1a>] kstrdup+0x3a/0x70 >>> [<ffffffffc0c7f9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >>> [<ffffffffc0c7fb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>> [<ffffffffc0c802c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>> [<ffffffffc03c9c53>] wmi_dev_probe+0x163/0x230 [wmi] >>> [<ffffffffa4f987eb>] really_probe+0x17b/0x3d0 >>> [<ffffffffa4f98ad4>] __driver_probe_device+0x84/0x190 >>> [<ffffffffa4f98c14>] driver_probe_device+0x24/0xc0 >>> [<ffffffffa4f98ed2>] __driver_attach+0xc2/0x190 >>> [<ffffffffa4f95ab1>] bus_for_each_dev+0x81/0xd0 >>> [<ffffffffa4f97c62>] driver_attach+0x22/0x30 >>> [<ffffffffa4f97354>] bus_add_driver+0x1b4/0x240 >>> [<ffffffffa4f9a0a2>] driver_register+0x62/0x120 >>> unreferenced object 0xffff9dff4d28a008 (size 192): >>> comm "systemd-udevd", pid 769, jiffies 4294897517 (age 85.540s) >>> hex dump (first 32 bytes): >>> 45 72 72 6f 72 42 6f 6f 74 53 65 71 75 65 6e 63 ErrorBootSequenc >>> 65 2c 4e 65 74 77 6f 72 6b 20 31 3a 4d 2e 32 20 e,Network 1:M.2 >>> backtrace: >>> [<ffffffffa48fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>> [<ffffffffa4902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>> [<ffffffffa48773c9>] __kmalloc_node_track_caller+0x59/0x180 >>> [<ffffffffa4866a1a>] kstrdup+0x3a/0x70 >>> [<ffffffffc0c7f9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >>> [<ffffffffc0c7fb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>> [<ffffffffc0c802c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>> [<ffffffffc03c9c53>] wmi_dev_probe+0x163/0x230 [wmi] >>> [<ffffffffa4f987eb>] really_probe+0x17b/0x3d0 >>> [<ffffffffa4f98ad4>] __driver_probe_device+0x84/0x190 >>> [<ffffffffa4f98c14>] driver_probe_device+0x24/0xc0 >>> [<ffffffffa4f98ed2>] __driver_attach+0xc2/0x190 >>> [<ffffffffa4f95ab1>] bus_for_each_dev+0x81/0xd0 >>> [<ffffffffa4f97c62>] driver_attach+0x22/0x30 >>> [<ffffffffa4f97354>] bus_add_driver+0x1b4/0x240 >>> [<ffffffffa4f9a0a2>] driver_register+0x62/0x120 >>> [root@pc-mtodorov marvin]# uname -rms >>> Linux 6.3.0-rc4-armin+tw-patch-00025-g3a93e40326c8-dirty x86_64 >>> [root@pc-mtodorov marvin]# >>> >>> What was applied is: >>> >>> mtodorov@domac:~/linux/kernel/linux_torvalds$ git diff >>> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >>> index c816646eb661..9a3015f43aaf 100644 >>> --- a/drivers/platform/x86/think-lmi.c >>> +++ b/drivers/platform/x86/think-lmi.c >>> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a >>> >>> /* validate and split from `item,value` -> `value` */ >>> value = strpbrk(item, ","); >>> - if (!value || value == item || !strlen(value + 1)) >>> + if (!value || value == item || !strlen(value + 1)) { >>> + kfree(item); >>> return -EINVAL; >>> + } >>> >>> ret = sysfs_emit(buf, "%s\n", value + 1); >>> kfree(item); >>> @@ -1380,7 +1382,6 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type, >>> >>> static int tlmi_analyze(void) >>> { >>> - acpi_status status; >>> int i, ret; >>> >>> if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && >>> @@ -1417,8 +1418,8 @@ static int tlmi_analyze(void) >>> char *p; >>> >>> tlmi_priv.setting[i] = NULL; >>> - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>> - if (ACPI_FAILURE(status)) >>> + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>> + if (ret) >>> break; >>> if (!item) >>> break; >>> >>> >>>> Also current_value_show() is used by attr_current_val, the __ATTR_RW_MODE() macro arranges for that. >>> >>> Thanks. >>> >>> In this build: >>> >>> [root@pc-mtodorov marvin]# uname -rms >>> Linux 6.3.0-rc34tests-00001-g6981739a967c x86_64 >>> [root@pc-mtodorov marvin]# >>> >>> ... the bug isn't present, so it might be something added recently: >>> >>> commit 8a02d70679fc1c434401863333c8ea7dbf201494 >>> Author: Mark Pearson <mpearson-lenovo@squebb.ca> >>> Date: Sun Mar 19 20:32:21 2023 -0400 >>> >>> platform/x86: think-lmi: Add possible_values for ThinkStation >>> >>> commit cf337f27f3bfc4aeab4954c468239fd6233c7638 >>> Author: Mark Pearson <mpearson-lenovo@squebb.ca> >>> Date: Sun Mar 19 20:32:20 2023 -0400 >>> >>> platform/x86: think-lmi: only display possible_values if available >>> >>> commit 45e21289bfc6e257885514790a8a8887da822d40 >>> Author: Mark Pearson <mpearson-lenovo@squebb.ca> >>> Date: Sun Mar 19 20:32:19 2023 -0400 >>> >>> platform/x86: think-lmi: use correct possible_values delimiters >>> >>> commit 583329dcf22e568a328a944f20427ccfc95dce01 >>> Author: Mark Pearson <mpearson-lenovo@squebb.ca> >>> Date: Sun Mar 19 20:32:18 2023 -0400 >>> >>> platform/x86: think-lmi: add missing type attribute >>> >>> I have CC:-ed the author of the commits. >>> >>> I can try bisect, but only after my day job. >> I seem to have been right about the culprit commit. >> Here is the bisect log: >> mtodorov@domac:~/linux/kernel/linux_torvalds$ git bisect log >> git bisect start '--' './drivers/platform/x86' >> # good: [caa0708a81d6a2217c942959ef40d515ec1d3108] bootconfig: Change message if no bootconfig with CONFIG_BOOT_CONFIG_FORCE=y >> git bisect good caa0708a81d6a2217c942959ef40d515ec1d3108 >> # bad: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation >> git bisect bad 8a02d70679fc1c434401863333c8ea7dbf201494 >> # good: [1a0009abfa7893b9cfcd3884658af1cbee6b26ce] platform: mellanox: mlx-platform: Initialize shift variable to 0 >> git bisect good 1a0009abfa7893b9cfcd3884658af1cbee6b26ce >> # good: [b7c994f8c35e916e27c60803bb21457bc1373500] platform/x86 (gigabyte-wmi): Add support for A320M-S2H V2 >> git bisect good b7c994f8c35e916e27c60803bb21457bc1373500 >> # good: [45e21289bfc6e257885514790a8a8887da822d40] platform/x86: think-lmi: use correct possible_values delimiters >> git bisect good 45e21289bfc6e257885514790a8a8887da822d40 >> # good: [cf337f27f3bfc4aeab4954c468239fd6233c7638] platform/x86: think-lmi: only display possible_values if available >> git bisect good cf337f27f3bfc4aeab4954c468239fd6233c7638 >> # first bad commit: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation >> mtodorov@domac:~/linux/kernel/linux_torvalds$ >> Please see below. >> Apparently, this commit broke something on my Lenovo box: >> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >> index e190fec26021..3f0641360251 100644 >> --- a/drivers/platform/x86/think-lmi.c >> +++ b/drivers/platform/x86/think-lmi.c >> @@ -941,9 +941,6 @@ static ssize_t possible_values_show(struct kobject *kobj, struct kobj_attribute >> { >> struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); >> - if (!tlmi_priv.can_get_bios_selections) >> - return -EOPNOTSUPP; >> - >> return sysfs_emit(buf, "%s\n", setting->possible_values); >> } >> @@ -1052,6 +1049,18 @@ static struct kobj_attribute attr_current_val = __ATTR_RW_MODE(current_value, 06 >> static struct kobj_attribute attr_type = __ATTR_RO(type); >> +static umode_t attr_is_visible(struct kobject *kobj, >> + struct attribute *attr, int n) >> +{ >> + struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); >> + >> + /* We don't want to display possible_values attributes if not available */ >> + if ((attr == &attr_possible_values.attr) && (!setting->possible_values)) >> + return 0; >> + >> + return attr->mode; >> +} >> + >> static struct attribute *tlmi_attrs[] = { >> &attr_displ_name.attr, >> &attr_current_val.attr, >> @@ -1061,6 +1070,7 @@ static struct attribute *tlmi_attrs[] = { >> }; >> static const struct attribute_group tlmi_attr_group = { >> + .is_visible = attr_is_visible, >> .attrs = tlmi_attrs, >> }; >> Hope this helps narrow down the problem. >> Best regards, >> Mirsad >> Why aren't you looking at the wmi.c driver? That should be >>>>>> … > > mtodorov@domac:~/linux/kernel/linux_torvalds$ git bisect log > git bisect start '--' './drivers/platform/x86' > # good: [caa0708a81d6a2217c942959ef40d515ec1d3108] bootconfig: Change message if no bootconfig with CONFIG_BOOT_CONFIG_FORCE=y > git bisect good caa0708a81d6a2217c942959ef40d515ec1d3108 > # bad: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation > git bisect bad 8a02d70679fc1c434401863333c8ea7dbf201494 > # good: [1a0009abfa7893b9cfcd3884658af1cbee6b26ce] platform: mellanox: mlx-platform: Initialize shift variable to 0 > git bisect good 1a0009abfa7893b9cfcd3884658af1cbee6b26ce > # good: [b7c994f8c35e916e27c60803bb21457bc1373500] platform/x86 (gigabyte-wmi): Add support for A320M-S2H V2 > git bisect good b7c994f8c35e916e27c60803bb21457bc1373500 > # good: [45e21289bfc6e257885514790a8a8887da822d40] platform/x86: think-lmi: use correct possible_values delimiters > git bisect good 45e21289bfc6e257885514790a8a8887da822d40 > # good: [cf337f27f3bfc4aeab4954c468239fd6233c7638] platform/x86: think-lmi: only display possible_values if available > git bisect good cf337f27f3bfc4aeab4954c468239fd6233c7638 > # first bad commit: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation > mtodorov@domac:~/linux/kernel/linux_torvalds$ > > So the commit that triggered the bug on the Lenovo desktop box was: > > diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c > index 3f0641360251..c816646eb661 100644 > --- a/drivers/platform/x86/think-lmi.c > +++ b/drivers/platform/x86/think-lmi.c > @@ -1450,6 +1450,26 @@ static int tlmi_analyze(void) > if (ret || !setting->possible_values) > pr_info("Error retrieving possible values for %d : %s\n", > i, setting->display_name); > + } else { > + /* > + * Older Thinkstations don't support the bios_selections API. > + * Instead they store this as a [Optional:Option1,Option2] section of the > + * name string. > + * Try and pull that out if it's available. > + */ > + char *item, *optstart, *optend; > + > + if (!tlmi_setting(setting->index, &item, LENOVO_BIOS_SETTING_GUID)) { > + optstart = strstr(item, "[Optional:"); > + if (optstart) { > + optstart += strlen("[Optional:"); > + optend = strstr(optstart, "]"); > + if (optend) > + setting->possible_values = > + kstrndup(optstart, optend - optstart, > + GFP_KERNEL); I guess item needs to be freed here. (Next week I have access to my Lenovo machine again. I'll look at it then if it's not solved.) > + } > + } > } > /* > * firmware-attributes requires that possible_values are separated by ';' but > > Thousand apologies, once again. > > Best regards, > Mirsad > > -- > Mirsad Todorovac > System engineer > Faculty of Graphic Arts | Academy of Fine Arts > University of Zagreb > Republic of Croatia, the European Union > > Sistem inženjer > Grafički fakultet | Akademija likovnih umjetnosti> Sveučilište u Zagrebu ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] [BISECTED] [CORRECTION] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-29 13:35 ` Thomas Weißschuh @ 2023-03-29 14:18 ` Mirsad Goran Todorovac 2023-03-29 15:46 ` Hans de Goede 0 siblings, 1 reply; 24+ messages in thread From: Mirsad Goran Todorovac @ 2023-03-29 14:18 UTC (permalink / raw) To: Thomas Weißschuh Cc: Armin Wolf, Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, Hans de Goede, Mark Gross, platform-driver-x86, Mark Pearson On 29.3.2023. 15:35, Thomas Weißschuh wrote: > > Mar 29, 2023 08:31:31 Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>: > >> Hi, again, >> >> NOTE: I forgot to rewind to the first bad commit. So please ignore >> the previous email. >> >> On 29.3.2023. 15:22, Mirsad Goran Todorovac wrote: >>> Hi, Armin, Mr. Greg, >>> On 29.3.2023. 10:13, Mirsad Goran Todorovac wrote: >>>> On 28.3.2023. 21:55, Armin Wolf wrote: >>>>> Am 28.03.23 um 21:06 schrieb Mirsad Goran Todorovac: >>>>> >>>>>> On 3/28/2023 6:53 PM, Armin Wolf wrote: >>>>>>> … >>>>>> >>>>>> Hi Armin, >>>>>> >>>>>> I tried your suggestion, and though it is an obvious improvement and a >>>>>> leak fix, this >>>>>> was not the one we were searching for. >>>>>> >>>>>> I tested the following patch: >>>>>> >>>>>> diff --git a/drivers/platform/x86/think-lmi.c >>>>>> b/drivers/platform/x86/think-lmi.c >>>>>> index c816646eb661..1e77ecb0cba8 100644 >>>>>> --- a/drivers/platform/x86/think-lmi.c >>>>>> +++ b/drivers/platform/x86/think-lmi.c >>>>>> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject >>>>>> *kobj, struct kobj_attribute *a >>>>>> >>>>>> /* validate and split from `item,value` -> `value` */ >>>>>> value = strpbrk(item, ","); >>>>>> - if (!value || value == item || !strlen(value + 1)) >>>>>> + if (!value || value == item || !strlen(value + 1)) { >>>>>> + kfree(item); >>>>>> return -EINVAL; >>>>>> + } >>>>>> >>>>>> ret = sysfs_emit(buf, "%s\n", value + 1); >>>>>> kfree(item); >>>>>> >>>>>> (I would also object to the use of strlen() here, for it is inherently >>>>>> insecure >>>>>> against SEGFAULT in kernel space.) >>>>>> >>>>>> I still get: >>>>>> [root@pc-mtodorov marvin]# uname -rms >>>>>> Linux 6.3.0-rc4-armin-patch-00025-g3a93e40326c8-dirty x86_64 >>>>>> [root@pc-mtodorov marvin]# cat /sys/kernel/debug/kmemleak [edited] >>>>>> unreferenced object 0xffff8eb008ef9260 (size 96): >>>>>> comm "systemd-udevd", pid 771, jiffies 4294896499 (age 74.880s) >>>>>> hex dump (first 32 bytes): >>>>>> 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 SerialPort1Addre >>>>>> 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 ss,3F8/IRQ4;[Opt >>>>>> backtrace: >>>>>> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>>> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>>> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>>> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >>>>>> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >>>>>> [think_lmi] >>>>>> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>>>> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>>> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>>> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >>>>>> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >>>>>> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >>>>>> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >>>>>> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >>>>>> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >>>>>> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >>>>>> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >>>>>> unreferenced object 0xffff8eb018ddbb40 (size 64): >>>>>> comm "systemd-udevd", pid 771, jiffies 4294896528 (age 74.780s) >>>>>> hex dump (first 32 bytes): >>>>>> 55 53 42 50 6f 72 74 41 63 63 65 73 73 2c 45 6e USBPortAccess,En >>>>>> 61 62 6c 65 64 3b 5b 4f 70 74 69 6f 6e 61 6c 3a abled;[Optional: >>>>>> backtrace: >>>>>> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>>> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>>> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>>> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >>>>>> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >>>>>> [think_lmi] >>>>>> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>>>> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>>> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>>> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >>>>>> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >>>>>> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >>>>>> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >>>>>> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >>>>>> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >>>>>> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >>>>>> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >>>>>> unreferenced object 0xffff8eb006fe2b40 (size 64): >>>>>> comm "systemd-udevd", pid 771, jiffies 4294896542 (age 74.724s) >>>>>> hex dump (first 32 bytes): >>>>>> 55 53 42 42 49 4f 53 53 75 70 70 6f 72 74 2c 45 USBBIOSSupport,E >>>>>> 6e 61 62 6c 65 64 3b 5b 4f 70 74 69 6f 6e 61 6c nabled;[Optional >>>>>> backtrace: >>>>>> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>>> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>>> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>>> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >>>>>> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >>>>>> [think_lmi] >>>>>> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>>>> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>>> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>>> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >>>>>> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >>>>>> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >>>>>> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >>>>>> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >>>>>> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >>>>>> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >>>>>> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >>>>>> >>>>>> There are currently 84 wmi_dev_probe leaks, sized mostly 64 bytes, and >>>>>> one 96 and two 192 bytes. >>>>>> >>>>>> I also cannot figure out the mechanism by which current_value_show() >>>>>> is called, when it is static? >>>>>> >>>>>> Any idea? >>>>>> >>>>>> Thanks. >>>>>> >>>>>> Best regards, >>>>>> Mirsad >>>>>> >>>>> Can you tell me how many BIOS settings think-lmi provides on your machine? Because according to the stacktrace, >>>>> the other place where the leak could have occurred is inside tlmi_analyze(), which calls tlmi_setting(). >>>> >>>> Yes, Sir! >>>> >>>> I think these could be the ones you need (totaling 83, which is close to 82 systemd-udevd leaks): >>>> >>>> [root@pc-mtodorov marvin]# ls -l /sys/devices/virtual/firmware-attributes/thinklmi/attributes | grep ^d >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 AfterPowerLoss >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmDate(MM\DD\YYYY) >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmDayofWeek >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmTime(HH:MM:SS) >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ASPMSupport >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 AutomaticBootSequence >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtBootDeviceList >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtReboot >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtUnattendedBoot >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BootMode >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BootPriority >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BootUpNum-LockStatus >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 C1ESupport >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 CardReader >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ClearTCGSecurityFeature >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ComputraceModuleActivation >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ConfigurationChangeDetection >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ConfigureSATAas >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 CoreMulti-Processing >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 CoverTamperDetected >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 CSM >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 CStateSupport >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 DeviceGuard >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 DustShieldAlert >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 EISTSupport >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 EnhancedPowerSavingMode >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ErrorBootSequence >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Friday >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 FrontUSBPorts >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 HardDiskPre-delay >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Intel(R)SGXControl >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 InternalSpeaker >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Monday >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 OnboardAudioController >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 OnboardEthernetController >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 OptionKeysDisplay >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 OptionKeysDisplayStyle >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 OSOptimizedDefaults >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PasswordCountExceededError >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PCIe16xSlotSpeed >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PCIe1xSlot1Speed >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PrimaryBootSequence >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEIPV4NetworkStack >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEIPV6NetworkStack >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEOptionROM >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 RearUSBPorts >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 RequireAdmin.Pass.whenFlashing >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 RequireHDPonSystemBoot >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SATAController >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SATADrive1 >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SATADrive2 >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Saturday >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SecureBoot >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SecureRollBackPrevention >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SecurityChip >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SelectActiveVideo >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SerialPort1Address >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SmartUSBProtection >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 StartupDeviceMenuPrompt >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 StartupSequence >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Sunday >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Thursday >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Tuesday >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 TurboMode >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBBIOSSupport >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBEnumerationDelay >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort1 >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort2 >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort3 >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort4 >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort5 >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort6 >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort7 >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort8 >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPortAccess >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 UserDefinedAlarmTime(HH:MM:SS) >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 VirtualizationTechnology >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 VTdFeature >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 WakefromSerialPortRing >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 WakeOnLAN >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 WakeUponAlarm >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Wednesday >>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 WindowsUEFIFirmwareUpdate >>>> [root@pc-mtodorov marvin]# ls -l /sys/devices/virtual/firmware-attributes/thinklmi/attributes | grep ^d | wc -l >>>> 83 >>>> [root@pc-mtodorov marvin]# >>>> >>>>> However, i have no idea on how *info is somehow leaked, it has to happen inside the for-loop tween the call >>>>> to tlmi_setting() and strreplace(), because otherwise the strings would not contain the "/" character. >>>> >>>> I see. It is the line 1404. >>>> >>>>> Can you check if the problem is somehow solved by applying the following commit from the platform-drivers-x86 >>>>> for-next branch: >>>>> da62908efe80 ("platform/x86: think-lmi: Properly interpret return value of tlmi_setting") >>>> >>>> It could possibly be that. But I do not recall seeing these messages in 6.3-rc3 ... >>>> >>>> ... >>>> >>>> Unfortunately, the build with Thomas' patch you referred to did not work: >>>> >>>> unreferenced object 0xffff9dff4d28bbc8 (size 192): >>>> comm "systemd-udevd", pid 769, jiffies 4294897473 (age 85.700s) >>>> hex dump (first 32 bytes): >>>> 50 72 69 6d 61 72 79 42 6f 6f 74 53 65 71 75 65 PrimaryBootSeque >>>> 6e 63 65 2c 4d 2e 32 20 44 72 69 76 65 20 31 3a nce,M.2 Drive 1: >>>> backtrace: >>>> [<ffffffffa48fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>> [<ffffffffa4902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>> [<ffffffffa48773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>> [<ffffffffa4866a1a>] kstrdup+0x3a/0x70 >>>> [<ffffffffc0c7f9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >>>> [<ffffffffc0c7fb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>> [<ffffffffc0c802c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>> [<ffffffffc03c9c53>] wmi_dev_probe+0x163/0x230 [wmi] >>>> [<ffffffffa4f987eb>] really_probe+0x17b/0x3d0 >>>> [<ffffffffa4f98ad4>] __driver_probe_device+0x84/0x190 >>>> [<ffffffffa4f98c14>] driver_probe_device+0x24/0xc0 >>>> [<ffffffffa4f98ed2>] __driver_attach+0xc2/0x190 >>>> [<ffffffffa4f95ab1>] bus_for_each_dev+0x81/0xd0 >>>> [<ffffffffa4f97c62>] driver_attach+0x22/0x30 >>>> [<ffffffffa4f97354>] bus_add_driver+0x1b4/0x240 >>>> [<ffffffffa4f9a0a2>] driver_register+0x62/0x120 >>>> unreferenced object 0xffff9dff4d28a008 (size 192): >>>> comm "systemd-udevd", pid 769, jiffies 4294897517 (age 85.540s) >>>> hex dump (first 32 bytes): >>>> 45 72 72 6f 72 42 6f 6f 74 53 65 71 75 65 6e 63 ErrorBootSequenc >>>> 65 2c 4e 65 74 77 6f 72 6b 20 31 3a 4d 2e 32 20 e,Network 1:M.2 >>>> backtrace: >>>> [<ffffffffa48fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>> [<ffffffffa4902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>> [<ffffffffa48773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>> [<ffffffffa4866a1a>] kstrdup+0x3a/0x70 >>>> [<ffffffffc0c7f9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >>>> [<ffffffffc0c7fb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>> [<ffffffffc0c802c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>> [<ffffffffc03c9c53>] wmi_dev_probe+0x163/0x230 [wmi] >>>> [<ffffffffa4f987eb>] really_probe+0x17b/0x3d0 >>>> [<ffffffffa4f98ad4>] __driver_probe_device+0x84/0x190 >>>> [<ffffffffa4f98c14>] driver_probe_device+0x24/0xc0 >>>> [<ffffffffa4f98ed2>] __driver_attach+0xc2/0x190 >>>> [<ffffffffa4f95ab1>] bus_for_each_dev+0x81/0xd0 >>>> [<ffffffffa4f97c62>] driver_attach+0x22/0x30 >>>> [<ffffffffa4f97354>] bus_add_driver+0x1b4/0x240 >>>> [<ffffffffa4f9a0a2>] driver_register+0x62/0x120 >>>> [root@pc-mtodorov marvin]# uname -rms >>>> Linux 6.3.0-rc4-armin+tw-patch-00025-g3a93e40326c8-dirty x86_64 >>>> [root@pc-mtodorov marvin]# >>>> >>>> What was applied is: >>>> >>>> mtodorov@domac:~/linux/kernel/linux_torvalds$ git diff >>>> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >>>> index c816646eb661..9a3015f43aaf 100644 >>>> --- a/drivers/platform/x86/think-lmi.c >>>> +++ b/drivers/platform/x86/think-lmi.c >>>> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a >>>> >>>> /* validate and split from `item,value` -> `value` */ >>>> value = strpbrk(item, ","); >>>> - if (!value || value == item || !strlen(value + 1)) >>>> + if (!value || value == item || !strlen(value + 1)) { >>>> + kfree(item); >>>> return -EINVAL; >>>> + } >>>> >>>> ret = sysfs_emit(buf, "%s\n", value + 1); >>>> kfree(item); >>>> @@ -1380,7 +1382,6 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type, >>>> >>>> static int tlmi_analyze(void) >>>> { >>>> - acpi_status status; >>>> int i, ret; >>>> >>>> if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && >>>> @@ -1417,8 +1418,8 @@ static int tlmi_analyze(void) >>>> char *p; >>>> >>>> tlmi_priv.setting[i] = NULL; >>>> - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>>> - if (ACPI_FAILURE(status)) >>>> + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>>> + if (ret) >>>> break; >>>> if (!item) >>>> break; >>>> >>>> >>>>> Also current_value_show() is used by attr_current_val, the __ATTR_RW_MODE() macro arranges for that. >>>> >>>> Thanks. >>>> >>>> In this build: >>>> >>>> [root@pc-mtodorov marvin]# uname -rms >>>> Linux 6.3.0-rc34tests-00001-g6981739a967c x86_64 >>>> [root@pc-mtodorov marvin]# >>>> >>>> ... the bug isn't present, so it might be something added recently: >>>> >>>> commit 8a02d70679fc1c434401863333c8ea7dbf201494 >>>> Author: Mark Pearson <mpearson-lenovo@squebb.ca> >>>> Date: Sun Mar 19 20:32:21 2023 -0400 >>>> >>>> platform/x86: think-lmi: Add possible_values for ThinkStation >>>> >>>> commit cf337f27f3bfc4aeab4954c468239fd6233c7638 >>>> Author: Mark Pearson <mpearson-lenovo@squebb.ca> >>>> Date: Sun Mar 19 20:32:20 2023 -0400 >>>> >>>> platform/x86: think-lmi: only display possible_values if available >>>> >>>> commit 45e21289bfc6e257885514790a8a8887da822d40 >>>> Author: Mark Pearson <mpearson-lenovo@squebb.ca> >>>> Date: Sun Mar 19 20:32:19 2023 -0400 >>>> >>>> platform/x86: think-lmi: use correct possible_values delimiters >>>> >>>> commit 583329dcf22e568a328a944f20427ccfc95dce01 >>>> Author: Mark Pearson <mpearson-lenovo@squebb.ca> >>>> Date: Sun Mar 19 20:32:18 2023 -0400 >>>> >>>> platform/x86: think-lmi: add missing type attribute >>>> >>>> I have CC:-ed the author of the commits. >>>> >>>> I can try bisect, but only after my day job. >>> I seem to have been right about the culprit commit. >>> Here is the bisect log: >>> mtodorov@domac:~/linux/kernel/linux_torvalds$ git bisect log >>> git bisect start '--' './drivers/platform/x86' >>> # good: [caa0708a81d6a2217c942959ef40d515ec1d3108] bootconfig: Change message if no bootconfig with CONFIG_BOOT_CONFIG_FORCE=y >>> git bisect good caa0708a81d6a2217c942959ef40d515ec1d3108 >>> # bad: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation >>> git bisect bad 8a02d70679fc1c434401863333c8ea7dbf201494 >>> # good: [1a0009abfa7893b9cfcd3884658af1cbee6b26ce] platform: mellanox: mlx-platform: Initialize shift variable to 0 >>> git bisect good 1a0009abfa7893b9cfcd3884658af1cbee6b26ce >>> # good: [b7c994f8c35e916e27c60803bb21457bc1373500] platform/x86 (gigabyte-wmi): Add support for A320M-S2H V2 >>> git bisect good b7c994f8c35e916e27c60803bb21457bc1373500 >>> # good: [45e21289bfc6e257885514790a8a8887da822d40] platform/x86: think-lmi: use correct possible_values delimiters >>> git bisect good 45e21289bfc6e257885514790a8a8887da822d40 >>> # good: [cf337f27f3bfc4aeab4954c468239fd6233c7638] platform/x86: think-lmi: only display possible_values if available >>> git bisect good cf337f27f3bfc4aeab4954c468239fd6233c7638 >>> # first bad commit: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation >>> mtodorov@domac:~/linux/kernel/linux_torvalds$ >>> Please see below. >>> Apparently, this commit broke something on my Lenovo box: >>> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >>> index e190fec26021..3f0641360251 100644 >>> --- a/drivers/platform/x86/think-lmi.c >>> +++ b/drivers/platform/x86/think-lmi.c >>> @@ -941,9 +941,6 @@ static ssize_t possible_values_show(struct kobject *kobj, struct kobj_attribute >>> { >>> struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); >>> - if (!tlmi_priv.can_get_bios_selections) >>> - return -EOPNOTSUPP; >>> - >>> return sysfs_emit(buf, "%s\n", setting->possible_values); >>> } >>> @@ -1052,6 +1049,18 @@ static struct kobj_attribute attr_current_val = __ATTR_RW_MODE(current_value, 06 >>> static struct kobj_attribute attr_type = __ATTR_RO(type); >>> +static umode_t attr_is_visible(struct kobject *kobj, >>> + struct attribute *attr, int n) >>> +{ >>> + struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); >>> + >>> + /* We don't want to display possible_values attributes if not available */ >>> + if ((attr == &attr_possible_values.attr) && (!setting->possible_values)) >>> + return 0; >>> + >>> + return attr->mode; >>> +} >>> + >>> static struct attribute *tlmi_attrs[] = { >>> &attr_displ_name.attr, >>> &attr_current_val.attr, >>> @@ -1061,6 +1070,7 @@ static struct attribute *tlmi_attrs[] = { >>> }; >>> static const struct attribute_group tlmi_attr_group = { >>> + .is_visible = attr_is_visible, >>> .attrs = tlmi_attrs, >>> }; >>> Hope this helps narrow down the problem. >>> Best regards, >>> Mirsad >>> Why aren't you looking at the wmi.c driver? That should be >>>>>>> … >> >> mtodorov@domac:~/linux/kernel/linux_torvalds$ git bisect log >> git bisect start '--' './drivers/platform/x86' >> # good: [caa0708a81d6a2217c942959ef40d515ec1d3108] bootconfig: Change message if no bootconfig with CONFIG_BOOT_CONFIG_FORCE=y >> git bisect good caa0708a81d6a2217c942959ef40d515ec1d3108 >> # bad: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation >> git bisect bad 8a02d70679fc1c434401863333c8ea7dbf201494 >> # good: [1a0009abfa7893b9cfcd3884658af1cbee6b26ce] platform: mellanox: mlx-platform: Initialize shift variable to 0 >> git bisect good 1a0009abfa7893b9cfcd3884658af1cbee6b26ce >> # good: [b7c994f8c35e916e27c60803bb21457bc1373500] platform/x86 (gigabyte-wmi): Add support for A320M-S2H V2 >> git bisect good b7c994f8c35e916e27c60803bb21457bc1373500 >> # good: [45e21289bfc6e257885514790a8a8887da822d40] platform/x86: think-lmi: use correct possible_values delimiters >> git bisect good 45e21289bfc6e257885514790a8a8887da822d40 >> # good: [cf337f27f3bfc4aeab4954c468239fd6233c7638] platform/x86: think-lmi: only display possible_values if available >> git bisect good cf337f27f3bfc4aeab4954c468239fd6233c7638 >> # first bad commit: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation >> mtodorov@domac:~/linux/kernel/linux_torvalds$ >> >> So the commit that triggered the bug on the Lenovo desktop box was: >> >> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >> index 3f0641360251..c816646eb661 100644 >> --- a/drivers/platform/x86/think-lmi.c >> +++ b/drivers/platform/x86/think-lmi.c >> @@ -1450,6 +1450,26 @@ static int tlmi_analyze(void) >> if (ret || !setting->possible_values) >> pr_info("Error retrieving possible values for %d : %s\n", >> i, setting->display_name); >> + } else { >> + /* >> + * Older Thinkstations don't support the bios_selections API. >> + * Instead they store this as a [Optional:Option1,Option2] section of the >> + * name string. >> + * Try and pull that out if it's available. >> + */ >> + char *item, *optstart, *optend; >> + >> + if (!tlmi_setting(setting->index, &item, LENOVO_BIOS_SETTING_GUID)) { >> + optstart = strstr(item, "[Optional:"); >> + if (optstart) { >> + optstart += strlen("[Optional:"); >> + optend = strstr(optstart, "]"); >> + if (optend) >> + setting->possible_values = >> + kstrndup(optstart, optend - optstart, >> + GFP_KERNEL); > > I guess item needs to be freed here. > > (Next week I have access to my Lenovo machine again. > I'll look at it then if it's not solved.) Yes, thank you, Thomas, I am just building with the following patch: diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index c816646eb661..e8c28f4f5a71 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -1469,6 +1469,7 @@ static int tlmi_analyze(void) kstrndup(optstart, optend - optstart, GFP_KERNEL); } + kfree(item); } } /* You were 3 minutes faster ;-) The build with this patch is finished. Apparently, that was the culprit, for now I get: [root@pc-mtodorov marvin]# cat /sys/kernel/debug/kmemleak unreferenced object 0xffff8fa859c89f10 (size 16): comm "kworker/u12:5", pid 369, jiffies 4294897651 (age 91.724s) hex dump (first 16 bytes): 6d 65 6d 73 74 69 63 6b 30 00 cc cc cc cc cc cc memstick0....... backtrace: [<ffffffff8ef0a8fc>] slab_post_alloc_hook+0x8c/0x3e0 [<ffffffff8ef12289>] __kmem_cache_alloc_node+0x1d9/0x2a0 [<ffffffff8ee85719>] __kmalloc_node_track_caller+0x59/0x1f0 [<ffffffff8ee749da>] kstrdup+0x3a/0x70 [<ffffffff8ee74a4c>] kstrdup_const+0x2c/0x40 [<ffffffff8f2c0a3c>] kvasprintf_const+0x7c/0xb0 [<ffffffff8fc5f427>] kobject_set_name_vargs+0x27/0xa0 [<ffffffff8f5a79f7>] dev_set_name+0x57/0x80 [<ffffffffc0cd2f0f>] memstick_check+0x10f/0x3b0 [memstick] [<ffffffff8ebd41d0>] process_one_work+0x250/0x600 [<ffffffff8ebd45d8>] worker_thread+0x48/0x3a0 [<ffffffff8ebdfdef>] kthread+0x10f/0x140 [<ffffffff8ea03089>] ret_from_fork+0x29/0x50 unreferenced object 0xffff8fa859c89d90 (size 16): comm "kworker/u12:5", pid 369, jiffies 4294897656 (age 91.704s) hex dump (first 16 bytes): 6d 65 6d 73 74 69 63 6b 30 00 cc cc cc cc cc cc memstick0....... backtrace: [<ffffffff8ef0a8fc>] slab_post_alloc_hook+0x8c/0x3e0 [<ffffffff8ef12289>] __kmem_cache_alloc_node+0x1d9/0x2a0 [<ffffffff8ee85719>] __kmalloc_node_track_caller+0x59/0x1f0 [<ffffffff8ee749da>] kstrdup+0x3a/0x70 [<ffffffff8ee74a4c>] kstrdup_const+0x2c/0x40 [<ffffffff8f2c0a3c>] kvasprintf_const+0x7c/0xb0 [<ffffffff8fc5f427>] kobject_set_name_vargs+0x27/0xa0 [<ffffffff8f5a79f7>] dev_set_name+0x57/0x80 [<ffffffffc0cd2f0f>] memstick_check+0x10f/0x3b0 [memstick] [<ffffffff8ebd41d0>] process_one_work+0x250/0x600 [<ffffffff8ebd45d8>] worker_thread+0x48/0x3a0 [<ffffffff8ebdfdef>] kthread+0x10f/0x140 [<ffffffff8ea03089>] ret_from_fork+0x29/0x50 [root@pc-mtodorov marvin]# So, the "tlmi_setting" memory leak appears to be fixed by this diff. The next step is to add Armin-suggested patch: diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index c816646eb661..1e77ecb0cba8 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a /* validate and split from `item,value` -> `value` */ value = strpbrk(item, ","); - if (!value || value == item || !strlen(value + 1)) + if (!value || value == item || !strlen(value + 1)) { + kfree(item); return -EINVAL; + } ret = sysfs_emit(buf, "%s\n", value + 1); kfree(item); and Thomas' correction for the return type of the tlmi_setting() function: diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index 86b33b74519be..c924e9e4a6a5b 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -1353,7 +1353,6 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type, static int tlmi_analyze(void) { - acpi_status status; int i, ret; if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && @@ -1390,8 +1389,8 @@ static int tlmi_analyze(void) char *p; tlmi_priv.setting[i] = NULL; - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); - if (ACPI_FAILURE(status)) + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); + if (ret) break; if (!item) break; A build on top of 6.3-rc4+ fcd476ea6a88 commit is on the way, with all three included. Best regards, Mirsad -- Mirsad Todorovac System engineer Faculty of Graphic Arts | Academy of Fine Arts University of Zagreb Republic of Croatia, the European Union Sistem inženjer Grafički fakultet | Akademija likovnih umjetnosti Sveučilište u Zagrebu ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [BUG] [BISECTED] [CORRECTION] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-29 14:18 ` Mirsad Goran Todorovac @ 2023-03-29 15:46 ` Hans de Goede 2023-03-29 16:24 ` Mark Pearson 2023-03-29 16:27 ` [BUG] [BISECTED] [CORRECTION] " Mirsad Goran Todorovac 0 siblings, 2 replies; 24+ messages in thread From: Hans de Goede @ 2023-03-29 15:46 UTC (permalink / raw) To: Mirsad Goran Todorovac, Thomas Weißschuh Cc: Armin Wolf, Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, Mark Gross, platform-driver-x86, Mark Pearson Hi, On 3/29/23 16:18, Mirsad Goran Todorovac wrote: > On 29.3.2023. 15:35, Thomas Weißschuh wrote: >> >> Mar 29, 2023 08:31:31 Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>: >> >>> Hi, again, >>> >>> NOTE: I forgot to rewind to the first bad commit. So please ignore >>> the previous email. >>> >>> On 29.3.2023. 15:22, Mirsad Goran Todorovac wrote: >>>> Hi, Armin, Mr. Greg, >>>> On 29.3.2023. 10:13, Mirsad Goran Todorovac wrote: >>>>> On 28.3.2023. 21:55, Armin Wolf wrote: >>>>>> Am 28.03.23 um 21:06 schrieb Mirsad Goran Todorovac: >>>>>> >>>>>>> On 3/28/2023 6:53 PM, Armin Wolf wrote: >>>>>>>> … >>>>>>> >>>>>>> Hi Armin, >>>>>>> >>>>>>> I tried your suggestion, and though it is an obvious improvement and a >>>>>>> leak fix, this >>>>>>> was not the one we were searching for. >>>>>>> >>>>>>> I tested the following patch: >>>>>>> >>>>>>> diff --git a/drivers/platform/x86/think-lmi.c >>>>>>> b/drivers/platform/x86/think-lmi.c >>>>>>> index c816646eb661..1e77ecb0cba8 100644 >>>>>>> --- a/drivers/platform/x86/think-lmi.c >>>>>>> +++ b/drivers/platform/x86/think-lmi.c >>>>>>> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject >>>>>>> *kobj, struct kobj_attribute *a >>>>>>> >>>>>>> /* validate and split from `item,value` -> `value` */ >>>>>>> value = strpbrk(item, ","); >>>>>>> - if (!value || value == item || !strlen(value + 1)) >>>>>>> + if (!value || value == item || !strlen(value + 1)) { >>>>>>> + kfree(item); >>>>>>> return -EINVAL; >>>>>>> + } >>>>>>> >>>>>>> ret = sysfs_emit(buf, "%s\n", value + 1); >>>>>>> kfree(item); >>>>>>> >>>>>>> (I would also object to the use of strlen() here, for it is inherently >>>>>>> insecure >>>>>>> against SEGFAULT in kernel space.) >>>>>>> >>>>>>> I still get: >>>>>>> [root@pc-mtodorov marvin]# uname -rms >>>>>>> Linux 6.3.0-rc4-armin-patch-00025-g3a93e40326c8-dirty x86_64 >>>>>>> [root@pc-mtodorov marvin]# cat /sys/kernel/debug/kmemleak [edited] >>>>>>> unreferenced object 0xffff8eb008ef9260 (size 96): >>>>>>> comm "systemd-udevd", pid 771, jiffies 4294896499 (age 74.880s) >>>>>>> hex dump (first 32 bytes): >>>>>>> 53 65 72 69 61 6c 50 6f 72 74 31 41 64 64 72 65 SerialPort1Addre >>>>>>> 73 73 2c 33 46 38 2f 49 52 51 34 3b 5b 4f 70 74 ss,3F8/IRQ4;[Opt >>>>>>> backtrace: >>>>>>> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>>>> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>>>> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>>>> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >>>>>>> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >>>>>>> [think_lmi] >>>>>>> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>>>>> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>>>> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>>>> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >>>>>>> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >>>>>>> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >>>>>>> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >>>>>>> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >>>>>>> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >>>>>>> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >>>>>>> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >>>>>>> unreferenced object 0xffff8eb018ddbb40 (size 64): >>>>>>> comm "systemd-udevd", pid 771, jiffies 4294896528 (age 74.780s) >>>>>>> hex dump (first 32 bytes): >>>>>>> 55 53 42 50 6f 72 74 41 63 63 65 73 73 2c 45 6e USBPortAccess,En >>>>>>> 61 62 6c 65 64 3b 5b 4f 70 74 69 6f 6e 61 6c 3a abled;[Optional: >>>>>>> backtrace: >>>>>>> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>>>> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>>>> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>>>> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >>>>>>> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >>>>>>> [think_lmi] >>>>>>> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>>>>> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>>>> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>>>> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >>>>>>> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >>>>>>> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >>>>>>> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >>>>>>> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >>>>>>> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >>>>>>> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >>>>>>> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >>>>>>> unreferenced object 0xffff8eb006fe2b40 (size 64): >>>>>>> comm "systemd-udevd", pid 771, jiffies 4294896542 (age 74.724s) >>>>>>> hex dump (first 32 bytes): >>>>>>> 55 53 42 42 49 4f 53 53 75 70 70 6f 72 74 2c 45 USBBIOSSupport,E >>>>>>> 6e 61 62 6c 65 64 3b 5b 4f 70 74 69 6f 6e 61 6c nabled;[Optional >>>>>>> backtrace: >>>>>>> [<ffffffff9eafb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>>>> [<ffffffff9eb02b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>>>> [<ffffffff9ea773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>>>> [<ffffffff9ea66a1a>] kstrdup+0x3a/0x70 >>>>>>> [<ffffffffc0eef9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 >>>>>>> [think_lmi] >>>>>>> [<ffffffffc0eefb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>>>>> [<ffffffffc0ef02c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>>>> [<ffffffffc0629c53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>>>> [<ffffffff9f1987eb>] really_probe+0x17b/0x3d0 >>>>>>> [<ffffffff9f198ad4>] __driver_probe_device+0x84/0x190 >>>>>>> [<ffffffff9f198c14>] driver_probe_device+0x24/0xc0 >>>>>>> [<ffffffff9f198ed2>] __driver_attach+0xc2/0x190 >>>>>>> [<ffffffff9f195ab1>] bus_for_each_dev+0x81/0xd0 >>>>>>> [<ffffffff9f197c62>] driver_attach+0x22/0x30 >>>>>>> [<ffffffff9f197354>] bus_add_driver+0x1b4/0x240 >>>>>>> [<ffffffff9f19a0a2>] driver_register+0x62/0x120 >>>>>>> >>>>>>> There are currently 84 wmi_dev_probe leaks, sized mostly 64 bytes, and >>>>>>> one 96 and two 192 bytes. >>>>>>> >>>>>>> I also cannot figure out the mechanism by which current_value_show() >>>>>>> is called, when it is static? >>>>>>> >>>>>>> Any idea? >>>>>>> >>>>>>> Thanks. >>>>>>> >>>>>>> Best regards, >>>>>>> Mirsad >>>>>>> >>>>>> Can you tell me how many BIOS settings think-lmi provides on your machine? Because according to the stacktrace, >>>>>> the other place where the leak could have occurred is inside tlmi_analyze(), which calls tlmi_setting(). >>>>> >>>>> Yes, Sir! >>>>> >>>>> I think these could be the ones you need (totaling 83, which is close to 82 systemd-udevd leaks): >>>>> >>>>> [root@pc-mtodorov marvin]# ls -l /sys/devices/virtual/firmware-attributes/thinklmi/attributes | grep ^d >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 AfterPowerLoss >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmDate(MM\DD\YYYY) >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmDayofWeek >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 AlarmTime(HH:MM:SS) >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ASPMSupport >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 AutomaticBootSequence >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtBootDeviceList >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtReboot >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BIOSPasswordAtUnattendedBoot >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BootMode >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BootPriority >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 BootUpNum-LockStatus >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 C1ESupport >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 CardReader >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ClearTCGSecurityFeature >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ComputraceModuleActivation >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ConfigurationChangeDetection >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ConfigureSATAas >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 CoreMulti-Processing >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 CoverTamperDetected >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 CSM >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 CStateSupport >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 DeviceGuard >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 DustShieldAlert >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 EISTSupport >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 EnhancedPowerSavingMode >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 ErrorBootSequence >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Friday >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 FrontUSBPorts >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 HardDiskPre-delay >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Intel(R)SGXControl >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 InternalSpeaker >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Monday >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 OnboardAudioController >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 OnboardEthernetController >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 OptionKeysDisplay >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 OptionKeysDisplayStyle >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 OSOptimizedDefaults >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PasswordCountExceededError >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PCIe16xSlotSpeed >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PCIe1xSlot1Speed >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PrimaryBootSequence >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEIPV4NetworkStack >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEIPV6NetworkStack >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 PXEOptionROM >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 RearUSBPorts >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 RequireAdmin.Pass.whenFlashing >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 RequireHDPonSystemBoot >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SATAController >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SATADrive1 >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SATADrive2 >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Saturday >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SecureBoot >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SecureRollBackPrevention >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SecurityChip >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SelectActiveVideo >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SerialPort1Address >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 SmartUSBProtection >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 StartupDeviceMenuPrompt >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 StartupSequence >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Sunday >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Thursday >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Tuesday >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 TurboMode >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBBIOSSupport >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBEnumerationDelay >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort1 >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort2 >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort3 >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort4 >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort5 >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort6 >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort7 >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPort8 >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 USBPortAccess >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 UserDefinedAlarmTime(HH:MM:SS) >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 VirtualizationTechnology >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 VTdFeature >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 WakefromSerialPortRing >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 WakeOnLAN >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 WakeUponAlarm >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 Wednesday >>>>> drwxr-xr-x 2 root root 0 Mar 29 08:24 WindowsUEFIFirmwareUpdate >>>>> [root@pc-mtodorov marvin]# ls -l /sys/devices/virtual/firmware-attributes/thinklmi/attributes | grep ^d | wc -l >>>>> 83 >>>>> [root@pc-mtodorov marvin]# >>>>> >>>>>> However, i have no idea on how *info is somehow leaked, it has to happen inside the for-loop tween the call >>>>>> to tlmi_setting() and strreplace(), because otherwise the strings would not contain the "/" character. >>>>> >>>>> I see. It is the line 1404. >>>>> >>>>>> Can you check if the problem is somehow solved by applying the following commit from the platform-drivers-x86 >>>>>> for-next branch: >>>>>> da62908efe80 ("platform/x86: think-lmi: Properly interpret return value of tlmi_setting") >>>>> >>>>> It could possibly be that. But I do not recall seeing these messages in 6.3-rc3 ... >>>>> >>>>> ... >>>>> >>>>> Unfortunately, the build with Thomas' patch you referred to did not work: >>>>> >>>>> unreferenced object 0xffff9dff4d28bbc8 (size 192): >>>>> comm "systemd-udevd", pid 769, jiffies 4294897473 (age 85.700s) >>>>> hex dump (first 32 bytes): >>>>> 50 72 69 6d 61 72 79 42 6f 6f 74 53 65 71 75 65 PrimaryBootSeque >>>>> 6e 63 65 2c 4d 2e 32 20 44 72 69 76 65 20 31 3a nce,M.2 Drive 1: >>>>> backtrace: >>>>> [<ffffffffa48fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>> [<ffffffffa4902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>> [<ffffffffa48773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>> [<ffffffffa4866a1a>] kstrdup+0x3a/0x70 >>>>> [<ffffffffc0c7f9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >>>>> [<ffffffffc0c7fb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>>> [<ffffffffc0c802c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>> [<ffffffffc03c9c53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>> [<ffffffffa4f987eb>] really_probe+0x17b/0x3d0 >>>>> [<ffffffffa4f98ad4>] __driver_probe_device+0x84/0x190 >>>>> [<ffffffffa4f98c14>] driver_probe_device+0x24/0xc0 >>>>> [<ffffffffa4f98ed2>] __driver_attach+0xc2/0x190 >>>>> [<ffffffffa4f95ab1>] bus_for_each_dev+0x81/0xd0 >>>>> [<ffffffffa4f97c62>] driver_attach+0x22/0x30 >>>>> [<ffffffffa4f97354>] bus_add_driver+0x1b4/0x240 >>>>> [<ffffffffa4f9a0a2>] driver_register+0x62/0x120 >>>>> unreferenced object 0xffff9dff4d28a008 (size 192): >>>>> comm "systemd-udevd", pid 769, jiffies 4294897517 (age 85.540s) >>>>> hex dump (first 32 bytes): >>>>> 45 72 72 6f 72 42 6f 6f 74 53 65 71 75 65 6e 63 ErrorBootSequenc >>>>> 65 2c 4e 65 74 77 6f 72 6b 20 31 3a 4d 2e 32 20 e,Network 1:M.2 >>>>> backtrace: >>>>> [<ffffffffa48fb26c>] slab_post_alloc_hook+0x8c/0x3e0 >>>>> [<ffffffffa4902b49>] __kmem_cache_alloc_node+0x1d9/0x2a0 >>>>> [<ffffffffa48773c9>] __kmalloc_node_track_caller+0x59/0x180 >>>>> [<ffffffffa4866a1a>] kstrdup+0x3a/0x70 >>>>> [<ffffffffc0c7f9aa>] tlmi_extract_output_string.isra.0+0x2a/0x60 [think_lmi] >>>>> [<ffffffffc0c7fb64>] tlmi_setting.constprop.4+0x54/0x90 [think_lmi] >>>>> [<ffffffffc0c802c1>] tlmi_probe+0x591/0xba0 [think_lmi] >>>>> [<ffffffffc03c9c53>] wmi_dev_probe+0x163/0x230 [wmi] >>>>> [<ffffffffa4f987eb>] really_probe+0x17b/0x3d0 >>>>> [<ffffffffa4f98ad4>] __driver_probe_device+0x84/0x190 >>>>> [<ffffffffa4f98c14>] driver_probe_device+0x24/0xc0 >>>>> [<ffffffffa4f98ed2>] __driver_attach+0xc2/0x190 >>>>> [<ffffffffa4f95ab1>] bus_for_each_dev+0x81/0xd0 >>>>> [<ffffffffa4f97c62>] driver_attach+0x22/0x30 >>>>> [<ffffffffa4f97354>] bus_add_driver+0x1b4/0x240 >>>>> [<ffffffffa4f9a0a2>] driver_register+0x62/0x120 >>>>> [root@pc-mtodorov marvin]# uname -rms >>>>> Linux 6.3.0-rc4-armin+tw-patch-00025-g3a93e40326c8-dirty x86_64 >>>>> [root@pc-mtodorov marvin]# >>>>> >>>>> What was applied is: >>>>> >>>>> mtodorov@domac:~/linux/kernel/linux_torvalds$ git diff >>>>> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >>>>> index c816646eb661..9a3015f43aaf 100644 >>>>> --- a/drivers/platform/x86/think-lmi.c >>>>> +++ b/drivers/platform/x86/think-lmi.c >>>>> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a >>>>> >>>>> /* validate and split from `item,value` -> `value` */ >>>>> value = strpbrk(item, ","); >>>>> - if (!value || value == item || !strlen(value + 1)) >>>>> + if (!value || value == item || !strlen(value + 1)) { >>>>> + kfree(item); >>>>> return -EINVAL; >>>>> + } >>>>> >>>>> ret = sysfs_emit(buf, "%s\n", value + 1); >>>>> kfree(item); >>>>> @@ -1380,7 +1382,6 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type, >>>>> >>>>> static int tlmi_analyze(void) >>>>> { >>>>> - acpi_status status; >>>>> int i, ret; >>>>> >>>>> if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && >>>>> @@ -1417,8 +1418,8 @@ static int tlmi_analyze(void) >>>>> char *p; >>>>> >>>>> tlmi_priv.setting[i] = NULL; >>>>> - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>>>> - if (ACPI_FAILURE(status)) >>>>> + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>>>> + if (ret) >>>>> break; >>>>> if (!item) >>>>> break; >>>>> >>>>> >>>>>> Also current_value_show() is used by attr_current_val, the __ATTR_RW_MODE() macro arranges for that. >>>>> >>>>> Thanks. >>>>> >>>>> In this build: >>>>> >>>>> [root@pc-mtodorov marvin]# uname -rms >>>>> Linux 6.3.0-rc34tests-00001-g6981739a967c x86_64 >>>>> [root@pc-mtodorov marvin]# >>>>> >>>>> ... the bug isn't present, so it might be something added recently: >>>>> >>>>> commit 8a02d70679fc1c434401863333c8ea7dbf201494 >>>>> Author: Mark Pearson <mpearson-lenovo@squebb.ca> >>>>> Date: Sun Mar 19 20:32:21 2023 -0400 >>>>> >>>>> platform/x86: think-lmi: Add possible_values for ThinkStation >>>>> >>>>> commit cf337f27f3bfc4aeab4954c468239fd6233c7638 >>>>> Author: Mark Pearson <mpearson-lenovo@squebb.ca> >>>>> Date: Sun Mar 19 20:32:20 2023 -0400 >>>>> >>>>> platform/x86: think-lmi: only display possible_values if available >>>>> >>>>> commit 45e21289bfc6e257885514790a8a8887da822d40 >>>>> Author: Mark Pearson <mpearson-lenovo@squebb.ca> >>>>> Date: Sun Mar 19 20:32:19 2023 -0400 >>>>> >>>>> platform/x86: think-lmi: use correct possible_values delimiters >>>>> >>>>> commit 583329dcf22e568a328a944f20427ccfc95dce01 >>>>> Author: Mark Pearson <mpearson-lenovo@squebb.ca> >>>>> Date: Sun Mar 19 20:32:18 2023 -0400 >>>>> >>>>> platform/x86: think-lmi: add missing type attribute >>>>> >>>>> I have CC:-ed the author of the commits. >>>>> >>>>> I can try bisect, but only after my day job. >>>> I seem to have been right about the culprit commit. >>>> Here is the bisect log: >>>> mtodorov@domac:~/linux/kernel/linux_torvalds$ git bisect log >>>> git bisect start '--' './drivers/platform/x86' >>>> # good: [caa0708a81d6a2217c942959ef40d515ec1d3108] bootconfig: Change message if no bootconfig with CONFIG_BOOT_CONFIG_FORCE=y >>>> git bisect good caa0708a81d6a2217c942959ef40d515ec1d3108 >>>> # bad: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation >>>> git bisect bad 8a02d70679fc1c434401863333c8ea7dbf201494 >>>> # good: [1a0009abfa7893b9cfcd3884658af1cbee6b26ce] platform: mellanox: mlx-platform: Initialize shift variable to 0 >>>> git bisect good 1a0009abfa7893b9cfcd3884658af1cbee6b26ce >>>> # good: [b7c994f8c35e916e27c60803bb21457bc1373500] platform/x86 (gigabyte-wmi): Add support for A320M-S2H V2 >>>> git bisect good b7c994f8c35e916e27c60803bb21457bc1373500 >>>> # good: [45e21289bfc6e257885514790a8a8887da822d40] platform/x86: think-lmi: use correct possible_values delimiters >>>> git bisect good 45e21289bfc6e257885514790a8a8887da822d40 >>>> # good: [cf337f27f3bfc4aeab4954c468239fd6233c7638] platform/x86: think-lmi: only display possible_values if available >>>> git bisect good cf337f27f3bfc4aeab4954c468239fd6233c7638 >>>> # first bad commit: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation >>>> mtodorov@domac:~/linux/kernel/linux_torvalds$ >>>> Please see below. >>>> Apparently, this commit broke something on my Lenovo box: >>>> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >>>> index e190fec26021..3f0641360251 100644 >>>> --- a/drivers/platform/x86/think-lmi.c >>>> +++ b/drivers/platform/x86/think-lmi.c >>>> @@ -941,9 +941,6 @@ static ssize_t possible_values_show(struct kobject *kobj, struct kobj_attribute >>>> { >>>> struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); >>>> - if (!tlmi_priv.can_get_bios_selections) >>>> - return -EOPNOTSUPP; >>>> - >>>> return sysfs_emit(buf, "%s\n", setting->possible_values); >>>> } >>>> @@ -1052,6 +1049,18 @@ static struct kobj_attribute attr_current_val = __ATTR_RW_MODE(current_value, 06 >>>> static struct kobj_attribute attr_type = __ATTR_RO(type); >>>> +static umode_t attr_is_visible(struct kobject *kobj, >>>> + struct attribute *attr, int n) >>>> +{ >>>> + struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); >>>> + >>>> + /* We don't want to display possible_values attributes if not available */ >>>> + if ((attr == &attr_possible_values.attr) && (!setting->possible_values)) >>>> + return 0; >>>> + >>>> + return attr->mode; >>>> +} >>>> + >>>> static struct attribute *tlmi_attrs[] = { >>>> &attr_displ_name.attr, >>>> &attr_current_val.attr, >>>> @@ -1061,6 +1070,7 @@ static struct attribute *tlmi_attrs[] = { >>>> }; >>>> static const struct attribute_group tlmi_attr_group = { >>>> + .is_visible = attr_is_visible, >>>> .attrs = tlmi_attrs, >>>> }; >>>> Hope this helps narrow down the problem. >>>> Best regards, >>>> Mirsad >>>> Why aren't you looking at the wmi.c driver? That should be >>>>>>>> … >>> >>> mtodorov@domac:~/linux/kernel/linux_torvalds$ git bisect log >>> git bisect start '--' './drivers/platform/x86' >>> # good: [caa0708a81d6a2217c942959ef40d515ec1d3108] bootconfig: Change message if no bootconfig with CONFIG_BOOT_CONFIG_FORCE=y >>> git bisect good caa0708a81d6a2217c942959ef40d515ec1d3108 >>> # bad: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation >>> git bisect bad 8a02d70679fc1c434401863333c8ea7dbf201494 >>> # good: [1a0009abfa7893b9cfcd3884658af1cbee6b26ce] platform: mellanox: mlx-platform: Initialize shift variable to 0 >>> git bisect good 1a0009abfa7893b9cfcd3884658af1cbee6b26ce >>> # good: [b7c994f8c35e916e27c60803bb21457bc1373500] platform/x86 (gigabyte-wmi): Add support for A320M-S2H V2 >>> git bisect good b7c994f8c35e916e27c60803bb21457bc1373500 >>> # good: [45e21289bfc6e257885514790a8a8887da822d40] platform/x86: think-lmi: use correct possible_values delimiters >>> git bisect good 45e21289bfc6e257885514790a8a8887da822d40 >>> # good: [cf337f27f3bfc4aeab4954c468239fd6233c7638] platform/x86: think-lmi: only display possible_values if available >>> git bisect good cf337f27f3bfc4aeab4954c468239fd6233c7638 >>> # first bad commit: [8a02d70679fc1c434401863333c8ea7dbf201494] platform/x86: think-lmi: Add possible_values for ThinkStation >>> mtodorov@domac:~/linux/kernel/linux_torvalds$ >>> >>> So the commit that triggered the bug on the Lenovo desktop box was: >>> >>> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >>> index 3f0641360251..c816646eb661 100644 >>> --- a/drivers/platform/x86/think-lmi.c >>> +++ b/drivers/platform/x86/think-lmi.c >>> @@ -1450,6 +1450,26 @@ static int tlmi_analyze(void) >>> if (ret || !setting->possible_values) >>> pr_info("Error retrieving possible values for %d : %s\n", >>> i, setting->display_name); >>> + } else { >>> + /* >>> + * Older Thinkstations don't support the bios_selections API. >>> + * Instead they store this as a [Optional:Option1,Option2] section of the >>> + * name string. >>> + * Try and pull that out if it's available. >>> + */ >>> + char *item, *optstart, *optend; >>> + >>> + if (!tlmi_setting(setting->index, &item, LENOVO_BIOS_SETTING_GUID)) { >>> + optstart = strstr(item, "[Optional:"); >>> + if (optstart) { >>> + optstart += strlen("[Optional:"); >>> + optend = strstr(optstart, "]"); >>> + if (optend) >>> + setting->possible_values = >>> + kstrndup(optstart, optend - optstart, >>> + GFP_KERNEL); >> >> I guess item needs to be freed here. >> >> (Next week I have access to my Lenovo machine again. >> I'll look at it then if it's not solved.) > > Yes, thank you, Thomas, I am just building with the following patch: > > diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c > index c816646eb661..e8c28f4f5a71 100644 > --- a/drivers/platform/x86/think-lmi.c > +++ b/drivers/platform/x86/think-lmi.c > @@ -1469,6 +1469,7 @@ static int tlmi_analyze(void) > kstrndup(optstart, optend - optstart, > GFP_KERNEL); > } > + kfree(item); > } > } > /* > > You were 3 minutes faster ;-) > > The build with this patch is finished. Apparently, that was the culprit, for now > I get: > > [root@pc-mtodorov marvin]# cat /sys/kernel/debug/kmemleak > unreferenced object 0xffff8fa859c89f10 (size 16): > comm "kworker/u12:5", pid 369, jiffies 4294897651 (age 91.724s) > hex dump (first 16 bytes): > 6d 65 6d 73 74 69 63 6b 30 00 cc cc cc cc cc cc memstick0....... > backtrace: > [<ffffffff8ef0a8fc>] slab_post_alloc_hook+0x8c/0x3e0 > [<ffffffff8ef12289>] __kmem_cache_alloc_node+0x1d9/0x2a0 > [<ffffffff8ee85719>] __kmalloc_node_track_caller+0x59/0x1f0 > [<ffffffff8ee749da>] kstrdup+0x3a/0x70 > [<ffffffff8ee74a4c>] kstrdup_const+0x2c/0x40 > [<ffffffff8f2c0a3c>] kvasprintf_const+0x7c/0xb0 > [<ffffffff8fc5f427>] kobject_set_name_vargs+0x27/0xa0 > [<ffffffff8f5a79f7>] dev_set_name+0x57/0x80 > [<ffffffffc0cd2f0f>] memstick_check+0x10f/0x3b0 [memstick] > [<ffffffff8ebd41d0>] process_one_work+0x250/0x600 > [<ffffffff8ebd45d8>] worker_thread+0x48/0x3a0 > [<ffffffff8ebdfdef>] kthread+0x10f/0x140 > [<ffffffff8ea03089>] ret_from_fork+0x29/0x50 > unreferenced object 0xffff8fa859c89d90 (size 16): > comm "kworker/u12:5", pid 369, jiffies 4294897656 (age 91.704s) > hex dump (first 16 bytes): > 6d 65 6d 73 74 69 63 6b 30 00 cc cc cc cc cc cc memstick0....... > backtrace: > [<ffffffff8ef0a8fc>] slab_post_alloc_hook+0x8c/0x3e0 > [<ffffffff8ef12289>] __kmem_cache_alloc_node+0x1d9/0x2a0 > [<ffffffff8ee85719>] __kmalloc_node_track_caller+0x59/0x1f0 > [<ffffffff8ee749da>] kstrdup+0x3a/0x70 > [<ffffffff8ee74a4c>] kstrdup_const+0x2c/0x40 > [<ffffffff8f2c0a3c>] kvasprintf_const+0x7c/0xb0 > [<ffffffff8fc5f427>] kobject_set_name_vargs+0x27/0xa0 > [<ffffffff8f5a79f7>] dev_set_name+0x57/0x80 > [<ffffffffc0cd2f0f>] memstick_check+0x10f/0x3b0 [memstick] > [<ffffffff8ebd41d0>] process_one_work+0x250/0x600 > [<ffffffff8ebd45d8>] worker_thread+0x48/0x3a0 > [<ffffffff8ebdfdef>] kthread+0x10f/0x140 > [<ffffffff8ea03089>] ret_from_fork+0x29/0x50 > [root@pc-mtodorov marvin]# > > So, the "tlmi_setting" memory leak appears to be fixed by this diff. > > The next step is to add Armin-suggested patch: > > diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c > index c816646eb661..1e77ecb0cba8 100644 > --- a/drivers/platform/x86/think-lmi.c > +++ b/drivers/platform/x86/think-lmi.c > @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a > > /* validate and split from `item,value` -> `value` */ > value = strpbrk(item, ","); > - if (!value || value == item || !strlen(value + 1)) > + if (!value || value == item || !strlen(value + 1)) { > + kfree(item); > return -EINVAL; > + } > > ret = sysfs_emit(buf, "%s\n", value + 1); > kfree(item); > > and Thomas' correction for the return type of the tlmi_setting() function: > > diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c > index 86b33b74519be..c924e9e4a6a5b 100644 > --- a/drivers/platform/x86/think-lmi.c > +++ b/drivers/platform/x86/think-lmi.c > @@ -1353,7 +1353,6 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type, > > static int tlmi_analyze(void) > { > - acpi_status status; > int i, ret; > > if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && > @@ -1390,8 +1389,8 @@ static int tlmi_analyze(void) > char *p; > > tlmi_priv.setting[i] = NULL; > - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); > - if (ACPI_FAILURE(status)) > + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); > + if (ret) > break; > if (!item) > break; > > A build on top of 6.3-rc4+ fcd476ea6a88 commit is on the way, with all three included. Good work on catching these issues, thank you all for your work on this. I assume that these fixes will be posted as a proper 3 patch patch-series (one patch per fix) once you are done testing? Regards, Hans ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] [BISECTED] [CORRECTION] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-29 15:46 ` Hans de Goede @ 2023-03-29 16:24 ` Mark Pearson 2023-03-29 16:43 ` Mirsad Goran Todorovac 2023-03-29 18:49 ` [BUG] [RFC] " Mirsad Goran Todorovac 2023-03-29 16:27 ` [BUG] [BISECTED] [CORRECTION] " Mirsad Goran Todorovac 1 sibling, 2 replies; 24+ messages in thread From: Mark Pearson @ 2023-03-29 16:24 UTC (permalink / raw) To: Hans de Goede, Mirsad Goran Todorovac, Thomas Weißschuh Cc: Armin Wolf, Greg KH, Rafael J. Wysocki, linux-kernel, markgross, platform-driver-x86 Hi On Wed, Mar 29, 2023, at 11:46 AM, Hans de Goede wrote: > Hi, > > On 3/29/23 16:18, Mirsad Goran Todorovac wrote: >> On 29.3.2023. 15:35, Thomas Weißschuh wrote: >>> >>> Mar 29, 2023 08:31:31 Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>: >>> <snip> >> >> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >> index c816646eb661..e8c28f4f5a71 100644 >> --- a/drivers/platform/x86/think-lmi.c >> +++ b/drivers/platform/x86/think-lmi.c >> @@ -1469,6 +1469,7 @@ static int tlmi_analyze(void) >> kstrndup(optstart, optend - optstart, >> GFP_KERNEL); >> } >> + kfree(item); >> } >> } >> /* >> >> You were 3 minutes faster ;-) >> >> The build with this patch is finished. Apparently, that was the culprit, for now <snip> >> >> >> So, the "tlmi_setting" memory leak appears to be fixed by this diff. >> My only concern here is it looks like I was dumb and used the variable name 'item' twice in the same function. I guess the compiler is smart enough to handle it but I'd like to change the name to make it clearer which 'item' is being freed in each context. In that block I would change it to be: char *optitem, *optstart, *optend; and fix all the pieces in the block to then be correct too (with the needed free) >> The next step is to add Armin-suggested patch: >> >> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >> index c816646eb661..1e77ecb0cba8 100644 >> --- a/drivers/platform/x86/think-lmi.c >> +++ b/drivers/platform/x86/think-lmi.c >> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a >> >> /* validate and split from `item,value` -> `value` */ >> value = strpbrk(item, ","); >> - if (!value || value == item || !strlen(value + 1)) >> + if (!value || value == item || !strlen(value + 1)) { >> + kfree(item); >> return -EINVAL; >> + } >> >> ret = sysfs_emit(buf, "%s\n", value + 1); >> kfree(item); >> This looks good to me - thank you! >> and Thomas' correction for the return type of the tlmi_setting() function: >> >> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >> index 86b33b74519be..c924e9e4a6a5b 100644 >> --- a/drivers/platform/x86/think-lmi.c >> +++ b/drivers/platform/x86/think-lmi.c >> @@ -1353,7 +1353,6 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type, >> >> static int tlmi_analyze(void) >> { >> - acpi_status status; >> int i, ret; >> >> if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && >> @@ -1390,8 +1389,8 @@ static int tlmi_analyze(void) >> char *p; >> >> tlmi_priv.setting[i] = NULL; >> - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >> - if (ACPI_FAILURE(status)) >> + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >> + if (ret) >> break; >> if (!item) >> break; >> >> A build on top of 6.3-rc4+ fcd476ea6a88 commit is on the way, with all three included. > > Good work on catching these issues, thank you all for your work on this. > Seconded - thank you for flagging and catching this. These were my mistakes :( > I assume that these fixes will be posted as a proper 3 patch > patch-series (one patch per fix) once you are done testing? > Let me know if you are happy to propose the changes as a patch-series. If you don't have time I can help and get these in ASAP as I was the original culprit. Happy to help out with testing too as I have access to HW. Let me know. Mark ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] [BISECTED] [CORRECTION] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-29 16:24 ` Mark Pearson @ 2023-03-29 16:43 ` Mirsad Goran Todorovac 2023-03-29 18:49 ` [BUG] [RFC] " Mirsad Goran Todorovac 1 sibling, 0 replies; 24+ messages in thread From: Mirsad Goran Todorovac @ 2023-03-29 16:43 UTC (permalink / raw) To: Mark Pearson, Hans de Goede, Thomas Weißschuh Cc: Armin Wolf, Greg KH, Rafael J. Wysocki, linux-kernel, markgross, platform-driver-x86 On 29.3.2023. 18:24, Mark Pearson wrote: > Hi > > On Wed, Mar 29, 2023, at 11:46 AM, Hans de Goede wrote: >> Hi, >> >> On 3/29/23 16:18, Mirsad Goran Todorovac wrote: >>> On 29.3.2023. 15:35, Thomas Weißschuh wrote: >>>> >>>> Mar 29, 2023 08:31:31 Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>: >>>> > <snip> >>> >>> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >>> index c816646eb661..e8c28f4f5a71 100644 >>> --- a/drivers/platform/x86/think-lmi.c >>> +++ b/drivers/platform/x86/think-lmi.c >>> @@ -1469,6 +1469,7 @@ static int tlmi_analyze(void) >>> kstrndup(optstart, optend - optstart, >>> GFP_KERNEL); >>> } >>> + kfree(item); >>> } >>> } >>> /* >>> >>> You were 3 minutes faster ;-) >>> >>> The build with this patch is finished. Apparently, that was the culprit, for now > <snip> >>> >>> >>> So, the "tlmi_setting" memory leak appears to be fixed by this diff. >>> > My only concern here is it looks like I was dumb and used the variable name 'item' twice in the same function. I guess the compiler is smart enough to handle it but I'd like to change the name to make it clearer which 'item' is being freed in each context. > > In that block I would change it to be: > char *optitem, *optstart, *optend; > and fix all the pieces in the block to then be correct too (with the needed free) > >>> The next step is to add Armin-suggested patch: >>> >>> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >>> index c816646eb661..1e77ecb0cba8 100644 >>> --- a/drivers/platform/x86/think-lmi.c >>> +++ b/drivers/platform/x86/think-lmi.c >>> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a >>> >>> /* validate and split from `item,value` -> `value` */ >>> value = strpbrk(item, ","); >>> - if (!value || value == item || !strlen(value + 1)) >>> + if (!value || value == item || !strlen(value + 1)) { >>> + kfree(item); >>> return -EINVAL; >>> + } >>> >>> ret = sysfs_emit(buf, "%s\n", value + 1); >>> kfree(item); >>> > This looks good to me - thank you! > >>> and Thomas' correction for the return type of the tlmi_setting() function: >>> >>> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >>> index 86b33b74519be..c924e9e4a6a5b 100644 >>> --- a/drivers/platform/x86/think-lmi.c >>> +++ b/drivers/platform/x86/think-lmi.c >>> @@ -1353,7 +1353,6 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type, >>> >>> static int tlmi_analyze(void) >>> { >>> - acpi_status status; >>> int i, ret; >>> >>> if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && >>> @@ -1390,8 +1389,8 @@ static int tlmi_analyze(void) >>> char *p; >>> >>> tlmi_priv.setting[i] = NULL; >>> - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>> - if (ACPI_FAILURE(status)) >>> + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>> + if (ret) >>> break; >>> if (!item) >>> break; >>> >>> A build on top of 6.3-rc4+ fcd476ea6a88 commit is on the way, with all three included. >> >> Good work on catching these issues, thank you all for your work on this. >> > Seconded - thank you for flagging and catching this. These were my mistakes :( Armin's hint was the largest part of the catch. I did not even suspect think-lmi.c, to be honest ... Apparently, the three patches together do not raise any new issues on my box, but of course, proper testing and peer review is required. Best regards, Mirsad >> I assume that these fixes will be posted as a proper 3 patch >> patch-series (one patch per fix) once you are done testing? >> > Let me know if you are happy to propose the changes as a patch-series. If you don't have time I can help and get these in ASAP as I was the original culprit. > > Happy to help out with testing too as I have access to HW. Let me know. > > Mark -- Mirsad Todorovac System engineer Faculty of Graphic Arts | Academy of Fine Arts University of Zagreb Republic of Croatia, the European Union Sistem inženjer Grafički fakultet | Akademija likovnih umjetnosti Sveučilište u Zagrebu ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] [RFC] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-29 16:24 ` Mark Pearson 2023-03-29 16:43 ` Mirsad Goran Todorovac @ 2023-03-29 18:49 ` Mirsad Goran Todorovac 2023-03-29 18:59 ` Mark Pearson 1 sibling, 1 reply; 24+ messages in thread From: Mirsad Goran Todorovac @ 2023-03-29 18:49 UTC (permalink / raw) To: Mark Pearson, Hans de Goede, Thomas Weißschuh Cc: Armin Wolf, Greg KH, Rafael J. Wysocki, linux-kernel, markgross, platform-driver-x86 On 29.3.2023. 18:24, Mark Pearson wrote: > Hi > > On Wed, Mar 29, 2023, at 11:46 AM, Hans de Goede wrote: >> Hi, >> >> On 3/29/23 16:18, Mirsad Goran Todorovac wrote: >>> On 29.3.2023. 15:35, Thomas Weißschuh wrote: >>>> >>>> Mar 29, 2023 08:31:31 Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>: >>>> > <snip> >>> >>> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >>> index c816646eb661..e8c28f4f5a71 100644 >>> --- a/drivers/platform/x86/think-lmi.c >>> +++ b/drivers/platform/x86/think-lmi.c >>> @@ -1469,6 +1469,7 @@ static int tlmi_analyze(void) >>> kstrndup(optstart, optend - optstart, >>> GFP_KERNEL); >>> } >>> + kfree(item); >>> } >>> } >>> /* >>> >>> You were 3 minutes faster ;-) >>> >>> The build with this patch is finished. Apparently, that was the culprit, for now > <snip> >>> >>> >>> So, the "tlmi_setting" memory leak appears to be fixed by this diff. >>> > My only concern here is it looks like I was dumb and used the variable name 'item' twice in the same function. I guess the compiler is smart enough to handle it but I'd like to change the name to make it clearer which 'item' is being freed in each context. > > In that block I would change it to be: > char *optitem, *optstart, *optend; > and fix all the pieces in the block to then be correct too (with the needed free) > >>> The next step is to add Armin-suggested patch: >>> >>> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >>> index c816646eb661..1e77ecb0cba8 100644 >>> --- a/drivers/platform/x86/think-lmi.c >>> +++ b/drivers/platform/x86/think-lmi.c >>> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a >>> >>> /* validate and split from `item,value` -> `value` */ >>> value = strpbrk(item, ","); >>> - if (!value || value == item || !strlen(value + 1)) >>> + if (!value || value == item || !strlen(value + 1)) { >>> + kfree(item); >>> return -EINVAL; >>> + } >>> >>> ret = sysfs_emit(buf, "%s\n", value + 1); >>> kfree(item); >>> > This looks good to me - thank you! > >>> and Thomas' correction for the return type of the tlmi_setting() function: >>> >>> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >>> index 86b33b74519be..c924e9e4a6a5b 100644 >>> --- a/drivers/platform/x86/think-lmi.c >>> +++ b/drivers/platform/x86/think-lmi.c >>> @@ -1353,7 +1353,6 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type, >>> >>> static int tlmi_analyze(void) >>> { >>> - acpi_status status; >>> int i, ret; >>> >>> if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && >>> @@ -1390,8 +1389,8 @@ static int tlmi_analyze(void) >>> char *p; >>> >>> tlmi_priv.setting[i] = NULL; >>> - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>> - if (ACPI_FAILURE(status)) >>> + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>> + if (ret) >>> break; >>> if (!item) >>> break; >>> >>> A build on top of 6.3-rc4+ fcd476ea6a88 commit is on the way, with all three included. >> >> Good work on catching these issues, thank you all for your work on this. >> > Seconded - thank you for flagging and catching this. These were my mistakes :( > >> I assume that these fixes will be posted as a proper 3 patch >> patch-series (one patch per fix) once you are done testing? >> > Let me know if you are happy to propose the changes as a patch-series. If you don't have time I can help and get these in ASAP as I was the original culprit. > > Happy to help out with testing too as I have access to HW. Let me know. > > Mark Here is the patch proposal according to what Mark advised (using different name for optitem): diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index c816646eb661..ab17254781c4 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a /* validate and split from `item,value` -> `value` */ value = strpbrk(item, ","); - if (!value || value == item || !strlen(value + 1)) + if (!value || value == item || !strlen(value + 1)) { + kfree(item); return -EINVAL; + } ret = sysfs_emit(buf, "%s\n", value + 1); kfree(item); @@ -1380,7 +1382,6 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type, static int tlmi_analyze(void) { - acpi_status status; int i, ret; if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && @@ -1417,8 +1418,8 @@ static int tlmi_analyze(void) char *p; tlmi_priv.setting[i] = NULL; - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); - if (ACPI_FAILURE(status)) + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); + if (ret) break; if (!item) break; @@ -1457,10 +1458,10 @@ static int tlmi_analyze(void) * name string. * Try and pull that out if it's available. */ - char *item, *optstart, *optend; + char *optitem, *optstart, *optend; - if (!tlmi_setting(setting->index, &item, LENOVO_BIOS_SETTING_GUID)) { - optstart = strstr(item, "[Optional:"); + if (!tlmi_setting(setting->index, &optitem, LENOVO_BIOS_SETTING_GUID)) { + optstart = strstr(optitem, "[Optional:"); if (optstart) { optstart += strlen("[Optional:"); optend = strstr(optstart, "]"); @@ -1469,6 +1470,7 @@ static int tlmi_analyze(void) kstrndup(optstart, optend - optstart, GFP_KERNEL); } + kfree(optitem); } } /* I have tested it, but without a few blunders of my own. I guess "nobody wins them all". Best regards, Mirsad -- Mirsad Todorovac System engineer Faculty of Graphic Arts | Academy of Fine Arts University of Zagreb Republic of Croatia, the European Union Sistem inženjer Grafički fakultet | Akademija likovnih umjetnosti Sveučilište u Zagrebu ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [BUG] [RFC] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-29 18:49 ` [BUG] [RFC] " Mirsad Goran Todorovac @ 2023-03-29 18:59 ` Mark Pearson 2023-03-29 19:21 ` Thomas Weißschuh 0 siblings, 1 reply; 24+ messages in thread From: Mark Pearson @ 2023-03-29 18:59 UTC (permalink / raw) To: Mirsad Goran Todorovac, Hans de Goede, Thomas Weißschuh Cc: Armin Wolf, Greg KH, Rafael J. Wysocki, linux-kernel, markgross, platform-driver-x86 Thanks Mirsad On Wed, Mar 29, 2023, at 2:49 PM, Mirsad Goran Todorovac wrote: <snip> > > Here is the patch proposal according to what Mark advised (using > different name for optitem): > > diff --git a/drivers/platform/x86/think-lmi.c > b/drivers/platform/x86/think-lmi.c > index c816646eb661..ab17254781c4 100644 > --- a/drivers/platform/x86/think-lmi.c > +++ b/drivers/platform/x86/think-lmi.c > @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject > *kobj, struct kobj_attribute *a > > /* validate and split from `item,value` -> `value` */ > value = strpbrk(item, ","); > - if (!value || value == item || !strlen(value + 1)) > + if (!value || value == item || !strlen(value + 1)) { > + kfree(item); > return -EINVAL; > + } > > ret = sysfs_emit(buf, "%s\n", value + 1); > kfree(item); > @@ -1380,7 +1382,6 @@ static struct tlmi_pwd_setting > *tlmi_create_auth(const char *pwd_type, > > static int tlmi_analyze(void) > { > - acpi_status status; > int i, ret; > > if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && > @@ -1417,8 +1418,8 @@ static int tlmi_analyze(void) > char *p; > > tlmi_priv.setting[i] = NULL; > - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); > - if (ACPI_FAILURE(status)) > + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); > + if (ret) Really minor, but tweak to be this and save a line of code? + if (tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID)) > break; > if (!item) > break; > @@ -1457,10 +1458,10 @@ static int tlmi_analyze(void) > * name string. > * Try and pull that out if it's available. > */ > - char *item, *optstart, *optend; > + char *optitem, *optstart, *optend; > > - if (!tlmi_setting(setting->index, &item, > LENOVO_BIOS_SETTING_GUID)) { > - optstart = strstr(item, "[Optional:"); > + if (!tlmi_setting(setting->index, &optitem, > LENOVO_BIOS_SETTING_GUID)) { > + optstart = strstr(optitem, > "[Optional:"); > if (optstart) { > optstart += > strlen("[Optional:"); > optend = strstr(optstart, "]"); > @@ -1469,6 +1470,7 @@ static int tlmi_analyze(void) > > kstrndup(optstart, optend - optstart, > > GFP_KERNEL); > } > + kfree(optitem); > } > } > /* > > I have tested it, but without a few blunders of my own. I'm running a build locally and will aim to put this thru a few different platforms myself too and sanity check > I guess "nobody wins them all". I hear you :P Mark ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] [RFC] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-29 18:59 ` Mark Pearson @ 2023-03-29 19:21 ` Thomas Weißschuh 2023-03-29 21:50 ` Mirsad Goran Todorovac 0 siblings, 1 reply; 24+ messages in thread From: Thomas Weißschuh @ 2023-03-29 19:21 UTC (permalink / raw) To: Mark Pearson Cc: Mirsad Goran Todorovac, Hans de Goede, Armin Wolf, Greg KH, Rafael J. Wysocki, linux-kernel, markgross, platform-driver-x86 Mar 29, 2023 14:00:22 Mark Pearson <mpearson-lenovo@squebb.ca>: > Thanks Mirsad > > On Wed, Mar 29, 2023, at 2:49 PM, Mirsad Goran Todorovac wrote: > <snip> >> >> Here is the patch proposal according to what Mark advised (using >> different name for optitem): >> >> diff --git a/drivers/platform/x86/think-lmi.c >> b/drivers/platform/x86/think-lmi.c >> index c816646eb661..ab17254781c4 100644 >> --- a/drivers/platform/x86/think-lmi.c >> +++ b/drivers/platform/x86/think-lmi.c >> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject >> *kobj, struct kobj_attribute *a >> >> /* validate and split from `item,value` -> `value` */ >> value = strpbrk(item, ","); >> - if (!value || value == item || !strlen(value + 1)) >> + if (!value || value == item || !strlen(value + 1)) { >> + kfree(item); >> return -EINVAL; >> + } >> >> ret = sysfs_emit(buf, "%s\n", value + 1); >> kfree(item); >> @@ -1380,7 +1382,6 @@ static struct tlmi_pwd_setting >> *tlmi_create_auth(const char *pwd_type, >> >> static int tlmi_analyze(void) >> { >> - acpi_status status; >> int i, ret; >> >> if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && >> @@ -1417,8 +1418,8 @@ static int tlmi_analyze(void) >> char *p; >> >> tlmi_priv.setting[i] = NULL; >> - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >> - if (ACPI_FAILURE(status)) >> + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >> + if (ret) > > Really minor, but tweak to be this and save a line of code? This hunk is actually from another commit and should not be needed here. https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/platform/x86/think-lmi.c?id=da62908efe80f132f691efc2ace4ca67626de86b > + if (tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID)) > >> break; >> if (!item) >> break; >> @@ -1457,10 +1458,10 @@ static int tlmi_analyze(void) >> * name string. >> * Try and pull that out if it's available. >> */ >> - char *item, *optstart, *optend; >> + char *optitem, *optstart, *optend; >> >> - if (!tlmi_setting(setting->index, &item, >> LENOVO_BIOS_SETTING_GUID)) { >> - optstart = strstr(item, "[Optional:"); >> + if (!tlmi_setting(setting->index, &optitem, >> LENOVO_BIOS_SETTING_GUID)) { >> + optstart = strstr(optitem, >> "[Optional:"); >> if (optstart) { >> optstart += >> strlen("[Optional:"); >> optend = strstr(optstart, "]"); >> @@ -1469,6 +1470,7 @@ static int tlmi_analyze(void) >> >> kstrndup(optstart, optend - optstart, >> >> GFP_KERNEL); >> } >> + kfree(optitem); >> } >> } >> /* >> >> I have tested it, but without a few blunders of my own. > > I'm running a build locally and will aim to put this thru a few different platforms myself too and sanity check > >> I guess "nobody wins them all". > > I hear you :P > > Mark ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] [RFC] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-29 19:21 ` Thomas Weißschuh @ 2023-03-29 21:50 ` Mirsad Goran Todorovac 2023-03-31 18:54 ` Mark Pearson 0 siblings, 1 reply; 24+ messages in thread From: Mirsad Goran Todorovac @ 2023-03-29 21:50 UTC (permalink / raw) To: Thomas Weißschuh, Mark Pearson Cc: Hans de Goede, Armin Wolf, Greg KH, Rafael J. Wysocki, linux-kernel, markgross, platform-driver-x86 On 29. 03. 2023. 21:21, Thomas Weißschuh wrote: > > Mar 29, 2023 14:00:22 Mark Pearson <mpearson-lenovo@squebb.ca>: > >> Thanks Mirsad >> >> On Wed, Mar 29, 2023, at 2:49 PM, Mirsad Goran Todorovac wrote: >> <snip> >>> >>> Here is the patch proposal according to what Mark advised (using >>> different name for optitem): >>> >>> diff --git a/drivers/platform/x86/think-lmi.c >>> b/drivers/platform/x86/think-lmi.c >>> index c816646eb661..ab17254781c4 100644 >>> --- a/drivers/platform/x86/think-lmi.c >>> +++ b/drivers/platform/x86/think-lmi.c >>> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject >>> *kobj, struct kobj_attribute *a >>> >>> /* validate and split from `item,value` -> `value` */ >>> value = strpbrk(item, ","); >>> - if (!value || value == item || !strlen(value + 1)) >>> + if (!value || value == item || !strlen(value + 1)) { >>> + kfree(item); >>> return -EINVAL; >>> + } >>> >>> ret = sysfs_emit(buf, "%s\n", value + 1); >>> kfree(item); >>> @@ -1380,7 +1382,6 @@ static struct tlmi_pwd_setting >>> *tlmi_create_auth(const char *pwd_type, >>> >>> static int tlmi_analyze(void) >>> { >>> - acpi_status status; >>> int i, ret; >>> >>> if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && >>> @@ -1417,8 +1418,8 @@ static int tlmi_analyze(void) >>> char *p; >>> >>> tlmi_priv.setting[i] = NULL; >>> - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>> - if (ACPI_FAILURE(status)) >>> + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>> + if (ret) >> >> Really minor, but tweak to be this and save a line of code? > > This hunk is actually from another commit and should not be needed here. > > https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/platform/x86/think-lmi.c?id=da62908efe80f132f691efc2ace4ca67626de86b Thank you, Thomas, Indeed, my mistake. I have accepted Armin's suggestion to test if that patch closed the leak, and I have just quoted it, never claiming authorship. I ought to apologise if I made confusion here. I was a bit euphoric about the leak being fixed, so forgive me for this blatant mistake. Of course, putting it here would cause a patch collision, so it was a stupid thing to do, and I would never do it in a formal patch submission ... Thanks, anyway for correction. Best regards, Mirsad -- Mirsad Goran Todorovac Sistem inženjer Grafički fakultet | Akademija likovnih umjetnosti Sveučilište u Zagrebu System engineer Faculty of Graphic Arts | Academy of Fine Arts University of Zagreb, Republic of Croatia The European Union "I see something approaching fast ... Will it be friends with me?" ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] [RFC] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-29 21:50 ` Mirsad Goran Todorovac @ 2023-03-31 18:54 ` Mark Pearson 2023-03-31 19:04 ` Hans de Goede 0 siblings, 1 reply; 24+ messages in thread From: Mark Pearson @ 2023-03-31 18:54 UTC (permalink / raw) To: Mirsad Goran Todorovac, Thomas Weißschuh Cc: Hans de Goede, Armin Wolf, Greg KH, Rafael J. Wysocki, linux-kernel, markgross, platform-driver-x86 Hi all, On Wed, Mar 29, 2023, at 5:50 PM, Mirsad Goran Todorovac wrote: > On 29. 03. 2023. 21:21, Thomas Weißschuh wrote: >> >> Mar 29, 2023 14:00:22 Mark Pearson <mpearson-lenovo@squebb.ca>: >> >>> Thanks Mirsad >>> >>> On Wed, Mar 29, 2023, at 2:49 PM, Mirsad Goran Todorovac wrote: >>> <snip> >>>> >>>> Here is the patch proposal according to what Mark advised (using >>>> different name for optitem): >>>> >>>> diff --git a/drivers/platform/x86/think-lmi.c >>>> b/drivers/platform/x86/think-lmi.c >>>> index c816646eb661..ab17254781c4 100644 >>>> --- a/drivers/platform/x86/think-lmi.c >>>> +++ b/drivers/platform/x86/think-lmi.c >>>> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject >>>> *kobj, struct kobj_attribute *a >>>> >>>> /* validate and split from `item,value` -> `value` */ >>>> value = strpbrk(item, ","); >>>> - if (!value || value == item || !strlen(value + 1)) >>>> + if (!value || value == item || !strlen(value + 1)) { >>>> + kfree(item); >>>> return -EINVAL; >>>> + } >>>> >>>> ret = sysfs_emit(buf, "%s\n", value + 1); >>>> kfree(item); >>>> @@ -1380,7 +1382,6 @@ static struct tlmi_pwd_setting >>>> *tlmi_create_auth(const char *pwd_type, >>>> >>>> static int tlmi_analyze(void) >>>> { >>>> - acpi_status status; >>>> int i, ret; >>>> >>>> if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && >>>> @@ -1417,8 +1418,8 @@ static int tlmi_analyze(void) >>>> char *p; >>>> >>>> tlmi_priv.setting[i] = NULL; >>>> - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>>> - if (ACPI_FAILURE(status)) >>>> + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>>> + if (ret) >>> >>> Really minor, but tweak to be this and save a line of code? >> >> This hunk is actually from another commit and should not be needed here. >> >> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/platform/x86/think-lmi.c?id=da62908efe80f132f691efc2ace4ca67626de86b > > Thank you, Thomas, > > Indeed, my mistake. > > I have accepted Armin's suggestion to test if that patch closed the leak, and I > have just quoted it, never claiming authorship. > > I ought to apologise if I made confusion here. > > I was a bit euphoric about the leak being fixed, so forgive me for this blatant > mistake. Of course, putting it here would cause a patch collision, so it was a > stupid thing to do, and I would never do it in a formal patch submission ... > > Thanks, anyway for correction. > > Best regards, > Mirsad > I have the patches ready to fix this issue - I just wanted to check that I wouldn't be stepping on anybodies toes or if there is a protocol for doing this. - I will add Reported-by tag for Mirsad and Suggested-by for Armin. - I've identified Fixes tags for the two commits that caused the issue. Let me know if there's anything else I should do - otherwise I'll get them sent out ASAP. Thanks Mark ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] [RFC] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-31 18:54 ` Mark Pearson @ 2023-03-31 19:04 ` Hans de Goede 2023-03-31 19:10 ` Mark Pearson 0 siblings, 1 reply; 24+ messages in thread From: Hans de Goede @ 2023-03-31 19:04 UTC (permalink / raw) To: Mark Pearson, Mirsad Goran Todorovac, Thomas Weißschuh Cc: Armin Wolf, Greg KH, Rafael J. Wysocki, linux-kernel, markgross, platform-driver-x86 Hi, On 3/31/23 20:54, Mark Pearson wrote: > Hi all, > > On Wed, Mar 29, 2023, at 5:50 PM, Mirsad Goran Todorovac wrote: >> On 29. 03. 2023. 21:21, Thomas Weißschuh wrote: >>> >>> Mar 29, 2023 14:00:22 Mark Pearson <mpearson-lenovo@squebb.ca>: >>> >>>> Thanks Mirsad >>>> >>>> On Wed, Mar 29, 2023, at 2:49 PM, Mirsad Goran Todorovac wrote: >>>> <snip> >>>>> >>>>> Here is the patch proposal according to what Mark advised (using >>>>> different name for optitem): >>>>> >>>>> diff --git a/drivers/platform/x86/think-lmi.c >>>>> b/drivers/platform/x86/think-lmi.c >>>>> index c816646eb661..ab17254781c4 100644 >>>>> --- a/drivers/platform/x86/think-lmi.c >>>>> +++ b/drivers/platform/x86/think-lmi.c >>>>> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject >>>>> *kobj, struct kobj_attribute *a >>>>> >>>>> /* validate and split from `item,value` -> `value` */ >>>>> value = strpbrk(item, ","); >>>>> - if (!value || value == item || !strlen(value + 1)) >>>>> + if (!value || value == item || !strlen(value + 1)) { >>>>> + kfree(item); >>>>> return -EINVAL; >>>>> + } >>>>> >>>>> ret = sysfs_emit(buf, "%s\n", value + 1); >>>>> kfree(item); >>>>> @@ -1380,7 +1382,6 @@ static struct tlmi_pwd_setting >>>>> *tlmi_create_auth(const char *pwd_type, >>>>> >>>>> static int tlmi_analyze(void) >>>>> { >>>>> - acpi_status status; >>>>> int i, ret; >>>>> >>>>> if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && >>>>> @@ -1417,8 +1418,8 @@ static int tlmi_analyze(void) >>>>> char *p; >>>>> >>>>> tlmi_priv.setting[i] = NULL; >>>>> - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>>>> - if (ACPI_FAILURE(status)) >>>>> + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>>>> + if (ret) >>>> >>>> Really minor, but tweak to be this and save a line of code? >>> >>> This hunk is actually from another commit and should not be needed here. >>> >>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/platform/x86/think-lmi.c?id=da62908efe80f132f691efc2ace4ca67626de86b >> >> Thank you, Thomas, >> >> Indeed, my mistake. >> >> I have accepted Armin's suggestion to test if that patch closed the leak, and I >> have just quoted it, never claiming authorship. >> >> I ought to apologise if I made confusion here. >> >> I was a bit euphoric about the leak being fixed, so forgive me for this blatant >> mistake. Of course, putting it here would cause a patch collision, so it was a >> stupid thing to do, and I would never do it in a formal patch submission ... >> >> Thanks, anyway for correction. >> >> Best regards, >> Mirsad >> > > I have the patches ready to fix this issue - I just wanted to check that I wouldn't be stepping on anybodies toes or if there is a protocol for doing this. > - I will add Reported-by tag for Mirsad and Suggested-by for Armin. > - I've identified Fixes tags for the two commits that caused the issue. > Let me know if there's anything else I should do - otherwise I'll get them sent out ASAP. This sounds to me like you have covered all the bases. Note Armin did send out a related fix earlier today, which I guess is duplicate with one of your patches: https://patchwork.kernel.org/project/platform-driver-x86/patch/20230331180912.38392-1-W_Armin@gmx.de/ So maybe add Armin's patch on top of pdx86/fixes and use that as a base for your series (dropping your likely duplicate patch) ? Regards, Hans ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] [RFC] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-31 19:04 ` Hans de Goede @ 2023-03-31 19:10 ` Mark Pearson 2023-03-31 19:13 ` Mirsad Goran Todorovac 0 siblings, 1 reply; 24+ messages in thread From: Mark Pearson @ 2023-03-31 19:10 UTC (permalink / raw) To: Hans de Goede, Mirsad Goran Todorovac, Thomas Weißschuh Cc: Armin Wolf, Greg KH, Rafael J. Wysocki, linux-kernel, markgross, platform-driver-x86 On Fri, Mar 31, 2023, at 3:04 PM, Hans de Goede wrote: > Hi, > > On 3/31/23 20:54, Mark Pearson wrote: >> Hi all, >> >> On Wed, Mar 29, 2023, at 5:50 PM, Mirsad Goran Todorovac wrote: >>> On 29. 03. 2023. 21:21, Thomas Weißschuh wrote: >>>> >>>> Mar 29, 2023 14:00:22 Mark Pearson <mpearson-lenovo@squebb.ca>: >>>> >>>>> Thanks Mirsad >>>>> >>>>> On Wed, Mar 29, 2023, at 2:49 PM, Mirsad Goran Todorovac wrote: >>>>> <snip> >>>>>> >>>>>> Here is the patch proposal according to what Mark advised (using >>>>>> different name for optitem): >>>>>> >>>>>> diff --git a/drivers/platform/x86/think-lmi.c >>>>>> b/drivers/platform/x86/think-lmi.c >>>>>> index c816646eb661..ab17254781c4 100644 >>>>>> --- a/drivers/platform/x86/think-lmi.c >>>>>> +++ b/drivers/platform/x86/think-lmi.c >>>>>> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject >>>>>> *kobj, struct kobj_attribute *a >>>>>> >>>>>> /* validate and split from `item,value` -> `value` */ >>>>>> value = strpbrk(item, ","); >>>>>> - if (!value || value == item || !strlen(value + 1)) >>>>>> + if (!value || value == item || !strlen(value + 1)) { >>>>>> + kfree(item); >>>>>> return -EINVAL; >>>>>> + } >>>>>> >>>>>> ret = sysfs_emit(buf, "%s\n", value + 1); >>>>>> kfree(item); >>>>>> @@ -1380,7 +1382,6 @@ static struct tlmi_pwd_setting >>>>>> *tlmi_create_auth(const char *pwd_type, >>>>>> >>>>>> static int tlmi_analyze(void) >>>>>> { >>>>>> - acpi_status status; >>>>>> int i, ret; >>>>>> >>>>>> if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && >>>>>> @@ -1417,8 +1418,8 @@ static int tlmi_analyze(void) >>>>>> char *p; >>>>>> >>>>>> tlmi_priv.setting[i] = NULL; >>>>>> - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>>>>> - if (ACPI_FAILURE(status)) >>>>>> + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>>>>> + if (ret) >>>>> >>>>> Really minor, but tweak to be this and save a line of code? >>>> >>>> This hunk is actually from another commit and should not be needed here. >>>> >>>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/platform/x86/think-lmi.c?id=da62908efe80f132f691efc2ace4ca67626de86b >>> >>> Thank you, Thomas, >>> >>> Indeed, my mistake. >>> >>> I have accepted Armin's suggestion to test if that patch closed the leak, and I >>> have just quoted it, never claiming authorship. >>> >>> I ought to apologise if I made confusion here. >>> >>> I was a bit euphoric about the leak being fixed, so forgive me for this blatant >>> mistake. Of course, putting it here would cause a patch collision, so it was a >>> stupid thing to do, and I would never do it in a formal patch submission ... >>> >>> Thanks, anyway for correction. >>> >>> Best regards, >>> Mirsad >>> >> >> I have the patches ready to fix this issue - I just wanted to check that I wouldn't be stepping on anybodies toes or if there is a protocol for doing this. >> - I will add Reported-by tag for Mirsad and Suggested-by for Armin. >> - I've identified Fixes tags for the two commits that caused the issue. >> Let me know if there's anything else I should do - otherwise I'll get them sent out ASAP. > > This sounds to me like you have covered all the bases. > > Note Armin did send out a related fix earlier today, > which I guess is duplicate with one of your patches: > > https://patchwork.kernel.org/project/platform-driver-x86/patch/20230331180912.38392-1-W_Armin@gmx.de/ > > So maybe add Armin's patch on top of pdx86/fixes and > use that as a base for your series (dropping your > likely duplicate patch) ? > Makes sense - will do Thanks! Mark ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] [RFC] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-31 19:10 ` Mark Pearson @ 2023-03-31 19:13 ` Mirsad Goran Todorovac 0 siblings, 0 replies; 24+ messages in thread From: Mirsad Goran Todorovac @ 2023-03-31 19:13 UTC (permalink / raw) To: Mark Pearson, Hans de Goede, Thomas Weißschuh Cc: Armin Wolf, Greg KH, Rafael J. Wysocki, linux-kernel, markgross, platform-driver-x86 On 31. 03. 2023. 21:10, Mark Pearson wrote: > > > On Fri, Mar 31, 2023, at 3:04 PM, Hans de Goede wrote: >> Hi, >> >> On 3/31/23 20:54, Mark Pearson wrote: >>> Hi all, >>> >>> On Wed, Mar 29, 2023, at 5:50 PM, Mirsad Goran Todorovac wrote: >>>> On 29. 03. 2023. 21:21, Thomas Weißschuh wrote: >>>>> >>>>> Mar 29, 2023 14:00:22 Mark Pearson <mpearson-lenovo@squebb.ca>: >>>>> >>>>>> Thanks Mirsad >>>>>> >>>>>> On Wed, Mar 29, 2023, at 2:49 PM, Mirsad Goran Todorovac wrote: >>>>>> <snip> >>>>>>> >>>>>>> Here is the patch proposal according to what Mark advised (using >>>>>>> different name for optitem): >>>>>>> >>>>>>> diff --git a/drivers/platform/x86/think-lmi.c >>>>>>> b/drivers/platform/x86/think-lmi.c >>>>>>> index c816646eb661..ab17254781c4 100644 >>>>>>> --- a/drivers/platform/x86/think-lmi.c >>>>>>> +++ b/drivers/platform/x86/think-lmi.c >>>>>>> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject >>>>>>> *kobj, struct kobj_attribute *a >>>>>>> >>>>>>> /* validate and split from `item,value` -> `value` */ >>>>>>> value = strpbrk(item, ","); >>>>>>> - if (!value || value == item || !strlen(value + 1)) >>>>>>> + if (!value || value == item || !strlen(value + 1)) { >>>>>>> + kfree(item); >>>>>>> return -EINVAL; >>>>>>> + } >>>>>>> >>>>>>> ret = sysfs_emit(buf, "%s\n", value + 1); >>>>>>> kfree(item); >>>>>>> @@ -1380,7 +1382,6 @@ static struct tlmi_pwd_setting >>>>>>> *tlmi_create_auth(const char *pwd_type, >>>>>>> >>>>>>> static int tlmi_analyze(void) >>>>>>> { >>>>>>> - acpi_status status; >>>>>>> int i, ret; >>>>>>> >>>>>>> if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && >>>>>>> @@ -1417,8 +1418,8 @@ static int tlmi_analyze(void) >>>>>>> char *p; >>>>>>> >>>>>>> tlmi_priv.setting[i] = NULL; >>>>>>> - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>>>>>> - if (ACPI_FAILURE(status)) >>>>>>> + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >>>>>>> + if (ret) >>>>>> >>>>>> Really minor, but tweak to be this and save a line of code? >>>>> >>>>> This hunk is actually from another commit and should not be needed here. >>>>> >>>>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/platform/x86/think-lmi.c?id=da62908efe80f132f691efc2ace4ca67626de86b >>>> >>>> Thank you, Thomas, >>>> >>>> Indeed, my mistake. >>>> >>>> I have accepted Armin's suggestion to test if that patch closed the leak, and I >>>> have just quoted it, never claiming authorship. >>>> >>>> I ought to apologise if I made confusion here. >>>> >>>> I was a bit euphoric about the leak being fixed, so forgive me for this blatant >>>> mistake. Of course, putting it here would cause a patch collision, so it was a >>>> stupid thing to do, and I would never do it in a formal patch submission ... >>>> >>>> Thanks, anyway for correction. >>>> >>>> Best regards, >>>> Mirsad >>>> >>> >>> I have the patches ready to fix this issue - I just wanted to check that I wouldn't be stepping on anybodies toes or if there is a protocol for doing this. >>> - I will add Reported-by tag for Mirsad and Suggested-by for Armin. >>> - I've identified Fixes tags for the two commits that caused the issue. >>> Let me know if there's anything else I should do - otherwise I'll get them sent out ASAP. >> >> This sounds to me like you have covered all the bases. >> >> Note Armin did send out a related fix earlier today, >> which I guess is duplicate with one of your patches: >> >> https://patchwork.kernel.org/project/platform-driver-x86/patch/20230331180912.38392-1-W_Armin@gmx.de/ >> >> So maybe add Armin's patch on top of pdx86/fixes and >> use that as a base for your series (dropping your >> likely duplicate patch) ? >> > Makes sense - will do > Thanks! > Mark Hi, Mark, You might find it convenient to test the patches in my initial environment that triggered the bug. Otherwise, it is fine with me. Regards, Mirsad -- Mirsad Goran Todorovac Sistem inženjer Grafički fakultet | Akademija likovnih umjetnosti Sveučilište u Zagrebu System engineer Faculty of Graphic Arts | Academy of Fine Arts University of Zagreb, Republic of Croatia The European Union "I see something approaching fast ... Will it be friends with me?" ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [BUG] [BISECTED] [CORRECTION] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() 2023-03-29 15:46 ` Hans de Goede 2023-03-29 16:24 ` Mark Pearson @ 2023-03-29 16:27 ` Mirsad Goran Todorovac 1 sibling, 0 replies; 24+ messages in thread From: Mirsad Goran Todorovac @ 2023-03-29 16:27 UTC (permalink / raw) To: Hans de Goede, Thomas Weißschuh Cc: Armin Wolf, Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, Mark Gross, platform-driver-x86, Mark Pearson On 29.3.2023. 17:46, Hans de Goede wrote: >> So, the "tlmi_setting" memory leak appears to be fixed by this diff. >> >> The next step is to add Armin-suggested patch: >> >> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >> index c816646eb661..1e77ecb0cba8 100644 >> --- a/drivers/platform/x86/think-lmi.c >> +++ b/drivers/platform/x86/think-lmi.c >> @@ -929,8 +929,10 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a >> >> /* validate and split from `item,value` -> `value` */ >> value = strpbrk(item, ","); >> - if (!value || value == item || !strlen(value + 1)) >> + if (!value || value == item || !strlen(value + 1)) { >> + kfree(item); >> return -EINVAL; >> + } >> >> ret = sysfs_emit(buf, "%s\n", value + 1); >> kfree(item); >> >> and Thomas' correction for the return type of the tlmi_setting() function: >> >> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >> index 86b33b74519be..c924e9e4a6a5b 100644 >> --- a/drivers/platform/x86/think-lmi.c >> +++ b/drivers/platform/x86/think-lmi.c >> @@ -1353,7 +1353,6 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type, >> >> static int tlmi_analyze(void) >> { >> - acpi_status status; >> int i, ret; >> >> if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && >> @@ -1390,8 +1389,8 @@ static int tlmi_analyze(void) >> char *p; >> >> tlmi_priv.setting[i] = NULL; >> - status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >> - if (ACPI_FAILURE(status)) >> + ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); >> + if (ret) >> break; >> if (!item) >> break; >> >> A build on top of 6.3-rc4+ fcd476ea6a88 commit is on the way, with all three included. > > Good work on catching these issues, thank you all for your work on this. Not at all. It was a very interesting problem and a great session of brainstorming with Greg, Armin and Thomas. > I assume that these fixes will be posted as a proper 3 patch > patch-series (one patch per fix) once you are done testing? This is for others to decide. Armin gave a great hint with the one patch, and I sort of had a race condition of the one with Thomas that was the final fix ;-) The tlmi_setting return value fix by Thomas is already committed to the for-next tree, I got it from there. I do not have any authorship pretensions, this was a collaboration, so I don't know what is due in the Code of Conduct for such circumstances. I trust you guys will do the right thing. The 6.3.0-rc4-00034-gfcd476ea6a88 kernel apparently has a stackdump: WARNING: CPU: 4 PID: 746 at drivers/thermal/thermal_sysfs.c:879 cooling_device_stats_setup+0xb4/0xc0 but with our without the patch, and it apparently isn't related. Best regards, Mirsad -- Mirsad Todorovac System engineer Faculty of Graphic Arts | Academy of Fine Arts University of Zagreb Republic of Croatia, the European Union Sistem inženjer Grafički fakultet | Akademija likovnih umjetnosti Sveučilište u Zagrebu ^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2023-03-31 19:13 UTC | newest] Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <5059b11b-8b6e-394b-338f-49e1339067fa@alu.unizg.hr> [not found] ` <ZCLPaYGKHlFQGKYQ@kroah.com> 2023-03-28 11:59 ` [BUG] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() Mirsad Todorovac 2023-03-28 12:08 ` Mirsad Todorovac 2023-03-28 12:17 ` Greg Kroah-Hartman 2023-03-28 12:44 ` Mirsad Todorovac 2023-03-28 16:53 ` Armin Wolf 2023-03-28 19:06 ` Mirsad Goran Todorovac 2023-03-28 19:55 ` Armin Wolf 2023-03-29 8:13 ` Mirsad Goran Todorovac 2023-03-29 13:22 ` [BUG] [BISECTED] " Mirsad Goran Todorovac 2023-03-29 13:31 ` [BUG] [BISECTED] [CORRECTION] " Mirsad Goran Todorovac 2023-03-29 13:35 ` Thomas Weißschuh 2023-03-29 14:18 ` Mirsad Goran Todorovac 2023-03-29 15:46 ` Hans de Goede 2023-03-29 16:24 ` Mark Pearson 2023-03-29 16:43 ` Mirsad Goran Todorovac 2023-03-29 18:49 ` [BUG] [RFC] " Mirsad Goran Todorovac 2023-03-29 18:59 ` Mark Pearson 2023-03-29 19:21 ` Thomas Weißschuh 2023-03-29 21:50 ` Mirsad Goran Todorovac 2023-03-31 18:54 ` Mark Pearson 2023-03-31 19:04 ` Hans de Goede 2023-03-31 19:10 ` Mark Pearson 2023-03-31 19:13 ` Mirsad Goran Todorovac 2023-03-29 16:27 ` [BUG] [BISECTED] [CORRECTION] " Mirsad Goran Todorovac
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).