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

zfs_handle used after being closed/freed in change_one() callback #9165

Merged
merged 1 commit into from
Aug 28, 2019
Merged

zfs_handle used after being closed/freed in change_one() callback #9165

merged 1 commit into from
Aug 28, 2019

Conversation

pzakha
Copy link
Contributor

@pzakha pzakha commented Aug 15, 2019

Motivation and Context

This is a typical case of use after free. We would call zfs_close(zhp) which would free the handle, and then call zfs_iter_children() on that handle later. This change ensures that the zfs_handle is only closed when we are ready to return.

Description

I've been running zfs inherit -r sharenfs pool which was failing with an error code without any error messages. After some debugging I've pinpointed the issue to be memory corruption, which would cause zfs to try to issue an ioctl to the wrong device and receive ENOTTY.

This failure was likely a fallout of the changes introduced in #7967.

How Has This Been Tested?

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:

@pzakha
Copy link
Contributor Author

pzakha commented Aug 15, 2019

cc: @sebroy @grwilson @alek-p

@pzakha
Copy link
Contributor Author

pzakha commented Aug 15, 2019

Added code to also fix a leak of a zfs handle.
Re-testing: http://platform.jenkins.delphix.com/job/devops-gate/job/master/job/zfs-precommit/4729/

@codecov
Copy link

codecov bot commented Aug 16, 2019

Codecov Report

Merging #9165 into master will decrease coverage by 0.14%.
The diff coverage is 80%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #9165      +/-   ##
==========================================
- Coverage   79.24%    79.1%   -0.15%     
==========================================
  Files         400      400              
  Lines      122012   122002      -10     
==========================================
- Hits        96687    96506     -181     
- Misses      25325    25496     +171
Flag Coverage Δ
#kernel 79.74% <ø> (-0.06%) ⬇️
#user 66.82% <80%> (-0.55%) ⬇️

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 e6203d2...d5c3adb. Read the comment docs.

Copy link
Contributor

@alek-p alek-p left a comment

Choose a reason for hiding this comment

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

LGTM

@behlendorf behlendorf added the Status: Code Review Needed Ready for review and testing label Aug 16, 2019
@pzakha pzakha added Status: Accepted Ready to integrate (reviewed, tested) Status: Code Review Needed Ready for review and testing and removed Status: Code Review Needed Ready for review and testing Status: Accepted Ready to integrate (reviewed, tested) labels Aug 16, 2019
@behlendorf behlendorf added the Status: Revision Needed Changes are required for the PR to be accepted label Aug 19, 2019
@pzakha pzakha added Status: Work in Progress Not yet ready for general review and removed Status: Revision Needed Changes are required for the PR to be accepted Status: Work in Progress Not yet ready for general review labels Aug 21, 2019
@pzakha
Copy link
Contributor Author

pzakha commented Aug 27, 2019

I've updated the code, and had a successful run for a slightly different version.

The issue is that we do need to close the handle, but only if it is not added to the changelist. Alternatively we could have dup'd the handle that we add to the changelist and always close the one passed to change_one.

zfs-precommit link (Delphix internal).

@behlendorf
Copy link
Contributor

@pzakha can you refresh this one last time with the final code and resolve the cstyle warning. Then this should be good to go.

@pzakha
Copy link
Contributor Author

pzakha commented Aug 28, 2019

@behlendorf done, thanks for spotting that!

Signed-off-by: Pavel Zakharov <pavel.zakharov@delphix.com>
@behlendorf behlendorf added Status: Accepted Ready to integrate (reviewed, tested) and removed Status: Code Review Needed Ready for review and testing labels Aug 28, 2019
@behlendorf behlendorf merged commit e6cebbf into openzfs:master Aug 28, 2019
tonyhutter pushed a commit to tonyhutter/zfs that referenced this pull request Sep 17, 2019
This is a typical case of use after free. We would call zfs_close(zhp) 
which would free the handle, and then call zfs_iter_children() on that 
handle later.  This change ensures that the zfs_handle is only closed 
when we are ready to return.

Running `zfs inherit -r sharenfs pool` was failing with an error
code without any error messages. After some debugging I've pinpointed 
the issue to be memory corruption, which would cause zfs to try to 
issue an ioctl to the wrong device and receive ENOTTY.

Reviewed-by: Paul Dagnelie <pcd@delphix.com>
Reviewed-by: George Wilson <gwilson@delphix.com>
Reviewed-by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alek Pinchuk <apinchuk@datto.com>
Signed-off-by: Pavel Zakharov <pavel.zakharov@delphix.com>
Issue openzfs#7967 
Closes openzfs#9165
tonyhutter pushed a commit to tonyhutter/zfs that referenced this pull request Sep 18, 2019
This is a typical case of use after free. We would call zfs_close(zhp) 
which would free the handle, and then call zfs_iter_children() on that 
handle later.  This change ensures that the zfs_handle is only closed 
when we are ready to return.

Running `zfs inherit -r sharenfs pool` was failing with an error
code without any error messages. After some debugging I've pinpointed 
the issue to be memory corruption, which would cause zfs to try to 
issue an ioctl to the wrong device and receive ENOTTY.

Reviewed-by: Paul Dagnelie <pcd@delphix.com>
Reviewed-by: George Wilson <gwilson@delphix.com>
Reviewed-by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alek Pinchuk <apinchuk@datto.com>
Signed-off-by: Pavel Zakharov <pavel.zakharov@delphix.com>
Issue openzfs#7967 
Closes openzfs#9165
tonyhutter pushed a commit to tonyhutter/zfs that referenced this pull request Sep 18, 2019
This is a typical case of use after free. We would call zfs_close(zhp) 
which would free the handle, and then call zfs_iter_children() on that 
handle later.  This change ensures that the zfs_handle is only closed 
when we are ready to return.

Running `zfs inherit -r sharenfs pool` was failing with an error
code without any error messages. After some debugging I've pinpointed 
the issue to be memory corruption, which would cause zfs to try to 
issue an ioctl to the wrong device and receive ENOTTY.

Reviewed-by: Paul Dagnelie <pcd@delphix.com>
Reviewed-by: George Wilson <gwilson@delphix.com>
Reviewed-by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alek Pinchuk <apinchuk@datto.com>
Signed-off-by: Pavel Zakharov <pavel.zakharov@delphix.com>
Issue openzfs#7967 
Closes openzfs#9165
tonyhutter pushed a commit to tonyhutter/zfs that referenced this pull request Sep 18, 2019
This is a typical case of use after free. We would call zfs_close(zhp) 
which would free the handle, and then call zfs_iter_children() on that 
handle later.  This change ensures that the zfs_handle is only closed 
when we are ready to return.

Running `zfs inherit -r sharenfs pool` was failing with an error
code without any error messages. After some debugging I've pinpointed 
the issue to be memory corruption, which would cause zfs to try to 
issue an ioctl to the wrong device and receive ENOTTY.

Reviewed-by: Paul Dagnelie <pcd@delphix.com>
Reviewed-by: George Wilson <gwilson@delphix.com>
Reviewed-by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alek Pinchuk <apinchuk@datto.com>
Signed-off-by: Pavel Zakharov <pavel.zakharov@delphix.com>
Issue openzfs#7967 
Closes openzfs#9165
tonyhutter pushed a commit to tonyhutter/zfs that referenced this pull request Sep 19, 2019
This is a typical case of use after free. We would call zfs_close(zhp) 
which would free the handle, and then call zfs_iter_children() on that 
handle later.  This change ensures that the zfs_handle is only closed 
when we are ready to return.

Running `zfs inherit -r sharenfs pool` was failing with an error
code without any error messages. After some debugging I've pinpointed 
the issue to be memory corruption, which would cause zfs to try to 
issue an ioctl to the wrong device and receive ENOTTY.

Reviewed-by: Paul Dagnelie <pcd@delphix.com>
Reviewed-by: George Wilson <gwilson@delphix.com>
Reviewed-by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alek Pinchuk <apinchuk@datto.com>
Signed-off-by: Pavel Zakharov <pavel.zakharov@delphix.com>
Issue openzfs#7967 
Closes openzfs#9165
tonyhutter pushed a commit to tonyhutter/zfs that referenced this pull request Sep 23, 2019
This is a typical case of use after free. We would call zfs_close(zhp) 
which would free the handle, and then call zfs_iter_children() on that 
handle later.  This change ensures that the zfs_handle is only closed 
when we are ready to return.

Running `zfs inherit -r sharenfs pool` was failing with an error
code without any error messages. After some debugging I've pinpointed 
the issue to be memory corruption, which would cause zfs to try to 
issue an ioctl to the wrong device and receive ENOTTY.

Reviewed-by: Paul Dagnelie <pcd@delphix.com>
Reviewed-by: George Wilson <gwilson@delphix.com>
Reviewed-by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alek Pinchuk <apinchuk@datto.com>
Signed-off-by: Pavel Zakharov <pavel.zakharov@delphix.com>
Issue openzfs#7967 
Closes openzfs#9165
tonyhutter pushed a commit that referenced this pull request Sep 26, 2019
This is a typical case of use after free. We would call zfs_close(zhp)
which would free the handle, and then call zfs_iter_children() on that
handle later.  This change ensures that the zfs_handle is only closed
when we are ready to return.

Running `zfs inherit -r sharenfs pool` was failing with an error
code without any error messages. After some debugging I've pinpointed
the issue to be memory corruption, which would cause zfs to try to
issue an ioctl to the wrong device and receive ENOTTY.

Reviewed-by: Paul Dagnelie <pcd@delphix.com>
Reviewed-by: George Wilson <gwilson@delphix.com>
Reviewed-by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alek Pinchuk <apinchuk@datto.com>
Signed-off-by: Pavel Zakharov <pavel.zakharov@delphix.com>
Issue #7967
Closes #9165
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Accepted Ready to integrate (reviewed, tested)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants