blob: e860b23cf2a6ee09dc6c484862d7b7f7c9f24a7b [file] [log] [blame]
Sergei Datsenko495f5da2019-06-06 17:44:23 +10001// Copyright 2019 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CROS_DISKS_SANDBOXED_INIT_H_
6#define CROS_DISKS_SANDBOXED_INIT_H_
7
8#include <memory>
9#include <string>
10#include <vector>
11
12#include <sys/types.h>
13
14#include <base/callback.h>
15#include <base/files/scoped_file.h>
Sergei Datsenko495f5da2019-06-06 17:44:23 +100016
17namespace cros_disks {
18
François Degrosc2bfe0e2019-10-14 13:08:49 +110019// Anonymous pipe to establish communication between a parent process and a
20// child process.
21struct SubprocessPipe {
22 base::ScopedFD child_fd, parent_fd;
François Degros4a76d702019-09-26 14:54:35 +100023
François Degrosc2bfe0e2019-10-14 13:08:49 +110024 // Direction of communication.
25 enum Direction { kChildToParent, kParentToChild };
26
27 // Creates an open pipe. Sets FD_CLOEXEC on parent_fd. Dies in case of error.
28 explicit SubprocessPipe(Direction direction);
François Degros1ef69942019-10-01 15:31:17 +100029
30 // Opens a pipe to communicate with a child process. Returns the end of the
31 // pipe that is used by the child process. Stores the end of the pipe that is
32 // kept by the parent process in *parent_fd and flags it with FD_CLOEXEC. Dies
33 // in case of error.
34 static base::ScopedFD Open(Direction direction, base::ScopedFD* parent_fd);
François Degros4a76d702019-09-26 14:54:35 +100035};
36
Sergei Datsenko495f5da2019-06-06 17:44:23 +100037// To run daemons in a PID namespace under minijail we need to provide
38// an "init" process for the sandbox. As we rely on return code of the
39// launcher of the daemonized process we must send it through a side
40// channel back to the caller without waiting to the whole PID namespace
41// to terminate.
42class SandboxedInit {
43 public:
François Degros1ef69942019-10-01 15:31:17 +100044 SandboxedInit(base::ScopedFD in_fd,
45 base::ScopedFD out_fd,
46 base::ScopedFD err_fd,
47 base::ScopedFD ctrl_fd);
Qijiang Fan6bc59e12020-11-11 02:51:06 +090048 SandboxedInit(const SandboxedInit&) = delete;
49 SandboxedInit& operator=(const SandboxedInit&) = delete;
50
Sergei Datsenko495f5da2019-06-06 17:44:23 +100051 ~SandboxedInit();
52
53 // To be run inside the jail. Never returns.
François Degros73168562019-10-03 13:34:26 +100054 [[noreturn]] void RunInsideSandboxNoReturn(
55 base::OnceCallback<int()> launcher);
Sergei Datsenko495f5da2019-06-06 17:44:23 +100056
François Degros02c5c712019-10-03 13:00:11 +100057 static bool PollLauncherStatus(base::ScopedFD* ctrl_fd, int* exit_code);
Sergei Datsenko495f5da2019-06-06 17:44:23 +100058
Sergei Datsenko1c8f2152019-06-19 15:21:21 +100059 static int WStatusToStatus(int wstatus);
60
Sergei Datsenko495f5da2019-06-06 17:44:23 +100061 private:
62 int RunInitLoop(pid_t root_pid, base::ScopedFD ctrl_fd);
Anand K Mistry08a71ca2019-09-13 10:38:20 +100063 pid_t StartLauncher(base::OnceCallback<int()> launcher);
Sergei Datsenko495f5da2019-06-06 17:44:23 +100064
François Degros1ef69942019-10-01 15:31:17 +100065 base::ScopedFD in_fd_, out_fd_, err_fd_, ctrl_fd_;
Sergei Datsenko495f5da2019-06-06 17:44:23 +100066};
67
68} // namespace cros_disks
69
70#endif // CROS_DISKS_SANDBOXED_INIT_H_