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

gh-101703: use PyOS_snprintf instead of sprintf #101729

Closed
wants to merge 17 commits into from

Conversation

sobolevn
Copy link
Member

@sobolevn sobolevn commented Feb 9, 2023

Several points of interest:

  1. sprintf is indeed insecure generally: https://rules.sonarsource.com/c/RSPEC-6069 But, for our cases - I was not able to find a single insecure place, so I don't mark this PR as :security:
  2. snprintf is also listed as not secure here: https://clang.llvm.org/docs/analyzer/checkers.html#security-insecureapi-deprecatedorunsafebufferhandling-c
  3. snprintf is reported to be slightly slower than sprintf

@sobolevn
Copy link
Member Author

sobolevn commented Feb 9, 2023

Ok, the first part with constant sized elements is done. Now, more complex ones.

@sobolevn
Copy link
Member Author

sobolevn commented Feb 9, 2023

Looks like we have PyOS_snprintf instead of just snprintf 🤔

@sobolevn
Copy link
Member Author

sobolevn commented Feb 9, 2023

Almost done!

There are a couple left, but I don't quite understand the code and I will highly appreciate help / advice on these cases:

@sobolevn sobolevn added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Feb 9, 2023
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @sobolevn for commit 9bc0864 🤖

If you want to schedule another build, you need to add the :hammer: test-with-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Feb 9, 2023
@sobolevn sobolevn added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Feb 9, 2023
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @sobolevn for commit c7dd348 🤖

If you want to schedule another build, you need to add the :hammer: test-with-buildbots label again.

@sobolevn sobolevn marked this pull request as ready for review February 10, 2023 10:03
@sobolevn
Copy link
Member Author

@Yhg1s @gvanrossum it is ready to be reviewed :)

Objects/unicodeobject.c Outdated Show resolved Hide resolved
@sobolevn
Copy link
Member Author

I've made the requested changes, thanks for the suggestions 👍

@sobolevn
Copy link
Member Author

@Yhg1s can you please review again? :)

@sobolevn sobolevn added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Apr 11, 2023
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @sobolevn for commit 8a95f08 🤖

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Apr 11, 2023
@sobolevn
Copy link
Member Author

I've merged it with the latest main, new round of buildbot tests are required to make sure that all still works correctly.

Does anyone want to take a look once again, please? 😉

@arhadthedev arhadthedev changed the title gh-101703: use snprintf instead of sprintf gh-101703: use PyOS_snprintf instead of sprintf Apr 24, 2023
@sobolevn sobolevn added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Apr 24, 2023
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @sobolevn for commit 3e8e61f 🤖

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Apr 24, 2023
@sobolevn sobolevn added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Apr 27, 2023
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @sobolevn for commit d82e315 🤖

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Apr 27, 2023
Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

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

This now has merge conflicts

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

Copy link
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

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

sprintf is indeed insecure generally: https://rules.sonarsource.com/c/RSPEC-6069 But, for our cases - I was not able to find a single insecure place, so I don't mark this PR as :security:

In the past, I saw people introducing bugs and security vulnerabilities by attempting to make linters happy about getting rid of "dangerous functions".

Python provides advances functions to format strings in a safe way: PyBytes_FromFormat() and PyUnicode_FromFormat(). Moreover, there is also _PyBytesWriter and _PyUnicodeWriter internal API which can be used to "create" a new string in a safe way (without having to handle memory directly).

If a string is longer than expected, PyOS_snprintf() truncates the string, but your change ignores PyOS_snprintf() result and so the string is ignored silently. I am not convinced that these changes are worth it:

  • It doesn't prevent to truncate strings.
  • It's designed to prevent buffer overflow, but it doesn't show examples of possible buffer overfow.
  • From my point of view, I don't see how it makes the code easier to maintain or easier to read.

For example, the PR changes FindAddress() to use PyOS_snprintf(), but it keeps alloca() which is IMO way more problematic. Using PyBytes_FromFormat() would be safer here: the function takes care of memory management and allocates memory on the heap, there is no risk of stack overflow.

If you want me to review this PR, I would prefer smaller PRs with a more precise scope and goal.

@vstinner
Copy link
Member

In the past, I saw people introducing bugs and security vulnerabilities by attempting to make linters happy about getting rid of "dangerous functions".

The worst example that I recall:

Commit message of the fix:

commit 4f980905a0bff94807ea07cb897c0e4cd4e6b83f
Author: Stanislav Malyshev <stas@php.net>
Date:   Fri Aug 19 22:49:18 2011 +0000

    Unbreak crypt() (fix bug #55439)
    # If you want to remove static analyser messages, be my guest,
    # but please run unit tests after

Well, at that time, PHP had no automated test suite, and running tests showed the regression. But well, it's surprising how using "safer" function can introduce a major security vulnerability.

The bug allowed to bypass any kind of login page (implemented with crypt()) with any password...

@sobolevn
Copy link
Member Author

I wanted to close this PR anyway, I think that we should do it on a per-usage approach. Easier to review, easier to merge.

@sobolevn sobolevn closed this Nov 10, 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.

6 participants