xref: /aosp_15_r20/external/sandboxed-api/sandboxed_api/sandbox2/util/maps_parser.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "sandboxed_api/sandbox2/util/maps_parser.h"
16 
17 #include <cstdio>
18 #include <cstring>
19 #include <string>
20 #include <vector>
21 
22 #include "absl/status/status.h"
23 #include "absl/status/statusor.h"
24 #include "absl/strings/str_split.h"
25 
26 namespace sandbox2 {
27 
ParseProcMaps(const std::string & contents)28 absl::StatusOr<std::vector<MapsEntry>> ParseProcMaps(
29     const std::string& contents) {
30   // Note: The format string
31   //       https://github.com/torvalds/linux/blob/v4.14/fs/proc/task_mmu.c#L289
32   //       changed to a non-format string implementation
33   //       (show_vma_header_prefix()).
34   static constexpr char kFormatString[] =
35       "%lx-%lx %c%c%c%c %lx %x:%x %lu %1023s";
36   static constexpr size_t kFilepathLength = 1023;
37 
38   std::vector<std::string> lines =
39       absl::StrSplit(contents, '\n', absl::SkipEmpty());
40   std::vector<MapsEntry> entries;
41   for (const auto& line : lines) {
42     MapsEntry entry{};
43     char r, w, x, s;
44     entry.path.resize(kFilepathLength + 1, '\0');
45     int n_matches = sscanf(
46         line.c_str(), kFormatString, &entry.start, &entry.end, &r, &w, &x, &s,
47         &entry.pgoff, &entry.major, &entry.minor, &entry.inode, &entry.path[0]);
48 
49     // Some lines do not have a filename.
50     if (n_matches == 10) {
51       entry.path.clear();
52     } else if (n_matches == 11) {
53       entry.path.resize(strlen(entry.path.c_str()));
54     } else {
55       return absl::FailedPreconditionError("Invalid format");
56     }
57     entry.is_readable = r == 'r';
58     entry.is_writable = w == 'w';
59     entry.is_executable = x == 'x';
60     entry.is_shared = s == 's';
61     entries.push_back(entry);
62   }
63   return entries;
64 }
65 
66 }  // namespace sandbox2
67