Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cope with double quotes in Linux Mountinfo #4325

Merged
merged 4 commits into from
Jun 24, 2020

Conversation

johannesfrey
Copy link
Contributor

This PR resolves the double quote problem described in issue #4257

@theopenlab-ci
Copy link

theopenlab-ci bot commented Jun 16, 2020

Build succeeded.

@@ -439,6 +439,9 @@ const (

mountInfoWithSpaces = `486 28 252:1 / /mnt/foo\040bar rw,relatime shared:243 - ext4 /dev/vda1 rw,data=ordered
31 21 0:23 / /DATA/foo_bla_bla rw,relatime - cifs //foo/BLA\040BLA\040BLA/ rw,sec=ntlm,cache=loose,unc=\\foo\BLA BLA BLA,username=my_login,domain=mydomain.com,uid=12345678,forceuid,gid=12345678,forcegid,addr=10.1.30.10,file_mode=0755,dir_mode=0755,nounix,rsize=61440,wsize=65536,actimeo=1`

mountInfoWithDoubleQuotes = `1046 30 253:1 /tmp/bar /var/lib/kubelet/pods/98d150a4-d814-4d52-9068-b10f62d7a895/volumes/kubernetes.io~empty-dir/tmp-dir/"var rw,relatime shared:1 - ext4 /dev/mapper/ubuntu--vg-root rw,errors=remount-ro
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also test with a path that contains \" (backslash + quote)?

Copy link
Contributor Author

@johannesfrey johannesfrey Jun 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mounting a directory containing a backslash will display it ascii escaped in /proc/self/mountinfo:

mkdir '/tmp/\"bar\"'
mkdir /tmp/bar
sudo mount --bind /tmp/bar '/tmp/\"bar\"'

cat /proc/self/mountinfo | grep bar
1100 30 253:1 /tmp/bar /tmp/\134"bar\134" rw,relatime shared:1 - ext4 /dev/mapper/ubuntu--vg-root rw,errors=remount-ro

So I added a testcase that receives the backslash ascii character. Did you mean it this way? It seems that a literal \" cannot show up in the output of /proc/self/mountinfo.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thanks

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to double-check; the field (as a whole) is never quoted? ("/var/lib/....."), so no exception is needed for leading/trailing quote?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh (sorry for the noise); would single quotes have the same problem?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem, valid questions 😉. For the latter I added some more test cases.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that a literal " cannot show up in the output of /proc/self/mountinfo

It's not really clear to me then why it is using unquote at all

Copy link
Contributor

@kolyshkin kolyshkin Jun 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not really clear to me then why it is using unquote at all

So, mountinfo entries quote the following characters, using escape sequences with their octal ascii codes:

  • (i.e. space) -- as \040
  • \t (i.e. tab) -- as \011
  • \n (i.e. newline) -- as \012
  • \\ (i.e. backslash) -- as \134

The unquote was added (by @thaJeztah AFAIR) to convert these escape sequences back to spaces, tabs etc. It does that but messes up double quotes.

I think the solution is to manually interpret the above sequences.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the solution is to manually interpret the above sequences.

I mean, write our own function to de-escape \040, \011, \012 and \134 instead of using strconv.Unquite

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I agree with that. Looking at the implementation of strconv.Unquote makes it seem like it is unnecessary to quote then use that. If these are the case we need to test against, then we should add them to the tests.

If you look at the strconv.Unquote function you will see it first just does some checks whether it contains some of these special characters. This could probably do the same thing and if there is no backslash, just return.

@theopenlab-ci
Copy link

theopenlab-ci bot commented Jun 16, 2020

Build succeeded.

@johannesfrey johannesfrey force-pushed the mountinfo-linux-double-quotes branch from 8f23ce2 to 33d6abc Compare June 16, 2020 10:03
@theopenlab-ci
Copy link

theopenlab-ci bot commented Jun 16, 2020

Build succeeded.

@thaJeztah
Copy link
Member

/cc @kolyshkin ptal

Signed-off-by: Johannes Frey <me@johannes-frey.de>
Signed-off-by: Johannes Frey <me@johannes-frey.de>
Signed-off-by: Johannes Frey <me@johannes-frey.de>
@johannesfrey johannesfrey force-pushed the mountinfo-linux-double-quotes branch from 33d6abc to 8897e15 Compare June 16, 2020 11:07
@theopenlab-ci
Copy link

theopenlab-ci bot commented Jun 16, 2020

Build succeeded.

Copy link
Member

@estesp estesp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

if err != nil {
return nil, errors.Wrapf(err, "parsing '%s' failed: unable to unquote root field", fields[3])
}
p.Mountpoint, err = strconv.Unquote(`"` + fields[4] + `"`)
p.Mountpoint, err = strconv.Unquote(`"` + strings.Replace(fields[4], `"`, `\"`, -1) + `"`)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would switching to backquote solve this out the extra replace. https://golang.org/pkg/strconv/#Unquote

`"` -> "`"

Unless of course backquote also needs to be supported...

Copy link
Contributor Author

@johannesfrey johannesfrey Jun 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems so:

› cat /proc/self/mountinfo | grep "foo\|bar"
1047 30 253:1 /tmp/`foo` /tmp/bar rw,relatime shared:1 - ext4 /dev/mapper/ubuntu--vg-root rw,errors=remount-ro

I added a test case containing backticks as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with backticks, \040 is not expanded and this brings back the bug that the initial unquote solves.

@theopenlab-ci
Copy link

theopenlab-ci bot commented Jun 18, 2020

Build succeeded.

Signed-off-by: Johannes Frey <me@johannes-frey.de>
@johannesfrey johannesfrey force-pushed the mountinfo-linux-double-quotes branch from 5d09a5b to ee734e8 Compare June 18, 2020 06:37
@theopenlab-ci
Copy link

theopenlab-ci bot commented Jun 18, 2020

Build succeeded.

@kolyshkin
Copy link
Contributor

kolyshkin commented Jun 18, 2020

Left a suggestion (#4325 (comment)) on how to fix this effectively.

WRT test cases -- I would separate out the filename unquote function and write test cases for it.

In general, I would love this repo to switch to using github.com/moby/sys/mountinfo

@kolyshkin
Copy link
Contributor

Fixed the same bug in github.com/moby/sys/mountinfo, see moby/sys#16

It would be beneficial to reuse that repo here; if not, the fix can be ported.

@dmcgowan
Copy link
Member

Doing a direct escape seems like the right thing to do here. Adding a dependency doesn't make much sense for this change, especially since we have avoided bringing in this dependency in the past.

@kolyshkin is there any documentation you can link to related to that set of characters or just the use of octal encoding in that file?

@kolyshkin
Copy link
Contributor

kolyshkin commented Jun 23, 2020

Adding a dependency doesn't make much sense for this change

I am not proposing the use of moby/sys/mountinfo for this particular change, but rather for overall simplification and easement of maintenance burden. containerd's mountinfo is a fork of the one in moby, and now every bugfix, feature, or improvement needs to be done in two places.

since we have avoided bringing in this dependency in the past

You're probably talking about moby/moby. Using packages from moby/moby is not possible, as it will lead to circular dependencies. This was one of the main reasons why moby/sys was born -- it does not have any outside deps and can be used by any project. After cross-porting some stuff from moby and containerd and back, I think the best solution long-term is to have a single place for such stuff.

I remember @crosbymichael at least considered the idea of using moby/sys in containerd earlier.

is there any documentation you can link to related to that set of characters or just the use of octal encoding in that file?

Probably not (there's proc(5) man page that describes mountinfo, but it does not mention escaping).

The source for what I wrote earlier is kernel source code, specifically, show_mountinfo in fs/proc_namespace.c, which calls seq_dentry in fs/seq_file.c (with the last argument being the characters to escape), which calls mangle_path in the same file, which does the actual escaping.

https://github.com/torvalds/linux/blob/dd0d718152e4c65b173070d48ea9dfc06894c3e5/fs/proc_namespace.c#L146

https://github.com/torvalds/linux/blob/dd0d718152e4c65b173070d48ea9dfc06894c3e5/fs/seq_file.c#L399-L428

@kolyshkin
Copy link
Contributor

is there any documentation you can link to related to that set of characters or just the use of octal encoding in that file?

In addition to source code references above, today I found https://www.kernel.org/doc/Documentation/filesystems/seq_file.txt (look for seq_escape) which might add some more context.

Copy link
Member

@dmcgowan dmcgowan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

This is a small PR with mostly tests, let's get this merged then moving away from Unquote can be a follow up

Copy link
Member

@crosbymichael crosbymichael left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@crosbymichael crosbymichael merged commit c751807 into containerd:master Jun 24, 2020
thaJeztah added a commit to thaJeztah/sys that referenced this pull request Sep 22, 2020
This adds tests for handling paths containing double quotes, and
is the equivalent to the changes made in containerd/containerd#4325
to fix the problem described in containerd/containerd#4257

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
thaJeztah added a commit to thaJeztah/sys that referenced this pull request Sep 22, 2020
This adds tests for handling paths containing double quotes, and
is the equivalent of the tests added in containerd/containerd#4325

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants