Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fix several messages mistreated as format strings #114970

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

Merged
merged 1 commit into from
Apr 24, 2025

Conversation

jakobbotsch
Copy link
Member

#113916 started incorrectly treating several messages as format strings. For example, we saw failing JIT asserts like

assert(m_size % TARGET_POINTER_SIZE == 0);

printed as

Assert failure(PID 38272 [0x00009580], Thread: 16904 [0x4208]): Assertion failed 'm_size  0X0.0027A801C8C01P-1022RGET_POINTER_SIZE == 0'

This fixes that case and others introduced in that PR found by audit.

These minipal APIs seem dangerous given that there is no indication in their names that they are taking a format string.

556f4dd started treating several
messages as format strings. For example, we saw failing JIT asserts like

```
assert(m_size % TARGET_POINTER_SIZE == 0);
```

printed as

```
Assert failure(PID 38272 [0x00009580], Thread: 16904 [0x4208]): Assertion failed 'm_size  0X0.0027A801C8C01P-1022RGET_POINTER_SIZE == 0'
```

This fixes that case and others introduced in that PR found by audit.
@Copilot Copilot AI review requested due to automatic review settings April 23, 2025 19:42
@ghost ghost added the area-VM-coreclr label Apr 23, 2025
@jakobbotsch jakobbotsch requested review from lateralusX and removed request for Copilot April 23, 2025 19:42
Copy link
Contributor

Tagging subscribers to this area: @mangod9
See info in area-owners.md if you want to be subscribed.

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes issues where log messages were mistakenly treated as format strings, which led to formatting errors in debugging output.

  • Updated minipal_log_print_info calls in frames.cpp and classcompat.cpp to include an explicit format string.
  • Changed minipal_log_print_error calls in debug.cpp to use a format string, ensuring correct message display.

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
src/coreclr/vm/frames.cpp Updated minipal_log_print_info to explicitly pass a format string ("%s").
src/coreclr/vm/classcompat.cpp Updated minipal_log_print_info to explicitly pass a format string ("%s").
src/coreclr/utilcode/debug.cpp Updated minipal_log_print_error to explicitly pass a format string ("%s").

@@ -2264,7 +2264,7 @@ static void DumpGCRefMap(const char *name, BYTE *address)
}
buf.AppendUTF8("\n");

minipal_log_print_info(buf.GetUTF8());
minipal_log_print_info("%s", buf.GetUTF8());
Copy link
Preview

Copilot AI Apr 23, 2025

Choose a reason for hiding this comment

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

Using an explicit format string (%s) ensures that the logged message is formatted correctly instead of being misinterpreted as a format string.

Copilot uses AI. Check for mistakes.

@@ -520,7 +520,7 @@ InteropMethodTableData *MethodTableBuilder::BuildInteropVTable(AllocMemTracker *
message.AppendUTF8((LPCUTF8) qb.Ptr());
message.AppendUTF8("\n");

minipal_log_print_info(message.GetUTF8());
minipal_log_print_info("%s", message.GetUTF8());
Copy link
Preview

Copilot AI Apr 23, 2025

Choose a reason for hiding this comment

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

The change to include a format string prevents the message from being incorrectly parsed as a format specifier.

Suggested change
minipal_log_print_info("%s", message.GetUTF8());
minipal_log_print_info(message.GetUTF8());

Copilot uses AI. Check for mistakes.

@@ -257,7 +257,7 @@ bool _DbgBreakCheck(
if (formattedMessages)
{
OutputDebugStringUtf8(formatBuffer);
minipal_log_print_error(formatBuffer);
minipal_log_print_error("%s", formatBuffer);
Copy link
Preview

Copilot AI Apr 23, 2025

Choose a reason for hiding this comment

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

Passing a format string explicitly ensures that the error message from formatBuffer is displayed correctly without format string errors.

Copilot uses AI. Check for mistakes.

@@ -489,7 +489,7 @@ void DECLSPEC_NORETURN __FreeBuildAssertFail(const char *szFile, int iLine, cons
OutputDebugStringUtf8(buffer.GetUTF8());

// Write out the error to the console
minipal_log_print_error(buffer.GetUTF8());
minipal_log_print_error("%s", buffer.GetUTF8());
Copy link
Preview

Copilot AI Apr 23, 2025

Choose a reason for hiding this comment

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

The update ensures that the error message is printed correctly by using an explicit format string.

Copilot uses AI. Check for mistakes.

Copy link
Member

@kunalspathak kunalspathak left a comment

Choose a reason for hiding this comment

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

LGTM

@lateralusX
Copy link
Member

lateralusX commented Apr 24, 2025

they minipal_log_print_* follows printf style formatting rules, so if we had a printf("%s", str) before we should have the same when using minpal_log_print_* API's.

In case we have the buffer ready and there is no formatting needs, then using minipal_log_write is probably a better alternative since it doesn't handle format strings, just the raw buffer.

@lateralusX
Copy link
Member

lateralusX commented Apr 24, 2025

The use of print instead of printf in the name originally came from Android naming of their logging API's, __android_log_print, that we use as our underlying implementation on Android, but if we think it will be safer to use printf, like minipal_log_printf_info then I can do that change to make things clearer that the API accepts a formatting string as its first argument.

@am11
Copy link
Member

am11 commented Apr 24, 2025

@lateralusX, minipal_log(flags, str) and minipal_log_format(flags, fmt, ...) may be more clear. Also, please add API docs as other minipal headers: https://github.com/dotnet/runtime/blob/main/src/native/minipal/utf8.h#L21

@jakobbotsch
Copy link
Member Author

they minipal_log_print_* follows printf style formatting rules, so if we had a printf("%s", str) before we should have the same when using minpal_log_print_* API's.

#113916 changed several instances of printf("%s", msg) to minimal_log_print_error(msg) or similar. This PR is changing those I found back.

In case we have the buffer ready and there is no formatting needs, then using minipal_log_write is probably a better alternative since it doesn't handle format strings, just the raw buffer.

Hmm, I can change it, but I notice that minipal_log_print_* calls fprintf directly, while minipal_log_write goes through some much more complicated writing logic. I was expecting it to use fputs to be analogous to minipal_log_print_*. Why the difference?

if we think it will be safer to use printf, like minipal_log_printf_info then I can do that change to make things clearer that the API accepts a formatting string as its first argument.

I think a name like that would be better, to make it harder to introduce these format string vulnerabilities.

@lateralusX
Copy link
Member

lateralusX commented Apr 24, 2025

they minipal_log_print_* follows printf style formatting rules, so if we had a printf("%s", str) before we should have the same when using minpal_log_print_* API's.

#113916 changed several instances of printf("%s", msg) to minimal_log_print_error(msg) or similar. This PR is changing those I found back.

In case we have the buffer ready and there is no formatting needs, then using minipal_log_write is probably a better alternative since it doesn't handle format strings, just the raw buffer.

Hmm, I can change it, but I notice that minipal_log_print_* calls fprintf directly, while minipal_log_write goes through some much more complicated writing logic. I was expecting it to use fputs to be analogous to minipal_log_print_*. Why the difference?

if we think it will be safer to use printf, like minipal_log_printf_info then I can do that change to make things clearer that the API accepts a formatting string as its first argument.

I think a name like that would be better, to make it harder to introduce these format string vulnerabilities.

The minipal_log_write should use as low level API as possible since it is used in cases where we hit crashes or stack overflow scenarios or other sensitive places of the runtime, so idea is that it should be as async signal safe as possible, using the low level write API. This was mainly moved from low level runtime logging in utilcode primarily used by PrintToStdErrA.

Since we originally used printf for all changed logging in this PR we can continue to go through minipal_log_print_* API.

I also did an audit of the changes in #113916 and didn't find any additional places where it used "%s" in the past than already fixed in this PR.

@jakobbotsch jakobbotsch merged commit bec2519 into dotnet:main Apr 24, 2025
96 checks passed
@jakobbotsch jakobbotsch deleted the fix-minipal-print-format branch April 24, 2025 12:48
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.

4 participants