Parse mount options with double quotes and commas correctly

A mount option can contain commas in double quoted string. Such comma is
part of the mount option and it is not option separator.

For example, this is a single mount option:
  context="system_u:object_r:container_file_t:s0:c460,c902"
This commit is contained in:
Jan Safranek 2022-02-16 14:12:16 +01:00
parent a06e272124
commit 1bc658a2d8
2 changed files with 34 additions and 2 deletions

View File

@ -136,7 +136,7 @@ func ParseMountInfo(filename string) ([]MountInfo, error) {
Minor: minor,
Root: fields[3],
MountPoint: fields[4],
MountOptions: strings.Split(fields[5], ","),
MountOptions: splitMountOptions(fields[5]),
}
// All fields until "-" are "optional fields".
i := 6
@ -150,12 +150,26 @@ func ParseMountInfo(filename string) ([]MountInfo, error) {
}
info.FsType = fields[i]
info.Source = fields[i+1]
info.SuperOptions = strings.Split(fields[i+2], ",")
info.SuperOptions = splitMountOptions(fields[i+2])
infos = append(infos, info)
}
return infos, nil
}
// splitMountOptions parses comma-separated list of mount options into an array.
// It respects double quotes - commas in them are not considered as the option separator.
func splitMountOptions(s string) []string {
inQuotes := false
list := strings.FieldsFunc(s, func(r rune) bool {
if r == '"' {
inQuotes = !inQuotes
}
// Report a new field only when outside of double quotes.
return r == ',' && !inQuotes
})
return list
}
// isMountPointMatch returns true if the path in mp is the same as dir.
// Handles case where mountpoint dir has been renamed due to stale NFS mount.
func isMountPointMatch(mp MountPoint, dir string) bool {

View File

@ -83,6 +83,7 @@ func TestParseMountInfo(t *testing.T) {
38 28 0:34 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:20 - cgroup cgroup rw,blkio
39 28 0:35 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime shared:21 - cgroup cgroup rw,memory
40 28 0:36 / /sys/fs/cgroup/perf_event rw,nosuid,nodev,noexec,relatime shared:22 - cgroup cgroup rw,perf_event
761 60 8:0 / /var/lib/kubelet/plugins/kubernetes.io/iscsi/iface-default/127.0.0.1:3260-iqn.2003-01.org.linux-iscsi.f21.x8664:sn.4b0aae584f7c-lun-0 rw,relatime shared:421 - ext4 /dev/sda rw,context="system_u:object_r:container_file_t:s0:c314,c894",data=ordered
`
tempDir, filename, err := writeFile(info)
if err != nil {
@ -197,6 +198,23 @@ func TestParseMountInfo(t *testing.T) {
SuperOptions: []string{"rw", "cpuset"},
},
},
{
"mount option with commas inside quotes",
761,
MountInfo{
ID: 761,
ParentID: 60,
Major: 8,
Minor: 0,
Root: "/",
Source: "/dev/sda",
MountPoint: "/var/lib/kubelet/plugins/kubernetes.io/iscsi/iface-default/127.0.0.1:3260-iqn.2003-01.org.linux-iscsi.f21.x8664:sn.4b0aae584f7c-lun-0",
OptionalFields: []string{"shared:421"},
FsType: "ext4",
MountOptions: []string{"rw", "relatime"},
SuperOptions: []string{"rw", "context=\"system_u:object_r:container_file_t:s0:c314,c894\"", "data=ordered"},
},
},
}
infos, err := ParseMountInfo(filename)