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

signed integer overflow in S_study_chunk #17848

Closed
wants to merge 3 commits into from
Closed

Conversation

lightsey
Copy link
Contributor

@lightsey lightsey commented Jun 8, 2020

This is a slightly modified version of the commits @hvds put together for #17847 in the security team issue tracker. I changed the comparisons in the second commit slightly to avoid compiler warnings about comparisons between signed and unsigned integers.

hvds added 3 commits June 8, 2020 14:54
delta and pos_delta may hold OPTIMIZE_INFTY (SSize_t_MAX) to represent infinity;

Fixes: Perl#17847
The expression we're about to add to data->pos_delta in this part of
study_chunk() can be both positive or negative; however while we apply
an overflow check to avoid exceeding OPTIMIZE_INFTY (used to represent
infinity), we'll happily subtract from it when the expression is
negative, making it no longer infinite.

Fixes: Perl#17847
@xsawyerx
Copy link
Member

xsawyerx commented Jun 9, 2020

Should this be in 5.32.0?

@hvds
Copy link
Contributor

hvds commented Jun 9, 2020

@khwilliamson objected to the third commit "I think that subtracting a finite value from infinity should be infinity, so I think I don't like your third patch." I think that objection may be because the commit message is not clear enough - when it says ".. we'll happily subtract from it when the expression is
negative, making it no longer infinite" I was describing the wrong state of affairs this commit was fixing, not the result after the commit. I believe this commit does correctly leave it acting to keep infinite values infinite.

He also suggested that these checks should be using REG_INFTY (or at worst a new symbol such as OPTIMIZE_INFTY) rather than SSize_t_MAX, and @lightsey appears to have implemented that in these versions of the commits. I'm unsure about this, and would have preferred such changes to have a separate commit with a properly attributed author.

I don't think I'm happy about the new version using OPTIMIZE_INFTY - and TBH I'm unsure about overflow handling in C more generally - because I'm concerned primarily about physical overflow of a particular datatype leading to wraparound (or undefined behaviour). What I really want is a way to have addition (or other arithmetic) safe for the actual datatype of the variable, so that if the type changes we will automatically switch to using the new relevant MAX value. But I don't know how to achieve that, and in any case we should discuss the philosophy of infinities somewhere distinct from this pull request.

@hvds
Copy link
Contributor

hvds commented Jun 9, 2020

Should this be in 5.32.0?

I'd say no (expressing opinion, not veto). Analysis suggested that if we hit this it fails in a safe way, so there's nothing to justify a late addition to the release.

@khwilliamson
Copy link
Contributor

khwilliamson commented Jun 9, 2020 via email

@khwilliamson
Copy link
Contributor

khwilliamson commented Jun 9, 2020 via email

@lightsey
Copy link
Contributor Author

lightsey commented Jun 9, 2020

The OPTIMIZE_INFTY does look odd in combination with a cast to SSize_t to silence the compiler warnings. When trying to sync up the original change set against the OPTIMIZE_INFTY change I debated whether it would make more sense to use SSize_t_MAX for the comparisons or to case the SSize_t side of the comparison to UV.

I apologize if my changes to the second commit seem more like a rewrite than a rebase. That wasn't my intent. The recent changes in the regex engine made it difficult to rebase the original fix without modifying it.

At any rate, if @hvds wants to address this in a different fashion down the road, it'd make sense to close out this pull request.

@xsawyerx xsawyerx added this to the 5.33.1 milestone Jun 10, 2020
@xsawyerx xsawyerx added the do not merge Don't merge this PR, at least for now label Jun 20, 2020
@atoomic atoomic requested a review from xsawyerx July 30, 2020 23:19
@atoomic
Copy link
Member

atoomic commented Jul 30, 2020

@hvds / @xsawyerx / @lightsey could you please comment on this case
is it ready to be merged as it?

@toddr
Copy link
Member

toddr commented Jul 30, 2020

also @khwilliamson it's not clear if you are ok with this.

@toddr toddr added Ready-to-merge and removed do not merge Don't merge this PR, at least for now labels Jul 30, 2020
@hvds
Copy link
Contributor

hvds commented Jul 31, 2020

I'd like to look through it again in light of the various comments, I'll try to do that within 24 hours.

Putting together comments from me, @khwilliamson and @lightsey I'd probably go with recreating it more like the original, using SSize_t_MAX rather than OPTIMIZE_INFTY; but it's been a while, so I also want to review the whole of the changes again and make sure I still understand what I'm doing.

@hvds
Copy link
Contributor

hvds commented Aug 1, 2020

Ok, on reviewing the current state of affairs, I think SSize_t_MAX no longer makes sense, so I've updated my patches close to what @lightsey had over latest blead; I've pushed this as branch gh17847 for consideration.

I don't consider either SSize_t_MAX or OPTIMIZE_INFTY to be ideal - neither actually usefully describes what sort of quantity or limit we're dealing with. I'd rather we decided what these types of quantities should be, typedefed something to that, and then used an associated MAX define as our infinity. But then make all variables representing those quantities of the relevant type so that we don't end up trying to add a UV to a SSize_t.

In particular I'm nervous that at some point someone will try to set min_subtract = OPTIMIZE_INFTY, and it'll overflow on some platform where UV_MAX < SSize_t_MAX.

@tonycoz
Copy link
Contributor

tonycoz commented Nov 5, 2020

In particular I'm nervous that at some point someone will try to set min_subtract = OPTIMIZE_INFTY, and it'll overflow on some platform where UV_MAX < SSize_t_MAX.

I don't think UV_MAX < SSize_t_MAX is possible.

A UV or IV is large enough to hold a pointer.

@hvds
Copy link
Contributor

hvds commented Mar 3, 2022

This PR should have been closed a while ago, the issue was resolved by merging 3 commits ending with 8227b2b.

@hvds hvds closed this Mar 3, 2022
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.

None yet

7 participants