Skip to content

mountinfo: correctness improvements#50

Merged
kolyshkin merged 3 commits intomoby:masterfrom
cyphar:mountinfo-improvements
Oct 21, 2020
Merged

mountinfo: correctness improvements#50
kolyshkin merged 3 commits intomoby:masterfrom
cyphar:mountinfo-improvements

Conversation

@cyphar
Copy link
Copy Markdown
Contributor

@cyphar cyphar commented Oct 20, 2020

This fixes two correctness issues with mountinfo (one of which caused opencontainers/runc#2647 to be a security regression):

  • Correctly handle IO errors during scanning.
  • Run the filter function after all fields are parsed.

Signed-off-by: Aleksa Sarai cyphar@cyphar.com

The previous code would actually ignore IO errors during scanning,
becuase s.Scan() returns false if there was an error (leaving the loop
and never being detected). Indeed the correct way[1] of using the
builtin bufio.Scanner is actually more like:

  s := bufio.NewScanner(...)
  for s.Scan() {
      // use s.Text()
  }
  if err := s.Err(); err != nil {
      return err
  }

[1]: https://blog.golang.org/errors-are-values

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
@@ -18,11 +18,9 @@ import (
func GetMountsFromReader(r io.Reader, filter FilterFunc) ([]*Info, error) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we have a UT?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added. There were a few for this function already, just not one for the FilterFunc callback.

@kolyshkin
Copy link
Copy Markdown
Collaborator

Previously, the filter would be run before all of the fields were parsed
(this behaviour also was not documented) -- this resulted in users of
the function accidentally assuming that fields like fsinfo.Root would
actually be filled correctly.

This is actually documented:

// FilterFunc is a type defining a callback function for GetMount(),
// used to filter out mountinfo entries we're not interested in,
// and/or stop further processing if we found what we wanted.
//
// It takes a pointer to the Info struct (not fully populated,
// currently only Mountpoint, FSType, Source, and (on Linux)
// VFSOptions are filled in), and returns two booleans:
//
// skip: true if the entry should be skipped;
//
// stop: true if parsing should be stopped after the entry.
type FilterFunc func(*Info) (skip, stop bool)

so the second commit needs to be amended accordingly.

There is also a comment in the code that needs to be removed:

// Fill in the fields that a filter might check

Otherwise LGTM

Copy link
Copy Markdown
Collaborator

@kolyshkin kolyshkin left a comment

Choose a reason for hiding this comment

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

Need to update FilterFunc docs and remove a comment in the code (see above).

@cyphar
Copy link
Copy Markdown
Contributor Author

cyphar commented Oct 21, 2020

@kolyshkin

This is actually documented:

Ah, I was looking at the docs of this function not FilterFunc. 🙇

Previously, the filter would be run before all of the fields were parsed
(this behaviour also was not documented) -- this resulted in users of
the function accidentally assuming that fields like fsinfo.Root would
actually be filled correctly. It seems that the performance overhead of
parsing a few extra fields is not exorbitant, and optimising this just
leads to incorrect user code.

For a concrete example, this optimisation actually made this runc
change[1] regress a security hardening feature because it relied on
fsinfo.Root being filled correctly.

[1]: opencontainers/runc#2647

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
Copy link
Copy Markdown
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Copy Markdown
Collaborator

@kolyshkin kolyshkin left a comment

Choose a reason for hiding this comment

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

LGTM

@kolyshkin kolyshkin merged commit 9a75fe6 into moby:master Oct 21, 2020
@thaJeztah
Copy link
Copy Markdown
Member

@kolyshkin should we tag a new release with this?

@cyphar cyphar deleted the mountinfo-improvements branch October 21, 2020 22:03
@kolyshkin
Copy link
Copy Markdown
Collaborator

@kolyshkin should we tag a new release with this?

I already did, https://github.com/moby/sys/releases/tag/mountinfo%2Fv0.4.0

Yet there are no users that are affected (runc was, but this is being fixed by opencontainers/runc#2655)

@thaJeztah
Copy link
Copy Markdown
Member

Oh! Somehow didn't get a notification; thanks!

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.

4 participants