• Chris Leech's avatar
    [SCSI] libfc: fix memory corruption caused by double frees and bad error handling · 8f550f93
    Chris Leech authored
    I was running into several different panics under stress, which I traced down
    to a few different possible slab corruption issues in error handling paths.
    I have not yet looked into why these exchange sends fail, but with these
    fixes my test system is much more stable under stress than before.
    
    fc_elsct_send() could fail and either leave the passed in frame intact
    (failure in fc_ct/els_fill) or the frame could have been freed if the
    failure was is fc_exch_seq_send().  The caller had no way of knowing, and
    there was a potential double free in the error handling in fc_fcp_rec().
    
    Make fc_elsct_send() always free the frame before returning, and remove the
    fc_frame_free() call in fc_fcp_rec().
    
    While fc_exch_seq_send() did always consume the frame, there were double free
    bugs in the error handling of fc_fcp_cmd_send() and fc_fcp_srr() as well.
    
    Numerous calls to error handling routines (fc_disc_error(),
    fc_lport_error(), fc_rport_error_retry() ) were passing in a frame pointer that
    had already been freed in the case of an error.  I have changed the call
    sites to pass in a NULL pointer, but there may be more appropriate error
    codes to use.
    
    Question:  Why do these error routines take a frame pointer anyway?  I
    understand passing in a pointer encoded error to the response handlers, but
    the error routines take no action on a valid pointer and should never be
    called that way.
    Signed-off-by: default avatarChris Leech <christopher.leech@intel.com>
    Signed-off-by: default avatarRobert Love <robert.w.love@intel.com>
    Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
    8f550f93
fc_fcp.c 53.8 KB