Bug 1470193

Summary: Premature free() in sftp_readdir_async()
Product: [Fedora] Fedora EPEL Reporter: Michael Mol <mikemol>
Component: fuse-sshfsAssignee: Peter Lemenkov <lemenkov>
Status: CLOSED ERRATA QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: high Docs Contact:
Priority: unspecified    
Version: epel7CC: lemenkov
Target Milestone: ---   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: fuse-sshfs-2.10-1.el7 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2019-04-10 08:36:05 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Michael Mol 2017-07-12 13:54:06 UTC
Description of problem:
Segfault of sshfs mount.

Version-Release number of selected component (if applicable):
fuse-sshfs-2.5-1.el7.x86_64 and earlier.

How reproducible:
Sometimes. Difficult.

Steps to Reproduce:
1. Mount sshfs mount
2. Transfer data

Actual results:
Data transferred.


Expected results:
Segfault.

Additional info:
Upstream developer analysis:
https://github.com/libfuse/sshfs/issues/7#issuecomment-314758425

My own valgrind-memcheck result:

==19702== Invalid read of size 4
==19702==    at 0x114AE6: sftp_readdir_async (sshfs.c:2092)
==19702==    by 0x114AE6: sshfs_getdir (sshfs.c:2157)
==19702==    by 0x1157F1: cache_getdir (cache.c:327)                                                                                                                                                                                                                                                                     
==19702==    by 0x4E42972: fuse_fs_readdir (fuse.c:2014)                                                                                                                                                                                                                                                                 
==19702==    by 0x4E42AAA: readdir_fill (fuse.c:3460)                                                                                                                                                                                                                                                                    
==19702==    by 0x4E42AAA: fuse_lib_readdir (fuse.c:3486)                                                                                                                                                                                                                                                                
==19702==    by 0x4E496A5: do_readdir (fuse_lowlevel.c:1389)                                                                                                                                                                                                                                                             
==19702==    by 0x4E4ABDA: fuse_ll_process_buf (fuse_lowlevel.c:2441)                                                                                                                                                                                                                                                    
==19702==    by 0x4E47470: fuse_do_work (fuse_loop_mt.c:117)                                                                                                                                                                                                                                                             
==19702==    by 0x55B2DC4: start_thread (pthread_create.c:308)                                                                                                                                                                                                                                                           
==19702==    by 0x58BE76C: clone (clone.S:113)                                                                                                                                                                                                                                                                           
==19702==  Address 0x7e4c4c0 is 0 bytes inside a block of size 136 free'd                                                                                                                                                                                                                                                
==19702==    at 0x4C29CDD: free (vg_replace_malloc.c:530)                                                                                                                                                                                                                                                                
==19702==    by 0x52C341D: g_free (gmem.c:189)                                                                                                                                                                                                                                                                           
==19702==    by 0x10E055: process_one_request (sshfs.c:1384)                                                                                                                                                                                                                                                             
==19702==    by 0x10E055: process_requests (sshfs.c:1414)                                                                                                                                                                                                                                                                
==19702==    by 0x55B2DC4: start_thread (pthread_create.c:308)                                                                                                                                                                                                                                                           
==19702==    by 0x58BE76C: clone (clone.S:113)                                                                                                                                                                                                                                                                           
==19702==  Block was alloc'd at                                                                                                                                                                                                                                                                                          
==19702==    at 0x4C2A975: calloc (vg_replace_malloc.c:711)                                                                                                                                                                                                                                                              
==19702==    by 0x52C3365: g_malloc0 (gmem.c:124)                                                                                                                                                                                                                                                                        
==19702==    by 0x11027A: sftp_request_send (sshfs.c:1835)                                                                                                                                                                                                                                                               
==19702==    by 0x1149B7: sftp_readdir_send (sshfs.c:2039)                                                                                                                                                                                                                                                               
==19702==    by 0x1149B7: sftp_readdir_async (sshfs.c:2067)                                                                                                                                                                                                                                                              
==19702==    by 0x1149B7: sshfs_getdir (sshfs.c:2157)                                                                                                                                                                                                                                                                    
==19702==    by 0x1157F1: cache_getdir (cache.c:327)                                                                                                                                                                                                                                                                     
==19702==    by 0x4E42972: fuse_fs_readdir (fuse.c:2014)                                                                                                                                                                                                                                                                 
==19702==    by 0x4E42AAA: readdir_fill (fuse.c:3460)                                                                                                                                                                                                                                                                    
==19702==    by 0x4E42AAA: fuse_lib_readdir (fuse.c:3486)                                                                                                                                                                                                                                                                
==19702==    by 0x4E496A5: do_readdir (fuse_lowlevel.c:1389)                                                                                                                                                                                                                                                             
==19702==    by 0x4E4ABDA: fuse_ll_process_buf (fuse_lowlevel.c:2441)                                                                                                                                                                                                                                                    
==19702==    by 0x4E47470: fuse_do_work (fuse_loop_mt.c:117)                                                                                                                                                                                                                                                             
==19702==    by 0x55B2DC4: start_thread (pthread_create.c:308)                                                                                                                                                                                                                                                           
==19702==    by 0x58BE76C: clone (clone.S:113)

Comment 1 Michael Mol 2017-07-13 12:18:50 UTC
Upstream fix in commit cc5d6bbbc5b7e78296f5245988b9ba947076a1b8.

https://github.com/libfuse/sshfs/commit/cc5d6bbbc5b7e78296f5245988b9ba947076a1b8

Comment 2 Michael Mol 2017-07-13 14:25:06 UTC
Looks like I flipped the "expected" and "actual" in my initial report. Expected result is that data transfers. Actual is the segfault.

Though it looks like it only happens during listings of large directories.