Compare commits
10 Commits
3f917b326b
...
1247f5d3e5
Author | SHA1 | Date | |
---|---|---|---|
1247f5d3e5 | |||
![]() |
765eb0bf16 | ||
![]() |
0608ec42f2 | ||
![]() |
c9b2413465 | ||
![]() |
ba23b05545 | ||
![]() |
57d8aa8ffe | ||
![]() |
cbca08cd38 | ||
![]() |
fcfb592adc | ||
![]() |
d02bb6ca05 | ||
![]() |
45b8632dcc |
23
conf.c
23
conf.c
@@ -38,6 +38,7 @@
|
||||
#include "ip.h"
|
||||
#include "passt.h"
|
||||
#include "netlink.h"
|
||||
#include "tap.h"
|
||||
#include "udp.h"
|
||||
#include "tcp.h"
|
||||
#include "pasta.h"
|
||||
@@ -1093,7 +1094,7 @@ static void conf_ugid(char *runas, uid_t *uid, gid_t *gid)
|
||||
return;
|
||||
|
||||
/* ...otherwise use nobody:nobody */
|
||||
warn("Don't run as root. Changing to nobody...");
|
||||
warn("Started as root, will change to nobody.");
|
||||
{
|
||||
#ifndef GLIBC_NO_STATIC_NSS
|
||||
const struct passwd *pw;
|
||||
@@ -1113,6 +1114,18 @@ static void conf_ugid(char *runas, uid_t *uid, gid_t *gid)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* conf_open_files() - Open files as requested by configuration
|
||||
* @c: Execution context
|
||||
*/
|
||||
static void conf_open_files(struct ctx *c)
|
||||
{
|
||||
if (c->mode == MODE_PASST && c->fd_tap == -1)
|
||||
c->fd_tap_listen = tap_sock_unix_open(c->sock_path);
|
||||
|
||||
c->pidfile_fd = pidfile_open(c->pidfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* conf() - Process command-line arguments and set configuration
|
||||
* @c: Execution context
|
||||
@@ -1443,12 +1456,12 @@ void conf(struct ctx *c, int argc, char **argv)
|
||||
|
||||
break;
|
||||
case 'P':
|
||||
if (*c->pid_file)
|
||||
if (*c->pidfile)
|
||||
die("Multiple --pid options given");
|
||||
|
||||
ret = snprintf(c->pid_file, sizeof(c->pid_file), "%s",
|
||||
ret = snprintf(c->pidfile, sizeof(c->pidfile), "%s",
|
||||
optarg);
|
||||
if (ret <= 0 || ret >= (int)sizeof(c->pid_file))
|
||||
if (ret <= 0 || ret >= (int)sizeof(c->pidfile))
|
||||
die("Invalid PID file: %s", optarg);
|
||||
|
||||
break;
|
||||
@@ -1712,6 +1725,8 @@ void conf(struct ctx *c, int argc, char **argv)
|
||||
else if (optind != argc)
|
||||
die("Extra non-option argument: %s", argv[optind]);
|
||||
|
||||
conf_open_files(c); /* Before any possible setuid() / setgid() */
|
||||
|
||||
isolate_user(uid, gid, !netns_only, userns, c->mode);
|
||||
|
||||
if (c->pasta_conf_ns)
|
||||
|
@@ -27,7 +27,7 @@
|
||||
@{PROC}/@{pid}/net/udp r,
|
||||
@{PROC}/@{pid}/net/udp6 r,
|
||||
|
||||
@{run}/user/@{uid}/** rw, # pasta_open_ns(), main()
|
||||
@{run}/user/@{uid}/** rw, # pasta_open_ns()
|
||||
|
||||
@{PROC}/[0-9]*/ns/ r, # pasta_netns_quit_init(),
|
||||
@{PROC}/[0-9]*/ns/net r, # pasta_wait_for_ns(),
|
||||
|
@@ -19,9 +19,12 @@ profile passt /usr/bin/passt{,.avx2} {
|
||||
include <abstractions/passt>
|
||||
|
||||
# Alternatively: include <abstractions/user-tmp>
|
||||
owner /tmp/** w, # tap_sock_unix_init(), pcap(),
|
||||
# write_pidfile(),
|
||||
owner /tmp/** w, # tap_sock_unix_open(),
|
||||
# tap_sock_unix_init(), pcap(),
|
||||
# pidfile_open(),
|
||||
# pidfile_write(),
|
||||
# logfile_init()
|
||||
|
||||
owner @{HOME}/** w, # pcap(), write_pidfile()
|
||||
owner @{HOME}/** w, # pcap(), pidfile_open(),
|
||||
# pidfile_write()
|
||||
}
|
||||
|
@@ -19,10 +19,13 @@ profile pasta /usr/bin/pasta{,.avx2} flags=(attach_disconnected) {
|
||||
include <abstractions/pasta>
|
||||
|
||||
# Alternatively: include <abstractions/user-tmp>
|
||||
/tmp/** rw, # tap_sock_unix_init(), pcap(),
|
||||
# write_pidfile(),
|
||||
/tmp/** rw, # tap_sock_unix_open(),
|
||||
# tap_sock_unix_init(), pcap(),
|
||||
# pidfile_open(),
|
||||
# pidfile_write(),
|
||||
# logfile_init(),
|
||||
# pasta_open_ns()
|
||||
|
||||
owner @{HOME}/** w, # pcap(), write_pidfile()
|
||||
owner @{HOME}/** w, # pcap(), pidfile_open(),
|
||||
# pidfile_write()
|
||||
}
|
||||
|
17
passt.c
17
passt.c
@@ -199,9 +199,9 @@ void exit_handler(int signal)
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int nfds, i, devnull_fd = -1, pidfile_fd = -1;
|
||||
struct epoll_event events[EPOLL_EVENTS];
|
||||
char *log_name, argv0[PATH_MAX], *name;
|
||||
int nfds, i, devnull_fd = -1;
|
||||
struct ctx c = { 0 };
|
||||
struct rlimit limit;
|
||||
struct timespec now;
|
||||
@@ -211,7 +211,7 @@ int main(int argc, char **argv)
|
||||
|
||||
isolate_initial();
|
||||
|
||||
c.pasta_netns_fd = c.fd_tap = c.fd_tap_listen = -1;
|
||||
c.pasta_netns_fd = c.fd_tap = c.pidfile_fd = -1;
|
||||
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
@@ -299,15 +299,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (*c.pid_file) {
|
||||
if ((pidfile_fd = open(c.pid_file,
|
||||
O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC,
|
||||
S_IRUSR | S_IWUSR)) < 0) {
|
||||
perror("PID file open");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (isolate_prefork(&c))
|
||||
die("Failed to sandbox process, exiting");
|
||||
|
||||
@@ -315,9 +306,9 @@ int main(int argc, char **argv)
|
||||
__openlog(log_name, 0, LOG_DAEMON);
|
||||
|
||||
if (!c.foreground)
|
||||
__daemon(pidfile_fd, devnull_fd);
|
||||
__daemon(c.pidfile_fd, devnull_fd);
|
||||
else
|
||||
write_pidfile(pidfile_fd, getpid());
|
||||
pidfile_write(c.pidfile_fd, getpid());
|
||||
|
||||
if (pasta_child_pid)
|
||||
kill(pasta_child_pid, SIGUSR1);
|
||||
|
8
passt.h
8
passt.h
@@ -184,7 +184,8 @@ struct ip6_ctx {
|
||||
* @nofile: Maximum number of open files (ulimit -n)
|
||||
* @sock_path: Path for UNIX domain socket
|
||||
* @pcap: Path for packet capture file
|
||||
* @pid_file: Path to PID file, empty string if not configured
|
||||
* @pidfile: Path to PID file, empty string if not configured
|
||||
* @pidfile_fd: File descriptor for PID file, -1 if none
|
||||
* @pasta_netns_fd: File descriptor for network namespace in pasta mode
|
||||
* @no_netns_quit: In pasta mode, don't exit if fs-bound namespace is gone
|
||||
* @netns_base: Base name for fs-bound namespace, if any, in pasta mode
|
||||
@@ -234,7 +235,10 @@ struct ctx {
|
||||
int nofile;
|
||||
char sock_path[UNIX_PATH_MAX];
|
||||
char pcap[PATH_MAX];
|
||||
char pid_file[PATH_MAX];
|
||||
|
||||
char pidfile[PATH_MAX];
|
||||
int pidfile_fd;
|
||||
|
||||
int one_off;
|
||||
|
||||
int pasta_netns_fd;
|
||||
|
55
tap.c
55
tap.c
@@ -1095,14 +1095,14 @@ restart:
|
||||
}
|
||||
|
||||
/**
|
||||
* tap_sock_unix_init() - Create and bind AF_UNIX socket, listen for connection
|
||||
* @c: Execution context
|
||||
* tap_sock_unix_open() - Create and bind AF_UNIX socket
|
||||
* @sock_path: Socket path. If empty, set on return (UNIX_SOCK_PATH as prefix)
|
||||
*
|
||||
* Return: socket descriptor on success, won't return on failure
|
||||
*/
|
||||
static void tap_sock_unix_init(struct ctx *c)
|
||||
int tap_sock_unix_open(char *sock_path)
|
||||
{
|
||||
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
union epoll_ref ref = { .type = EPOLL_TYPE_TAP_LISTEN };
|
||||
struct epoll_event ev = { 0 };
|
||||
struct sockaddr_un addr = {
|
||||
.sun_family = AF_UNIX,
|
||||
};
|
||||
@@ -1111,18 +1111,12 @@ static void tap_sock_unix_init(struct ctx *c)
|
||||
if (fd < 0)
|
||||
die("UNIX socket: %s", strerror(errno));
|
||||
|
||||
/* In passt mode, we don't know the guest's MAC until it sends
|
||||
* us packets. Use the broadcast address so our first packets
|
||||
* will reach it.
|
||||
*/
|
||||
memset(&c->mac_guest, 0xff, sizeof(c->mac_guest));
|
||||
|
||||
for (i = 1; i < UNIX_SOCK_MAX; i++) {
|
||||
char *path = addr.sun_path;
|
||||
int ex, ret;
|
||||
|
||||
if (*c->sock_path)
|
||||
memcpy(path, c->sock_path, UNIX_PATH_MAX);
|
||||
if (*sock_path)
|
||||
memcpy(path, sock_path, UNIX_PATH_MAX);
|
||||
else
|
||||
snprintf(path, UNIX_PATH_MAX - 1, UNIX_SOCK_PATH, i);
|
||||
|
||||
@@ -1133,7 +1127,7 @@ static void tap_sock_unix_init(struct ctx *c)
|
||||
ret = connect(ex, (const struct sockaddr *)&addr, sizeof(addr));
|
||||
if (!ret || (errno != ENOENT && errno != ECONNREFUSED &&
|
||||
errno != EACCES)) {
|
||||
if (*c->sock_path)
|
||||
if (*sock_path)
|
||||
die("Socket path %s already in use", path);
|
||||
|
||||
close(ex);
|
||||
@@ -1143,25 +1137,39 @@ static void tap_sock_unix_init(struct ctx *c)
|
||||
|
||||
unlink(path);
|
||||
if (!bind(fd, (const struct sockaddr *)&addr, sizeof(addr)) ||
|
||||
*c->sock_path)
|
||||
*sock_path)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == UNIX_SOCK_MAX)
|
||||
die("UNIX socket bind: %s", strerror(errno));
|
||||
|
||||
info("UNIX domain socket bound at %s\n", addr.sun_path);
|
||||
info("UNIX domain socket bound at %s", addr.sun_path);
|
||||
if (!*sock_path)
|
||||
memcpy(sock_path, addr.sun_path, UNIX_PATH_MAX);
|
||||
|
||||
listen(fd, 0);
|
||||
return fd;
|
||||
}
|
||||
|
||||
ref.fd = c->fd_tap_listen = fd;
|
||||
/**
|
||||
* tap_sock_unix_init() - Start listening for connections on AF_UNIX socket
|
||||
* @c: Execution context
|
||||
*/
|
||||
static void tap_sock_unix_init(struct ctx *c)
|
||||
{
|
||||
union epoll_ref ref = { .type = EPOLL_TYPE_TAP_LISTEN };
|
||||
struct epoll_event ev = { 0 };
|
||||
|
||||
listen(c->fd_tap_listen, 0);
|
||||
|
||||
ref.fd = c->fd_tap_listen;
|
||||
ev.events = EPOLLIN | EPOLLET;
|
||||
ev.data.u64 = ref.u64;
|
||||
epoll_ctl(c->epollfd, EPOLL_CTL_ADD, c->fd_tap_listen, &ev);
|
||||
|
||||
info("You can now start qemu (>= 7.2, with commit 13c6be96618c):");
|
||||
info("\nYou can now start qemu (>= 7.2, with commit 13c6be96618c):");
|
||||
info(" kvm ... -device virtio-net-pci,netdev=s -netdev stream,id=s,server=off,addr.type=unix,addr.path=%s",
|
||||
addr.sun_path);
|
||||
c->sock_path);
|
||||
info("or qrap, for earlier qemu versions:");
|
||||
info(" ./qrap 5 kvm ... -net socket,fd=5 -net nic,model=virtio");
|
||||
}
|
||||
@@ -1310,8 +1318,13 @@ void tap_sock_init(struct ctx *c)
|
||||
}
|
||||
|
||||
if (c->mode == MODE_PASST) {
|
||||
if (c->fd_tap_listen == -1)
|
||||
tap_sock_unix_init(c);
|
||||
|
||||
/* In passt mode, we don't know the guest's MAC address until it
|
||||
* sends us packets. Use the broadcast address so that our
|
||||
* first packets will reach it.
|
||||
*/
|
||||
memset(&c->mac_guest, 0xff, sizeof(c->mac_guest));
|
||||
} else {
|
||||
tap_sock_tun_init(c);
|
||||
}
|
||||
|
1
tap.h
1
tap.h
@@ -68,6 +68,7 @@ void tap_handler_pasta(struct ctx *c, uint32_t events,
|
||||
const struct timespec *now);
|
||||
void tap_handler_passt(struct ctx *c, uint32_t events,
|
||||
const struct timespec *now);
|
||||
int tap_sock_unix_open(char *sock_path);
|
||||
void tap_sock_init(struct ctx *c);
|
||||
|
||||
#endif /* TAP_H */
|
||||
|
28
util.c
28
util.c
@@ -380,11 +380,11 @@ int open_in_ns(const struct ctx *c, const char *path, int flags)
|
||||
}
|
||||
|
||||
/**
|
||||
* pid_file() - Write PID to file, if requested to do so, and close it
|
||||
* pidfile_write() - Write PID to file, if requested to do so, and close it
|
||||
* @fd: Open PID file descriptor, closed on exit, -1 to skip writing it
|
||||
* @pid: PID value to write
|
||||
*/
|
||||
void write_pidfile(int fd, pid_t pid)
|
||||
void pidfile_write(int fd, pid_t pid)
|
||||
{
|
||||
char pid_buf[12];
|
||||
int n;
|
||||
@@ -402,6 +402,28 @@ void write_pidfile(int fd, pid_t pid)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* pidfile_open() - Open PID file if needed
|
||||
* @path: Path for PID file, empty string if no PID file is requested
|
||||
*
|
||||
* Return: descriptor for PID file, -1 if path is NULL, won't return on failure
|
||||
*/
|
||||
int pidfile_open(const char *path)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (!*path)
|
||||
return -1;
|
||||
|
||||
if ((fd = open(path, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC,
|
||||
S_IRUSR | S_IWUSR)) < 0) {
|
||||
perror("PID file open");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* __daemon() - daemon()-like function writing PID file before parent exits
|
||||
* @pidfile_fd: Open PID file descriptor
|
||||
@@ -419,7 +441,7 @@ int __daemon(int pidfile_fd, int devnull_fd)
|
||||
}
|
||||
|
||||
if (pid) {
|
||||
write_pidfile(pidfile_fd, pid);
|
||||
pidfile_write(pidfile_fd, pid);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
4
util.h
4
util.h
@@ -6,6 +6,7 @@
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
@@ -156,7 +157,8 @@ char *line_read(char *buf, size_t len, int fd);
|
||||
void ns_enter(const struct ctx *c);
|
||||
bool ns_is_init(void);
|
||||
int open_in_ns(const struct ctx *c, const char *path, int flags);
|
||||
void write_pidfile(int fd, pid_t pid);
|
||||
int pidfile_open(const char *path);
|
||||
void pidfile_write(int fd, pid_t pid);
|
||||
int __daemon(int pidfile_fd, int devnull_fd);
|
||||
int fls(unsigned long x);
|
||||
int write_file(const char *path, const char *buf);
|
||||
|
Reference in New Issue
Block a user