Skip to content

Commit

Permalink
fusermount: Fix option escaping
Browse files Browse the repository at this point in the history
Before this patch no commas were allowed in any fusermount option string.
But it is in fact possible to use commas in fusermount options: we only
need to escape them [1].

Now go-fuse users can use commas in fusermount options.

Related libfuse commits are [1] and [2].

This patch also adds a test which ensures neither go-fuse nor fusermount
crash if we pass options with commas.

---

[1] libfuse/libfuse@555d6b5
[2] libfuse/libfuse@5c094ac

Change-Id: Iadf8283e630dc1fb884d047d8765eeaaca90eabd
  • Loading branch information
levinzimmermannn committed Jun 7, 2023
1 parent 854d591 commit 90b055a
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 7 deletions.
28 changes: 28 additions & 0 deletions fuse/mount_linux_test.go
Expand Up @@ -187,3 +187,31 @@ fusermount: %#v`, o3, o1)
}
}
}

// TestEscapedMountOption tests that fusermount doesn't exit when when using commas or backslashs in options.
// It also tests that commas or backslashs in options are correctly propagated to /proc/mounts.
func TestEscapedMountOption(t *testing.T) {
fsname := `fsname,with\,many,comm\as,and\backsl\\ashs`
opts := &MountOptions{
FsName: fsname,
}
mnt := t.TempDir()
fs := NewDefaultRawFileSystem()
srv, err := NewServer(fs, mnt, opts)
if err != nil {
t.Error(err)
}
go srv.Serve()
defer srv.Unmount()
mounts, err := mountinfo.GetMounts(mountinfo.SingleEntryFilter(mnt))
if err != nil {
t.Fatal(err)
}
if len(mounts) != 1 {
t.Fatalf("Could not find mountpoint %q in /proc/self/mountinfo", mnt)
}
m := *mounts[0]
if m.Source != fsname {
t.Errorf("mountinfo(%q): got %q want %q", mnt, m.Source, fsname)
}
}
20 changes: 13 additions & 7 deletions fuse/server.go
Expand Up @@ -185,12 +185,6 @@ func NewServer(fs RawFileSystem, mountPoint string, opts *MountOptions) (*Server
o.Name = strings.Replace(name[:l], ",", ";", -1)
}

for _, s := range o.optionsStrings() {
if strings.Contains(s, ",") {
return nil, fmt.Errorf("found ',' in option string %q", s)
}
}

maxReaders := runtime.GOMAXPROCS(0)
if maxReaders < minMaxReaders {
maxReaders = minMaxReaders
Expand Down Expand Up @@ -251,6 +245,10 @@ func NewServer(fs RawFileSystem, mountPoint string, opts *MountOptions) (*Server
return ms, nil
}

func escape(optionValue string) string {
return strings.Replace(strings.Replace(optionValue, `\`, `\\`, -1), `,`, `\,`, -1)
}

func (o *MountOptions) optionsStrings() []string {
var r []string
r = append(r, o.Options...)
Expand All @@ -273,7 +271,15 @@ func (o *MountOptions) optionsStrings() []string {
r = append(r, "daemon_timeout=0")
}

return r
// Commas and backslashs in an option need to be escaped, because
// options are separated by a comma and backslashs are used to
// escape other characters.
var rEscaped []string
for _, s := range r {
rEscaped = append(rEscaped, escape(s))
}

return rEscaped
}

// DebugData returns internal status information for debugging
Expand Down

0 comments on commit 90b055a

Please sign in to comment.