Skip to content

[FIX] Prevent stack smashing via unbounded OSD message array writes#11365

Open
sensei-hacker wants to merge 2 commits intoiNavFlight:maintenance-9.xfrom
sensei-hacker:fix/pr10048-add-msg
Open

[FIX] Prevent stack smashing via unbounded OSD message array writes#11365
sensei-hacker wants to merge 2 commits intoiNavFlight:maintenance-9.xfrom
sensei-hacker:fix/pr10048-add-msg

Conversation

@sensei-hacker
Copy link
Member

@sensei-hacker sensei-hacker commented Feb 25, 2026

Summary

Both osdGetSystemMessage() and osdGetMultiFunctionMessage() accumulate message pointers into fixed-size arrays with no bounds checking. With additions since this was originally reported (geozone avoidance, pitot validation, etc.) the number of potential writes can exceed the array size, causing stack corruption during active flight.

This is a rebase/rework of #10048 by @Yury-MonZon, adapted to current maintenance-9.x.

Some folks didn't care for the syntax:

messages[nextMsg()] = theMessage;

So I adjusted it to:

ADD_MSG(theMessage);

This replaces the unsafe:

messages[messageCount++] = theMessage;

Related

Fixes #10048

Both osdGetSystemMessage() and osdGetMultiFunctionMessage() accumulate
message pointers into a fixed-size array with no bounds checking. With
recent additions (geozone avoidance, pitot validation, etc.) the number
of potential writes exceeds the array size, causing stack corruption.

Introduce a scoped ADD_MSG() macro that guards each write:

    #define ADD_MSG(msg) if (messageCount < ARRAYLEN(messages)) \
        messages[messageCount++] = (msg)

Excess messages are silently dropped rather than written past the end
of the array. The macro is #undef'd at the end of each function.

Fixes: iNavFlight#10048 (Yury-MonZon)
@Yury-MonZon
Copy link
Contributor

That fix was made in a macro way in order to keep the original code intact as much as possible.

At current state(after 2 major versions) I suggest re-writing it as a function with counter which guards the limits of the buffer. Easier to read - less problems later.

@sensei-hacker
Copy link
Member Author

sensei-hacker commented Feb 25, 2026

I started to do it as a function, but then you have to pass messages and a pointer to the count in each of 57 calls. 🫤

I think your original approach of using a macro was best way. Just maybe reads cleaner with ADD_MSG(msg) rather than messages[nextMsg()] = msg.

@Yury-MonZon
Copy link
Contributor

but then you have to pass messages and a pointer to the count

No, only pass the message. The function can read/write the message counter by itself.

@sensei-hacker
Copy link
Member Author

sensei-hacker commented Feb 25, 2026

No, only pass the message. The function can read/write the message counter by itself.

I'm sleepy today and not 100% on my game, so maybe I'm missing something but -
what about variable scope?
Change it to a global, from being in one block in one function?

@breadoven
Copy link
Collaborator

Problem with this is it still doesn't deal the the issue of message priority, more important messages never appear if the queue gets clogged with less important messages.

@sensei-hacker
Copy link
Member Author

sensei-hacker commented Feb 27, 2026

Problem with this is it still doesn't deal the the issue of message priority, more important messages never appear if the queue gets clogged with less important messages.

Sure, prioritizing eight or more concurrent system messages is not a goal of this PR.

With the current code, if you have too many messages it crashes the flight controller. Preventing that crash is the goal here.

If someone wants to make a PR that prioritizes messages, that would be cool. Though frankly, if you have eight or more system messages going off at once, the priority should probably be --
somewhat control the "unscheduled landing" that's probably happening. Then go see if you can find whatever parts fell off that caused a 10-alarm incident.

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.

3 participants