-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlibcontainer_util.h
146 lines (112 loc) · 5.03 KB
/
libcontainer_util.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LIBCONTAINER_LIBCONTAINER_UTIL_H_
#define LIBCONTAINER_LIBCONTAINER_UTIL_H_
#include <linux/loop.h>
#include <string>
#include <vector>
#include <base/callback_forward.h>
#include <base/files/file_path.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/macros.h>
#include <libminijail.h>
#include "libcontainer/config.h"
#include "libcontainer/libcontainer.h"
namespace libcontainer {
// WaitablePipe provides a way for one process to wait on another. This only
// uses the read(2) and close(2) syscalls, so it can work even in a restrictive
// environment. Each process must call only one of Wait() and Signal() exactly
// once.
struct WaitablePipe {
WaitablePipe();
~WaitablePipe();
WaitablePipe(WaitablePipe&&);
WaitablePipe(const WaitablePipe&) = delete;
WaitablePipe& operator=(const WaitablePipe&) = delete;
// Waits for Signal() to be called.
void Wait();
// Notifies the process that called Wait() to continue running.
void Signal();
int pipe_fds[2];
};
// HookState holds two WaitablePipes so that the container can wait for its
// parent to run prestart hooks just prior to calling execve(2).
class HookState {
public:
HookState();
~HookState();
HookState(HookState&& state);
HookState(const HookState&) = delete;
HookState& operator=(const HookState&) = delete;
// Initializes this HookState so that WaitForHookAndRun() can be invoked and
// waited upon when |j| reaches |event|. Returns true on success.
bool InstallHook(minijail* j, minijail_hook_event_t event);
// Waits for the event specified in InstallHook() and invokes |callbacks| in
// the caller process. Returns true if all callbacks succeeded.
bool WaitForHookAndRun(const std::vector<HookCallback>& callbacks,
pid_t container_pid);
private:
// A function that can be passed to minijail_add_hook() that blocks the
// process in the container until the parent has finished running whatever
// operations are needed outside the container. This is not expected to be
// called directly.
static int WaitHook(void* payload);
bool installed_ = false;
WaitablePipe reached_pipe_;
WaitablePipe ready_pipe_;
};
// Loopdev represents an active loopback device.
struct Loopdev {
// The path of the loopback device. e.g. /dev/loop1
base::FilePath path;
// An open file descriptor for the loopback device. Has the autoclear flag,
// such that the kernel will automatically remove it once all references to it
// are closed.
base::ScopedFD fd;
// Information about the loop device.
struct loop_info64 info;
};
// Given a uid/gid map of "inside1 outside1 length1, ...", and an id inside of
// the user namespace, populate |id_out|. Returns true on success.
bool GetUsernsOutsideId(const std::string& map, int id, int* id_out);
bool MakeDir(const base::FilePath& path, int uid, int gid, int mode);
bool TouchFile(const base::FilePath& path, int uid, int gid, int mode);
// Find a free loop device and attach it.
bool LoopdevSetup(const base::FilePath& source, Loopdev* loopdev_out);
// Detach the specified loop device.
bool LoopdevDetach(Loopdev* loopdev);
// Create a new device mapper target for the source.
bool DeviceMapperSetup(const base::FilePath& source,
const std::string& verity_cmdline,
base::FilePath* dm_path_out,
std::string* dm_name_out);
// Tear down the device mapper target.
bool DeviceMapperDetach(const std::string& dm_name);
// Match mount_one in minijail, mount one mountpoint with
// consideration for combination of MS_BIND/MS_RDONLY flag.
bool MountExternal(const std::string& src,
const std::string& dest,
const std::string& type,
unsigned long flags,
const std::string& data);
// Creates a pipe using pipe2(2) and returns both ends as base::ScopedFDs.
bool Pipe2(base::ScopedFD* read_pipe, base::ScopedFD* write_pipe, int flags);
// Creates a callback that will fork(2)+execve(2) the program specified by args.
HookCallback CreateExecveCallback(base::FilePath filename,
std::vector<std::string> args,
base::ScopedFD stdin_fd,
base::ScopedFD stdout_fd,
base::ScopedFD stderr_fd);
// Wraps a callback to be run in a subset of the container's namespaces.
HookCallback AdaptCallbackToRunInNamespaces(HookCallback callback,
std::vector<int> nstypes);
// Similar to base::CreateDirectory, but allows specifying the created
// directories' mode and owner.
bool CreateDirectoryOwnedBy(const base::FilePath& full_path,
mode_t mode,
uid_t uid,
gid_t gid);
} // namespace libcontainer
#endif // LIBCONTAINER_LIBCONTAINER_UTIL_H_