Commit 90b055af authored by Levin Zimmermann's avatar Levin Zimmermann

fusermount: Fix option escaping

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] https://github.com/libfuse/libfuse/commit/555d6b504308eac6b976321ce938ee4bec62c354
[2] https://github.com/libfuse/libfuse/commit/5c094ac0150ebfef6a2c9c2c9d1c545a90ff4e96

Change-Id: Iadf8283e630dc1fb884d047d8765eeaaca90eabd
parent 854d591b
...@@ -187,3 +187,31 @@ fusermount: %#v`, o3, o1) ...@@ -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)
}
}
...@@ -185,12 +185,6 @@ func NewServer(fs RawFileSystem, mountPoint string, opts *MountOptions) (*Server ...@@ -185,12 +185,6 @@ func NewServer(fs RawFileSystem, mountPoint string, opts *MountOptions) (*Server
o.Name = strings.Replace(name[:l], ",", ";", -1) 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) maxReaders := runtime.GOMAXPROCS(0)
if maxReaders < minMaxReaders { if maxReaders < minMaxReaders {
maxReaders = minMaxReaders maxReaders = minMaxReaders
...@@ -251,6 +245,10 @@ func NewServer(fs RawFileSystem, mountPoint string, opts *MountOptions) (*Server ...@@ -251,6 +245,10 @@ func NewServer(fs RawFileSystem, mountPoint string, opts *MountOptions) (*Server
return ms, nil return ms, nil
} }
func escape(optionValue string) string {
return strings.Replace(strings.Replace(optionValue, `\`, `\\`, -1), `,`, `\,`, -1)
}
func (o *MountOptions) optionsStrings() []string { func (o *MountOptions) optionsStrings() []string {
var r []string var r []string
r = append(r, o.Options...) r = append(r, o.Options...)
...@@ -273,7 +271,15 @@ func (o *MountOptions) optionsStrings() []string { ...@@ -273,7 +271,15 @@ func (o *MountOptions) optionsStrings() []string {
r = append(r, "daemon_timeout=0") 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 // DebugData returns internal status information for debugging
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment