Skip to content

Commit

Permalink
rbd: prevent calling rbdVolume.Destroy() after an error
Browse files Browse the repository at this point in the history
It seems possible that the .Destroy() function is called on a nil
pointer. This would cause a panic in the node-plugin.

Depending on how far GenVolFromVolID() comes, the returned rbdVolume can
be connected. If an error occurs, the rbdVolume should not be connected
at all, so call the .Destroy() function in those cases too.

Fixes: #4548
Signed-off-by: Niels de Vos <ndevos@ibm.com>
  • Loading branch information
nixpanic committed Apr 17, 2024
1 parent 51d1d46 commit a8da3d6
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 8 deletions.
1 change: 0 additions & 1 deletion internal/rbd/nodeserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,6 @@ func (ns *NodeServer) populateRbdVol(
} else {
rv, err = GenVolFromVolID(ctx, volID, cr, req.GetSecrets())
if err != nil {
rv.Destroy()
log.ErrorLog(ctx, "error generating volume %s: %v", volID, err)

return nil, status.Errorf(codes.Internal, "error generating volume %s: %v", volID, err)
Expand Down
35 changes: 28 additions & 7 deletions internal/rbd/rbd_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,8 @@ func updateSnapshotDetails(rbdSnap *rbdSnapshot) error {
}

// generateVolumeFromVolumeID generates a rbdVolume structure from the provided identifier.
// The returned rbdVolume is connected in case no error occurred, and should be
// cleaned up with rbdVolume.Destroy().
func generateVolumeFromVolumeID(
ctx context.Context,
volumeID string,
Expand Down Expand Up @@ -1116,6 +1118,13 @@ func generateVolumeFromVolumeID(
if err != nil {
return rbdVol, err
}
// in case of any error call Destroy for cleanup.
defer func() {
if err != nil {
rbdVol.Destroy()
}
}()

rbdVol.JournalPool = rbdVol.Pool

imageAttributes, err := j.GetImageAttributes(
Expand Down Expand Up @@ -1163,6 +1172,8 @@ func generateVolumeFromVolumeID(

// GenVolFromVolID generates a rbdVolume structure from the provided identifier, updating
// the structure with elements from on-disk image metadata as well.
// The returned rbdVolume is connected in case no error occurred, and should be
// cleaned up with rbdVolume.Destroy().
func GenVolFromVolID(
ctx context.Context,
volumeID string,
Expand All @@ -1185,17 +1196,27 @@ func GenVolFromVolID(
!errors.Is(err, ErrImageNotFound) {
return vol, err
}
defer func() {
if err != nil {
vol.Destroy()
}
}()

// Check clusterID mapping exists
mapping, mErr := util.GetClusterMappingInfo(vi.ClusterID)
if mErr != nil {
return vol, mErr
mapping, err := util.GetClusterMappingInfo(vi.ClusterID)
if err != nil {
return vol, err
}
if mapping != nil {
rbdVol, vErr := generateVolumeFromMapping(ctx, mapping, volumeID, vi, cr, secrets)
if !errors.Is(vErr, util.ErrKeyNotFound) && !errors.Is(vErr, util.ErrPoolNotFound) &&
!errors.Is(vErr, ErrImageNotFound) {
return rbdVol, vErr
// create a new volume based on the mapping, cleanup the old volume
if vol != nil {
vol.Destroy()
}

vol, err = generateVolumeFromMapping(ctx, mapping, volumeID, vi, cr, secrets)
if !errors.Is(err, util.ErrKeyNotFound) && !errors.Is(err, util.ErrPoolNotFound) &&
!errors.Is(err, ErrImageNotFound) {
return vol, err
}
}

Expand Down

0 comments on commit a8da3d6

Please sign in to comment.