Fix mount_util mountinfo parsing to account for multiple optional tags.

Before this change, the parsing fails with a PosixError saying the line
has too many entries.

PiperOrigin-RevId: 483777338
This commit is contained in:
Lucas Manning
2022-10-25 14:33:15 -07:00
committed by gVisor bot
parent 7e3bd4db0f
commit db4a71af39
4 changed files with 22 additions and 9 deletions
+1
View File
@@ -164,6 +164,7 @@ cc_library(
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/strings",
gtest,
"@com_google_absl//absl/types:span",
],
)
+13 -9
View File
@@ -18,7 +18,9 @@
#include <unistd.h>
#include "absl/strings/numbers.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "absl/types/span.h"
namespace gvisor {
namespace testing {
@@ -103,11 +105,11 @@ PosixErrorOr<std::vector<ProcMountInfoEntry>> ProcSelfMountInfoEntriesFrom(
ProcMountInfoEntry entry;
std::vector<std::string> fields =
absl::StrSplit(line, absl::ByChar(' '), absl::AllowEmpty());
if (fields.size() < 10 || fields.size() > 11) {
if (fields.size() < 10 || fields.size() > 13) {
return PosixError(
EINVAL, absl::StrFormat(
"Unexpected number of tokens, got %d, content: <<%s>>",
fields.size(), content));
EINVAL,
absl::StrFormat("Unexpected number of tokens, got %d, line: <<%s>>",
fields.size(), line));
}
ASSIGN_OR_RETURN_ERRNO(entry.id, Atoi<uint64_t>(fields[0]));
@@ -129,12 +131,14 @@ PosixErrorOr<std::vector<ProcMountInfoEntry>> ProcSelfMountInfoEntriesFrom(
entry.mount_point = fields[4];
entry.mount_opts = fields[5];
// The optional field (fields[6]) may or may not be present. We know based
// on the total number of tokens.
// The optional field (fields[6]) may or may not be present and can have up
// to 3 elements. We know based on the total number of tokens.
int off = -1;
if (fields.size() == 11) {
entry.optional = fields[6];
off = 0;
if (fields.size() > 10) {
int num_optional_tags = fields.size() - 10;
entry.optional = absl::StrJoin(
absl::MakeSpan(fields).subspan(6, num_optional_tags), " ");
off += num_optional_tags;
}
// Field 7 is the optional field terminator char '-'.
entry.fstype = fields[8 + off];
+7
View File
@@ -37,6 +37,13 @@ TEST(ParseMounts, MountInfo) {
R"proc(22 28 0:20 / /sys rw,relatime shared:7 - sysfs sysfs rw
23 28 0:21 / /proc rw,relatime shared:14 - proc proc rw
2007 8844 0:278 / /mnt rw,noexec - tmpfs rw,mode=123,uid=268601820,gid=5000
)proc"));
EXPECT_EQ(entries.size(), 3);
entries = ASSERT_NO_ERRNO_AND_VALUE(ProcSelfMountInfoEntriesFrom(
R"proc(22 28 0:20 / /sys rw,relatime shared:7 master:20 - sysfs sysfs rw
23 28 0:21 / /proc rw,relatime shared:14 master:20 propagate_from:1 - proc proc rw
2007 8844 0:278 / /mnt rw,noexec - tmpfs rw,mode=123,uid=268601820,gid=5000
)proc"));
EXPECT_EQ(entries.size(), 3);
}
+1
View File
@@ -64,6 +64,7 @@ class ABSL_MUST_USE_RESULT PosixError {
private:
int errno_ = 0;
// std::string is not async-signal-safe. We must use a c string instead.
char msg_[1024] = {};
};