Skip to content

llext: fix memory leak in no-data case#10599

Open
wjablon1 wants to merge 1 commit intothesofproject:mainfrom
wjablon1:llext_bss_fix
Open

llext: fix memory leak in no-data case#10599
wjablon1 wants to merge 1 commit intothesofproject:mainfrom
wjablon1:llext_bss_fix

Conversation

@wjablon1
Copy link
Contributor

@wjablon1 wjablon1 commented Mar 5, 2026

If there is no .data section in a llext module, the base data address is replaced with the .bss address while loading the module. There is no a corresponding logic during module unloading. This causes a memory leak because FW attempts to free memory under a NULL address while the .bss memory remains allocated. This change adds the missing logic.

The issue was caught with RTC_AEC module during long run/multi-test or immediate Zephyr assert with debug build

Copy link
Contributor

@tmleman tmleman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @wjablon1 , great finding!

if (ret < 0)
err = ret;

va_base_data = va_base_data ? va_base_data : va_bss_data;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would inline comment this assumption to make it easier to follow.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't like redundancy like

if (x)
    x = x;
else
    x = y;

Can we just make this

if (!va_base_data)
    va_base_data = va_base_bss;

or maybe even use size:

if (!mctx->segment[LIB_MANAGER_DATA].size)
    va_base_data = va_base_bss;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, will fix. It's just my habit from the previous project where constructions like this were common and immediately understood. I need to get rid of this habit :/

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wjablon1 no worries, the compiler would probably optimise that away, but... it just looks not very pretty to me, sorry, just my personal preference :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lyakh I agree that in this case your proposal looks much cleaner if you consider all the other SOF stylistic rules. But in other projects it's forbidden to omit curly brackets with if statements so the construction I used was a handy shortcut.

Copy link
Collaborator

@lyakh lyakh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the fix! Looks correct, can we just improve cosmetics a bit

/* Writable data (.data, .bss, etc.) */
void __sparse_cache *va_base_data = (void __sparse_cache *)
mctx->segment[LIB_MANAGER_DATA].addr;
void __sparse_cache *va_bss_data = (void __sparse_cache *)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for consistency this should be called va_base_bss or bss_addr to match llext_manager_load_module().

if (ret < 0)
err = ret;

va_base_data = va_base_data ? va_base_data : va_bss_data;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't like redundancy like

if (x)
    x = x;
else
    x = y;

Can we just make this

if (!va_base_data)
    va_base_data = va_base_bss;

or maybe even use size:

if (!mctx->segment[LIB_MANAGER_DATA].size)
    va_base_data = va_base_bss;

If there is no .data section in a llext module, the base data address is
replaced with the .bss address while loading the module. There is no a
corresponding logic during module unloading. This causes a memory leak
because FW attempts to free memory under a NULL address while the .bss
memory remains allocated. This change adds the missing logic.

Signed-off-by: Wojciech Jablonski <wojciech.jablonski@intel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants