Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows: Fix heap overflow setting native icon #71699

Merged

Conversation

jordo
Copy link
Contributor

@jordo jordo commented Jan 19, 2023

Fixes #71697. Can probably be fixed on master as well.

@jordo jordo requested a review from a team as a code owner January 19, 2023 21:33
@akien-mga
Copy link
Member

We really like more descriptive commit message in a codebase that gets a few dozen commits merged everyday :)

Something like

Windows: Fix heap overflow setting native icon

Fixes #71697.

would be perfect.

@akien-mga akien-mga added this to the 3.6 milestone Jan 19, 2023
@akien-mga akien-mga added the cherrypick:3.5 Considered for cherry-picking into a future 3.5.x release label Jan 19, 2023
@jordo
Copy link
Contributor Author

jordo commented Jan 19, 2023

OK will change commit msg

@jordo jordo force-pushed the PR-windows-heap-overflow-fix branch from b1cff06 to a2c15c3 Compare January 19, 2023 21:43
@jordo
Copy link
Contributor Author

jordo commented Jan 19, 2023

Updated commit msg

@akien-mga akien-mga changed the title fix heap overflow Windows: Fix heap overflow setting native icon Jan 19, 2023
@akien-mga
Copy link
Member

Seems like this was fixed in master already with a slightly different fix: #68631.

@@ -3105,7 +3105,7 @@ void OS_Windows::set_native_icon(const String &p_filename) {
pos += sizeof(WORD);
f->seek(pos);

icon_dir = (ICONDIR *)memrealloc(icon_dir, 3 * sizeof(WORD) + icon_dir->idCount * sizeof(ICONDIRENTRY));
icon_dir = (ICONDIR *)memrealloc(icon_dir, sizeof(ICONDIR) + (icon_dir->idCount * sizeof(ICONDIRENTRY)));
Copy link
Member

Choose a reason for hiding this comment

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

In master it is icon_dir = (ICONDIR *)memrealloc(icon_dir, sizeof(ICONDIR) - sizeof(ICONDIRENTRY) + icon_dir->idCount * sizeof(ICONDIRENTRY));, (see #68631) which is probably correct since ICONDIR already include the first entry.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, that saves sizeof(ICONDIRENTRY) bytes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can idCount ever be zero?

Copy link
Contributor Author

@jordo jordo Jan 19, 2023

Choose a reason for hiding this comment

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

Part of why I guess I didn't love subtracting that part of the struct size away... Was thinking better safe than sorry, as was unsure what valid range of idCount could be without any context of how icons worked.

Copy link
Member

Choose a reason for hiding this comment

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

Can idCount ever be zero?

Technically yes (in practice no, icon file with 0 icons doesn't make sense), but it should be fine, if it's zero nothing will be written to the buffer anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sometimes if the spec (or whatever icon format this is working on), technically allows something it could probably be handled if it's technically possible, better to be robust imo than save a couple bytes. I've dealt with annoying .icns formats in the past which crashed a parser based on some weird assumption of practical formats and sizes.

Anywhoo should be same as master now

Copy link
Contributor Author

@jordo jordo Jan 19, 2023

Choose a reason for hiding this comment

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

Actually, i changed my mind. I think i'm going to revert it to my original implementation. It's safer in general, and safer for future contributors who may not have context or may not work at this allocation point. Sure there are some guards there now, but I don't like that the allocation has potential to be wrong and insufficient. Maybe it could also be exploited, etc.

There just shouldn't be a possible way to allocate unsufficient memory for the size of struct required, even with checks after allocation... At the minimum it should guarantee to always allocate sizeof(ICONDIR) for safety regardless of any external multiplier (idCount).

@jordo jordo force-pushed the PR-windows-heap-overflow-fix branch from a2c15c3 to 02be75f Compare January 19, 2023 22:02
@jordo
Copy link
Contributor Author

jordo commented Jan 19, 2023

I changed this commit to what is currently pushed to master... but I'm not sure what version is actually best.

When i implemented, i didn't know what valid range of idCount can be. If it can be zero, it's possibly incorrect on master as the struct won't be allocated to it's minimum size.

icon_dir = (ICONDIR *)memrealloc(icon_dir, sizeof(ICONDIR) - sizeof(ICONDIRENTRY) + icon_dir->idCount * sizeof(ICONDIRENTRY));

@jordo jordo force-pushed the PR-windows-heap-overflow-fix branch from 02be75f to 33c03a1 Compare January 19, 2023 22:33
@akien-mga
Copy link
Member

The CI error seems unrelated to this PR, likely Xcode got updated on GH Actions and it's now reporting this warning (which we treat as errors):

platform/osx/joypad_osx.cpp:326:3: error: 'sprintf' is deprecated: This function is provided for compatibility reasons only.  Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead. [-Werror,-Wdeprecated-declarations]
                sprintf(uid, "%08x%08x%08x%08x", OSSwapHostToBigInt32(3), OSSwapHostToBigInt32(vendor), OSSwapHostToBigInt32(product_id), OSSwapHostToBigInt32(version));
                ^
/Applications/Xcode_14.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/stdio.h:188:1: note: 'sprintf' has been explicitly marked deprecated here
__deprecated_msg("This function is provided for compatibility reasons only.  Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead.")
^
/Applications/Xcode_14.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/sys/cdefs.h:215:48: note: expanded from macro '__deprecated_msg'
        #define __deprecated_msg(_msg) __attribute__((__deprecated__(_msg)))
                                                      ^
1 error generated.

Will look into fixing this in a separate PR, then this will need a rebase to pass CI.

@akien-mga
Copy link
Member

Will look into fixing this in a separate PR, then this will need a rebase to pass CI.

Done, once rebased this should be good to go.

@akien-mga
Copy link
Member

This added an extra commit, we'd really prefer a rebase to keep the Git history clean.

@jordo
Copy link
Contributor Author

jordo commented Jan 21, 2023

arg ya, didn't see the 2 commits there... Will rebase and resubmit monday, sry!

@jordo jordo closed this Jan 23, 2023
@jordo jordo force-pushed the PR-windows-heap-overflow-fix branch from c9d8b11 to ae47e1d Compare January 23, 2023 16:25
@jordo jordo reopened this Jan 23, 2023
@akien-mga akien-mga merged commit 627d688 into godotengine:3.x Jan 23, 2023
@akien-mga
Copy link
Member

Thanks!

@akien-mga
Copy link
Member

Cherry-picked for 3.5.2.

@akien-mga akien-mga removed the cherrypick:3.5 Considered for cherry-picking into a future 3.5.x release label Mar 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants