linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [BUG] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register()
@ 2023-03-28 11:13 Mirsad Todorovac
  2023-03-28 11:28 ` Greg Kroah-Hartman
  0 siblings, 1 reply; 26+ messages in thread
From: Mirsad Todorovac @ 2023-03-28 11:13 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel

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]
     [<ffffffffaef987eb>] really_probe+0x17b/0x3d0
     [<ffffffffaef98ad4>] __driver_probe_device+0x84/0x190
     [<ffffffffaef98c14>] driver_probe_device+0x24/0xc0
     [<ffffffffaef98ed2>] __driver_attach+0xc2/0x190
     [<ffffffffaef95ab1>] bus_for_each_dev+0x81/0xd0
     [<ffffffffaef97c62>] driver_attach+0x22/0x30
     [<ffffffffaef97354>] bus_add_driver+0x1b4/0x240
     [<ffffffffaef9a0a2>] driver_register+0x62/0x120
unreferenced object 0xffff88ad0845a840 (size 64):
   comm "systemd-udevd", pid 735, jiffies 4294896783 (age 2257.488s)
   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:
     [<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]
     [<ffffffffaef987eb>] really_probe+0x17b/0x3d0
     [<ffffffffaef98ad4>] __driver_probe_device+0x84/0x190
     [<ffffffffaef98c14>] driver_probe_device+0x24/0xc0
     [<ffffffffaef98ed2>] __driver_attach+0xc2/0x190
     [<ffffffffaef95ab1>] bus_for_each_dev+0x81/0xd0
     [<ffffffffaef97c62>] driver_attach+0x22/0x30
     [<ffffffffaef97354>] bus_add_driver+0x1b4/0x240
     [<ffffffffaef9a0a2>] driver_register+0x62/0x120
unreferenced object 0xffff88ad069f5e40 (size 64):
   comm "systemd-udevd", pid 735, jiffies 4294896822 (age 2257.332s)
   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:
     [<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]
     [<ffffffffaef987eb>] really_probe+0x17b/0x3d0
     [<ffffffffaef98ad4>] __driver_probe_device+0x84/0x190
     [<ffffffffaef98c14>] driver_probe_device+0x24/0xc0
     [<ffffffffaef98ed2>] __driver_attach+0xc2/0x190
     [<ffffffffaef95ab1>] bus_for_each_dev+0x81/0xd0
     [<ffffffffaef97c62>] driver_attach+0x22/0x30
     [<ffffffffaef97354>] bus_add_driver+0x1b4/0x240
     [<ffffffffaef9a0a2>] driver_register+0x62/0x120
[snip]

Please see build config and the more verbose debug output at the URL:

https://domac.alu.hr/~mtodorov/linux/bugreports/driver_register/

I hope this helps someone.

This one is way too complex to even attempt guessing what went wrong,
with my current knowledge of the Linux kernel internals.

Please contact me for any additional required information.

As usual, I have Cc:-ed all maintainers as per get_maintainers.pl script.

Thank you very much for your patience.

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

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [BUG] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register()
  2023-03-28 11:13 [BUG] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() Mirsad Todorovac
@ 2023-03-28 11:28 ` Greg Kroah-Hartman
  2023-03-28 11:59   ` Mirsad Todorovac
  0 siblings, 1 reply; 26+ messages in thread
From: Greg Kroah-Hartman @ 2023-03-28 11:28 UTC (permalink / raw)
  To: Mirsad Todorovac; +Cc: Rafael J. Wysocki, linux-kernel

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

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [BUG] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register()
  2023-03-28 11:28 ` Greg Kroah-Hartman
@ 2023-03-28 11:59   ` Mirsad Todorovac
  2023-03-28 12:08     ` Mirsad Todorovac
  0 siblings, 1 reply; 26+ 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] 26+ messages in thread

* Re: [BUG] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register()
  2023-03-28 11:59   ` Mirsad Todorovac
@ 2023-03-28 12:08     ` Mirsad Todorovac
  2023-03-28 12:17       ` Greg Kroah-Hartman
  0 siblings, 1 reply; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ 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; 26+ 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] 26+ messages in thread

end of thread, other threads:[~2023-03-31 19:13 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-28 11:13 [BUG] systemd-devd triggers kernel memleak apparently in drivers/core/dd.c: driver_register() Mirsad Todorovac
2023-03-28 11:28 ` Greg Kroah-Hartman
2023-03-28 11:59   ` 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).