> On Sun, Feb 14, 2021 at 7:09 PM Peter Gerber <pe...@arbitrary.ch> wrote:

> > the following steps crash sshfs with SIGSEGV when a file is open while
> > the folder containing it is renamed.
> >
> > Steps to reproduce:
> >
> > #!/usr/bin/python3
> > import os
> >
> > os.mkdir('old_name')
> > f = open('old_name/f', 'w')
> > os.rename('old_name', 'new_name')
> > f.close()  # crashes here

My observations:
- The open file has an entry in sshfs's conntab, keyed by its path.
- sshfs_rename checks and updates only the given directory paths in conntab.
- During close, there is a dangling entry for "old_name/f" in conntab, and no 
entry for "new_name/f", breaking sshfs_release:

> > 2885            chunk_put_locked(sf->readahead);
> > 2886            if (sshfs.max_conns > 1) {
> > 2887                    pthread_mutex_lock(&sshfs.lock);
> > 2888                    sf->conn->file_count--;
> > 2889                    ce = g_hash_table_lookup(sshfs.conntab, path);
> > 2890                    ce->refcount--;
> > 2891                    if(ce->refcount == 0) {
> > 2892                            g_hash_table_remove(sshfs.conntab, path);
> > 2893                            g_free(ce);
> > 2894                    }

> > Looks to me like `ce` on line 2890 shown above is NULL.

So sshfs_rename should rewrite all matching keys in conntab when a directory is 
renamed.  (Perhaps the data structure should be changed to a tree?)

I also noticed that now that the connections are refcounted, the refcount 
should be decremented when replacing an existing key (g_hash_table_replace).  
Right, Nikolaus?

timo

Reply via email to