Skip to content

gh-106263: Fix segfault in signaldict_repr #106270

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 8 commits into from
Jul 30, 2023

Conversation

CharlieZhao95
Copy link
Contributor

@CharlieZhao95 CharlieZhao95 commented Jun 30, 2023

Fix potential crash risks in signaldict object.

Co-authored-by: sunmy2019 <59365878+sunmy2019@users.noreply.github.com>
static int
signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED)
{
SdFlagAddr(self) = NULL;
SdFlagAddr(self) = &dflt_ctx.status;
Copy link
Member

@sunmy2019 sunmy2019 Jun 30, 2023

Choose a reason for hiding this comment

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

They will all share the same flags.

Will users start to misuse this construction method, then found in surprise that its flags being changed without notice?

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 prefer forbidding this than silently allowing this.

Copy link
Contributor Author

@CharlieZhao95 CharlieZhao95 Jun 30, 2023

Choose a reason for hiding this comment

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

Thanks! It seems that it is not easy to forbid instantiation directly, because decimal.Context() depends on the signaldict instance. If you have a good idea, please let me know :) Or let's wait for advice from other professionals~

@CharlieZhao95
Copy link
Contributor Author

CharlieZhao95 commented Jun 30, 2023

At first I considered two solutions to fix this:

  1. Add NULL pointer checker in all places where signaldict is used. If signaldict is NULL , an exception will be thrown (maybe SdFlags macro can help us do this)
  2. Assign default value to signaldict object in the signaldict_init (simplest)

Assuming that there is a class with parameterless constructor, we use this constructor to create an instance of the class, then call the method of the class, and then the program crashes. It sounds weird, even though we don't want users to call this constructor directly.

IMO, it makes sense to properly initialize instance attributes in a parameterless constructor. So I prefer solution 2 for now, it's simple and works. Please correct me if I am wrong :)

@rhettinger rhettinger removed their request for review June 30, 2023 22:36
@sunmy2019
Copy link
Member

sunmy2019 commented Jul 1, 2023

IMO, it makes sense to properly initialize instance attributes in a parameterless constructor. So I prefer solution 2 for now, it's simple and works. Please correct me if I am wrong :)

How about this? Disallowing signaldict_setitem if SdFlagAddr(v) == dflt_ctx->flags || .... (edited)

@CharlieZhao95
Copy link
Contributor Author

How about this? Disallowing signaldict_setitem if SdFlagAddr(v) == &dflt_ctx.

I got you. But this seems to limit users from changing the value of decimal.Context().flags or decimal.Context().traps.

if (default_context_template) {
*ctx = *CTX(default_context_template);
}
else {
*ctx = dflt_ctx;
}
SdFlagAddr(self->traps) = &ctx->traps;
SdFlagAddr(self->flags) = &ctx->status;

That's why we hate global variable.

What if we choose option 1? @sunmy2019 We need to add pointer checker for all methods of signaldict object, not just methods that may crash. Otherwise, the signaldict_len function will always return SIGNAL_MAP_LEN(9), but the actual object is NULL. This will confuse others.

@sunmy2019

This comment was marked as outdated.

@sunmy2019
Copy link
Member

I got you. But this seems to limit users from changing the value of decimal.Context().flags or decimal.Context().traps.

I got you now. I didn't look into it closely.

What if we choose option 1? @sunmy2019 We need to add pointer checker for all methods of signaldict object, not just methods that may crash. Otherwise, the signaldict_len function will always return SIGNAL_MAP_LEN(9), but the actual object is NULL. This will confuse others.

This is what I previously preferred.

@erlend-aasland erlend-aasland self-requested a review July 2, 2023 20:35
@CharlieZhao95
Copy link
Contributor Author

@erlend-aasland I updated this PR, would you mind to review this :)

@kumaraditya303 kumaraditya303 added the extension-modules C modules in the Modules dir label Jul 30, 2023
@kumaraditya303 kumaraditya303 merged commit 3979150 into python:main Jul 30, 2023
@erlend-aasland
Copy link
Contributor

Thanks, Kumar and Charlie! Should this be backported?

@sunmy2019
Copy link
Member

I think it should.

@CharlieZhao95
Copy link
Contributor Author

Thanks, Kumar and Charlie! Should this be backported?

Yes, it should. This backport does not bring any side effects. If there are conflicts, I can manually backport them. :)

@erlend-aasland erlend-aasland added needs backport to 3.11 only security fixes needs backport to 3.12 only security fixes labels Jul 31, 2023
@miss-islington
Copy link
Contributor

Thanks @CharlieZhao95 for the PR, and @kumaraditya303 for merging it 🌮🎉.. I'm working now to backport this PR to: 3.11.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

Thanks @CharlieZhao95 for the PR, and @kumaraditya303 for merging it 🌮🎉.. I'm working now to backport this PR to: 3.12.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

Sorry, @CharlieZhao95 and @kumaraditya303, I could not cleanly backport this to 3.12 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 3979150a0d406707f6d253d7c15fb32c1e005a77 3.12

@miss-islington
Copy link
Contributor

Sorry, @CharlieZhao95 and @kumaraditya303, I could not cleanly backport this to 3.11 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 3979150a0d406707f6d253d7c15fb32c1e005a77 3.11

CharlieZhao95 added a commit to CharlieZhao95/cpython that referenced this pull request Jul 31, 2023
…le (python#106270)

Co-authored-by: sunmy2019 <59365878+sunmy2019@users.noreply.github.com>
(cherry picked from commit 3979150)
CharlieZhao95 added a commit to CharlieZhao95/cpython that referenced this pull request Jul 31, 2023
…le (python#106270)

Co-authored-by: sunmy2019 <59365878+sunmy2019@users.noreply.github.com>
(cherry picked from commit 3979150)
@bedevere-bot
Copy link

GH-107490 is a backport of this pull request to the 3.11 branch.

@bedevere-bot bedevere-bot removed the needs backport to 3.11 only security fixes label Jul 31, 2023
@bedevere-bot
Copy link

GH-107491 is a backport of this pull request to the 3.12 branch.

@bedevere-bot bedevere-bot removed the needs backport to 3.12 only security fixes label Jul 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
extension-modules C modules in the Modules dir
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants