Skip to content

ICP: Fix null pointer dereference and use after free #9659

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
Dec 3, 2019

Conversation

AttilaFueloep
Copy link
Contributor

Motivation and Context

Bugfix.

Description

In gcm_mode_decrypt_contiguous_blocks(), if vmem_alloc() fails, bcopy() is called with a null pointer destination and a length > 0. This results in undefined behavior. Further ctx->gcm_pt_buf is freed but not set to NULL, leading to a potential write after free and a double free due to missing return value handling in crypto_update_uio(). The code as is may write to ctx->gcm_pt_buf in gcm_decrypt_final() and may free ctx->gcm_pt_buf again in aes_decrypt_atomic().

The fix is to slightly rework error handling in gcm_mode_decrypt_contiguous_blocks() and check the return value in crypto_update_uio().

How Has This Been Tested?

As part of another branch this survived 6 hours of zloop. Currently zloop fails with unmodified master within one hour, so can't use zloop to test this PR, sorry.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Performance enhancement (non-breaking change which improves efficiency)
  • Code cleanup (non-breaking change which makes code smaller or more readable)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation (a change to man pages or other documentation)

Checklist:

In gcm_mode_decrypt_contiguous_blocks(), if vmem_alloc() fails,
bcopy is called with a NULL pointer destination and a length > 0.
This results in undefined behavior. Further ctx->gcm_pt_buf is
freed but not set to NULL, leading to a potential write after
free and a double free due to missing return value handling in
crypto_update_uio(). The code as is may write to ctx->gcm_pt_buf
in gcm_decrypt_final() and may free ctx->gcm_pt_buf again in
aes_decrypt_atomic().

The fix is to slightly rework error handling and check the return
value in crypto_update_uio().

Signed-off-by: Attila Fülöp <[email protected]>
@behlendorf behlendorf added the Status: Code Review Needed Ready for review and testing label Dec 2, 2019
Copy link
Contributor

@behlendorf behlendorf left a comment

Choose a reason for hiding this comment

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

Thanks for running down this failure. The fix here makes good sense, my only question is do you know the size and flags passed to the failed vmem_alloc()? I ask because normallly these allocations are not allowed to fail. Did this issue manifest itself as a hang?

@behlendorf behlendorf requested a review from tcaputi December 2, 2019 19:25
@AttilaFueloep
Copy link
Contributor Author

Well, I found this bug while reading the code, never managed to trigger it. And I agree that it is mostly academic for in-kernel use, but user space consumers of libicp may be able to hit this. This, btw also applies to #9660.

@behlendorf behlendorf added the Component: Encryption "native encryption" feature label Dec 2, 2019
@codecov
Copy link

codecov bot commented Dec 3, 2019

Codecov Report

Merging #9659 into master will increase coverage by 0.05%.
The diff coverage is 50%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #9659      +/-   ##
==========================================
+ Coverage   79.32%   79.38%   +0.05%     
==========================================
  Files         418      418              
  Lines      123544   123548       +4     
==========================================
+ Hits        98003    98078      +75     
+ Misses      25541    25470      -71
Flag Coverage Δ
#kernel 79.93% <50%> (-0.02%) ⬇️
#user 67.15% <50%> (+0.26%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5142032...3a834d5. Read the comment docs.

@AttilaFueloep
Copy link
Contributor Author

The failing resilver test is most likely not related to this change and code coverage can't be increased without making vmem_alloc() fail.

Copy link
Contributor

@tcaputi tcaputi left a comment

Choose a reason for hiding this comment

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

LGTM. good catch.

@AttilaFueloep
Copy link
Contributor Author

Illumos issue 12047

@behlendorf behlendorf added Status: Accepted Ready to integrate (reviewed, tested) and removed Status: Code Review Needed Ready for review and testing labels Dec 3, 2019
@behlendorf behlendorf merged commit 54c8366 into openzfs:master Dec 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Encryption "native encryption" feature Status: Accepted Ready to integrate (reviewed, tested)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants