]> git.proxmox.com Git - mirror_lxc.git/blame_incremental - src/lxc/commands.c
seccomp: don't close the mainloop, simply remove the handler
[mirror_lxc.git] / src / lxc / commands.c
... / ...
CommitLineData
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#ifndef _GNU_SOURCE
4#define _GNU_SOURCE 1
5#endif
6#include <caps.h>
7#include <errno.h>
8#include <fcntl.h>
9#include <malloc.h>
10#include <poll.h>
11#include <signal.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <sys/param.h>
15#include <sys/socket.h>
16#include <sys/un.h>
17#include <unistd.h>
18
19#include "af_unix.h"
20#include "cgroup.h"
21#include "cgroups/cgroup2_devices.h"
22#include "commands.h"
23#include "commands_utils.h"
24#include "conf.h"
25#include "config.h"
26#include "confile.h"
27#include "log.h"
28#include "lxc.h"
29#include "lxclock.h"
30#include "lxcseccomp.h"
31#include "mainloop.h"
32#include "memory_utils.h"
33#include "monitor.h"
34#include "start.h"
35#include "terminal.h"
36#include "utils.h"
37
38/*
39 * This file provides the different functions for clients to query/command the
40 * server. The client is typically some lxc tool and the server is typically the
41 * container (ie. lxc-start).
42 *
43 * Each command is transactional, the clients send a request to the server and
44 * the server answers the request with a message giving the request's status
45 * (zero or a negative errno value). Both the request and response may contain
46 * additional data.
47 *
48 * Each command is wrapped in a ancillary message in order to pass a credential
49 * making possible to the server to check if the client is allowed to ask for
50 * this command or not.
51 *
52 * IMPORTANTLY: Note that semantics for current commands are fixed. If you wish
53 * to make any changes to how, say, LXC_CMD_GET_CONFIG_ITEM works by adding
54 * information to the end of cmd.data, then you must introduce a new
55 * LXC_CMD_GET_CONFIG_ITEM_V2 define with a new number. You may wish to also
56 * mark LXC_CMD_GET_CONFIG_ITEM deprecated in commands.h.
57 *
58 * This is necessary in order to avoid having a newly compiled lxc command
59 * communicating with a running (old) monitor from crashing the running
60 * container.
61 */
62
63lxc_log_define(commands, lxc);
64
65static const char *lxc_cmd_str(lxc_cmd_t cmd)
66{
67 static const char *const cmdname[LXC_CMD_MAX] = {
68 [LXC_CMD_CONSOLE] = "console",
69 [LXC_CMD_TERMINAL_WINCH] = "terminal_winch",
70 [LXC_CMD_STOP] = "stop",
71 [LXC_CMD_GET_STATE] = "get_state",
72 [LXC_CMD_GET_INIT_PID] = "get_init_pid",
73 [LXC_CMD_GET_CLONE_FLAGS] = "get_clone_flags",
74 [LXC_CMD_GET_CGROUP] = "get_cgroup",
75 [LXC_CMD_GET_CONFIG_ITEM] = "get_config_item",
76 [LXC_CMD_GET_NAME] = "get_name",
77 [LXC_CMD_GET_LXCPATH] = "get_lxcpath",
78 [LXC_CMD_ADD_STATE_CLIENT] = "add_state_client",
79 [LXC_CMD_CONSOLE_LOG] = "console_log",
80 [LXC_CMD_SERVE_STATE_CLIENTS] = "serve_state_clients",
81 [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER] = "seccomp_notify_add_listener",
82 [LXC_CMD_ADD_BPF_DEVICE_CGROUP] = "add_bpf_device_cgroup",
83 [LXC_CMD_FREEZE] = "freeze",
84 [LXC_CMD_UNFREEZE] = "unfreeze",
85 [LXC_CMD_GET_CGROUP2_FD] = "get_cgroup2_fd",
86 [LXC_CMD_GET_INIT_PIDFD] = "get_init_pidfd",
87 [LXC_CMD_GET_LIMITING_CGROUP] = "get_limiting_cgroup",
88 [LXC_CMD_GET_LIMITING_CGROUP2_FD] = "get_limiting_cgroup2_fd",
89 [LXC_CMD_GET_DEVPTS_FD] = "get_devpts_fd",
90 };
91
92 if (cmd >= LXC_CMD_MAX)
93 return "Invalid request";
94
95 return cmdname[cmd];
96}
97
98/*
99 * lxc_cmd_rsp_recv: Receive a response to a command
100 *
101 * @sock : the socket connected to the container
102 * @cmd : command to put response in
103 *
104 * Returns the size of the response message or < 0 on failure
105 *
106 * Note that if the command response datalen > 0, then data is
107 * a malloc()ed buffer and should be free()ed by the caller. If
108 * the response data is <= a void * worth of data, it will be
109 * stored directly in data and datalen will be 0.
110 *
111 * As a special case, the response for LXC_CMD_CONSOLE is created
112 * here as it contains an fd for the ptx pty passed through the
113 * unix socket.
114 */
115static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
116{
117 __do_close int fd_rsp = -EBADF;
118 int ret;
119 struct lxc_cmd_rsp *rsp = &cmd->rsp;
120
121 ret = lxc_abstract_unix_recv_fds(sock, &fd_rsp, 1, rsp, sizeof(*rsp));
122 if (ret < 0)
123 return log_warn_errno(-1,
124 errno, "Failed to receive response for command \"%s\"",
125 lxc_cmd_str(cmd->req.cmd));
126 TRACE("Command \"%s\" received response", lxc_cmd_str(cmd->req.cmd));
127
128 if (cmd->req.cmd == LXC_CMD_CONSOLE) {
129 struct lxc_cmd_console_rsp_data *rspdata;
130
131 /* recv() returns 0 bytes when a tty cannot be allocated,
132 * rsp->ret is < 0 when the peer permission check failed
133 */
134 if (ret == 0 || rsp->ret < 0)
135 return 0;
136
137 rspdata = malloc(sizeof(*rspdata));
138 if (!rspdata)
139 return log_warn_errno(-1,
140 ENOMEM, "Failed to receive response for command \"%s\"",
141 lxc_cmd_str(cmd->req.cmd));
142
143 rspdata->ptxfd = move_fd(fd_rsp);
144 rspdata->ttynum = PTR_TO_INT(rsp->data);
145 rsp->data = rspdata;
146 }
147
148 if (cmd->req.cmd == LXC_CMD_GET_CGROUP2_FD ||
149 cmd->req.cmd == LXC_CMD_GET_LIMITING_CGROUP2_FD)
150 {
151 int cgroup2_fd = move_fd(fd_rsp);
152 rsp->data = INT_TO_PTR(cgroup2_fd);
153 }
154
155 if (cmd->req.cmd == LXC_CMD_GET_INIT_PIDFD) {
156 int init_pidfd = move_fd(fd_rsp);
157 rsp->data = INT_TO_PTR(init_pidfd);
158 }
159
160 if (cmd->req.cmd == LXC_CMD_GET_DEVPTS_FD) {
161 int devpts_fd = move_fd(fd_rsp);
162 rsp->data = INT_TO_PTR(devpts_fd);
163 }
164
165 if (rsp->datalen == 0)
166 return log_debug(ret,
167 "Response data length for command \"%s\" is 0",
168 lxc_cmd_str(cmd->req.cmd));
169
170 if ((rsp->datalen > LXC_CMD_DATA_MAX) &&
171 (cmd->req.cmd != LXC_CMD_CONSOLE_LOG))
172 return log_error(-1, "Response data for command \"%s\" is too long: %d bytes > %d",
173 lxc_cmd_str(cmd->req.cmd), rsp->datalen,
174 LXC_CMD_DATA_MAX);
175
176 if (cmd->req.cmd == LXC_CMD_CONSOLE_LOG) {
177 rsp->data = malloc(rsp->datalen + 1);
178 ((char *)rsp->data)[rsp->datalen] = '\0';
179 } else {
180 rsp->data = malloc(rsp->datalen);
181 }
182 if (!rsp->data)
183 return log_error_errno(-1,
184 ENOMEM, "Failed to allocate response buffer for command \"%s\"",
185 lxc_cmd_str(cmd->req.cmd));
186
187 ret = lxc_recv_nointr(sock, rsp->data, rsp->datalen, 0);
188 if (ret != rsp->datalen)
189 return log_error_errno(-1,
190 errno, "Failed to receive response data for command \"%s\"",
191 lxc_cmd_str(cmd->req.cmd));
192
193 return ret;
194}
195
196/*
197 * lxc_cmd_rsp_send: Send a command response
198 *
199 * @fd : file descriptor of socket to send response on
200 * @rsp : response to send
201 *
202 * Returns 0 on success, < 0 on failure
203 */
204static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
205{
206 ssize_t ret;
207
208 errno = EMSGSIZE;
209 ret = lxc_send_nointr(fd, rsp, sizeof(*rsp), MSG_NOSIGNAL);
210 if (ret < 0 || (size_t)ret != sizeof(*rsp))
211 return log_error_errno(-1, errno, "Failed to send command response %zd", ret);
212
213 if (!rsp->data || rsp->datalen <= 0)
214 return 0;
215
216 errno = EMSGSIZE;
217 ret = lxc_send_nointr(fd, rsp->data, rsp->datalen, MSG_NOSIGNAL);
218 if (ret < 0 || ret != (ssize_t)rsp->datalen)
219 return log_warn_errno(-1, errno, "Failed to send command response data %zd", ret);
220
221 return 0;
222}
223
224static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
225 const char *lxcpath, const char *hashed_sock_name)
226{
227 __do_close int client_fd = -EBADF;
228 ssize_t ret = -1;
229
230 client_fd = lxc_cmd_connect(name, lxcpath, hashed_sock_name, "command");
231 if (client_fd < 0)
232 return -1;
233
234 ret = lxc_abstract_unix_send_credential(client_fd, &cmd->req,
235 sizeof(cmd->req));
236 if (ret < 0 || (size_t)ret != sizeof(cmd->req))
237 return -1;
238
239 if (cmd->req.cmd == LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER) {
240 int notify_fd = PTR_TO_INT(cmd->req.data);
241 ret = lxc_abstract_unix_send_fds(client_fd, &notify_fd, 1, NULL, 0);
242 if (ret <= 0)
243 return -1;
244 } else {
245 if (cmd->req.datalen <= 0)
246 return move_fd(client_fd);
247
248 errno = EMSGSIZE;
249 ret = lxc_send_nointr(client_fd, (void *)cmd->req.data,
250 cmd->req.datalen, MSG_NOSIGNAL);
251 if (ret < 0 || ret != (ssize_t)cmd->req.datalen)
252 return -1;
253 }
254
255 return move_fd(client_fd);
256}
257
258/*
259 * lxc_cmd: Connect to the specified running container, send it a command
260 * request and collect the response
261 *
262 * @name : name of container to connect to
263 * @cmd : command with initialized request to send
264 * @stopped : output indicator if the container was not running
265 * @lxcpath : the lxcpath in which the container is running
266 *
267 * Returns the size of the response message on success, < 0 on failure
268 *
269 * Note that there is a special case for LXC_CMD_CONSOLE. For this command
270 * the fd cannot be closed because it is used as a placeholder to indicate
271 * that a particular tty slot is in use. The fd is also used as a signal to
272 * the container that when the caller dies or closes the fd, the container
273 * will notice the fd on its side of the socket in its mainloop select and
274 * then free the slot with lxc_cmd_fd_cleanup(). The socket fd will be
275 * returned in the cmd response structure.
276 */
277static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
278 const char *lxcpath, const char *hashed_sock_name)
279{
280 __do_close int client_fd = -EBADF;
281 int ret = -1;
282 bool stay_connected = false;
283
284 if (cmd->req.cmd == LXC_CMD_CONSOLE ||
285 cmd->req.cmd == LXC_CMD_ADD_STATE_CLIENT)
286 stay_connected = true;
287
288 *stopped = 0;
289
290 client_fd = lxc_cmd_send(name, cmd, lxcpath, hashed_sock_name);
291 if (client_fd < 0) {
292 if (errno == ECONNREFUSED || errno == EPIPE)
293 *stopped = 1;
294
295 return log_trace_errno(-1, errno, "Command \"%s\" failed to connect command socket",
296 lxc_cmd_str(cmd->req.cmd));
297 }
298
299 ret = lxc_cmd_rsp_recv(client_fd, cmd);
300 if (ret < 0 && errno == ECONNRESET)
301 *stopped = 1;
302
303 TRACE("Opened new command socket connection fd %d for command \"%s\"",
304 client_fd, lxc_cmd_str(cmd->req.cmd));
305
306 if (stay_connected && ret > 0)
307 cmd->rsp.ret = move_fd(client_fd);
308
309 return ret;
310}
311
312int lxc_try_cmd(const char *name, const char *lxcpath)
313{
314 int stopped, ret;
315 struct lxc_cmd_rr cmd = {
316 .req = { .cmd = LXC_CMD_GET_INIT_PID },
317 };
318
319 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
320 if (stopped)
321 return 0;
322 if (ret > 0 && cmd.rsp.ret < 0) {
323 errno = cmd.rsp.ret;
324 return -1;
325 }
326 if (ret > 0)
327 return 0;
328
329 /* At this point we weren't denied access, and the container *was*
330 * started. There was some inexplicable error in the protocol. I'm not
331 * clear on whether we should return -1 here, but we didn't receive a
332 * -EACCES, so technically it's not that we're not allowed to control
333 * the container - it's just not behaving.
334 */
335 return 0;
336}
337
338/*
339 * Validate that the input is a proper string parameter. If not,
340 * send an EINVAL response and return -1.
341 *
342 * Precondition: there is non-zero-length data available.
343 */
344static int validate_string_request(int fd, const struct lxc_cmd_req *req)
345{
346 int ret;
347 size_t maxlen = req->datalen - 1;
348 const char *data = req->data;
349
350 if (data[maxlen] == 0 && strnlen(data, maxlen) == maxlen)
351 return 0;
352
353 struct lxc_cmd_rsp rsp = {
354 .ret = -EINVAL,
355 .datalen = 0,
356 .data = NULL,
357 };
358
359 ret = lxc_cmd_rsp_send(fd, &rsp);
360 if (ret < 0)
361 return LXC_CMD_REAP_CLIENT_FD;
362
363 return -1;
364}
365
366/* Implementations of the commands and their callbacks */
367
368/*
369 * lxc_cmd_get_init_pid: Get pid of the container's init process
370 *
371 * @name : name of container to connect to
372 * @lxcpath : the lxcpath in which the container is running
373 *
374 * Returns the pid on success, < 0 on failure
375 */
376pid_t lxc_cmd_get_init_pid(const char *name, const char *lxcpath)
377{
378 int ret, stopped;
379 pid_t pid = -1;
380 struct lxc_cmd_rr cmd = {
381 .req = {
382 .cmd = LXC_CMD_GET_INIT_PID
383 },
384 .rsp = {
385 .data = PID_TO_PTR(pid)
386 }
387 };
388
389 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
390 if (ret < 0)
391 return -1;
392
393 pid = PTR_TO_PID(cmd.rsp.data);
394 if (pid < 0)
395 return -1;
396
397 /* We need to assume that pid_t can actually hold any pid given to us
398 * by the kernel. If it can't it's a libc bug.
399 */
400 return (pid_t)pid;
401}
402
403static int lxc_cmd_get_init_pid_callback(int fd, struct lxc_cmd_req *req,
404 struct lxc_handler *handler,
405 struct lxc_epoll_descr *descr)
406{
407 int ret;
408 struct lxc_cmd_rsp rsp = {
409 .data = PID_TO_PTR(handler->pid)
410 };
411
412 ret = lxc_cmd_rsp_send(fd, &rsp);
413 if (ret < 0)
414 return LXC_CMD_REAP_CLIENT_FD;
415
416 return 0;
417}
418
419int lxc_cmd_get_init_pidfd(const char *name, const char *lxcpath)
420{
421 int ret, stopped;
422 struct lxc_cmd_rr cmd = {
423 .req = {
424 .cmd = LXC_CMD_GET_INIT_PIDFD,
425 },
426 };
427
428 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
429 if (ret < 0)
430 return log_debug_errno(-1, errno, "Failed to process init pidfd command");
431
432 if (cmd.rsp.ret < 0)
433 return log_debug_errno(-EBADF, errno, "Failed to receive init pidfd");
434
435 return PTR_TO_INT(cmd.rsp.data);
436}
437
438static int lxc_cmd_get_init_pidfd_callback(int fd, struct lxc_cmd_req *req,
439 struct lxc_handler *handler,
440 struct lxc_epoll_descr *descr)
441{
442 struct lxc_cmd_rsp rsp = {
443 .ret = 0,
444 };
445 int ret;
446
447 if (handler->pidfd < 0)
448 rsp.ret = -EBADF;
449 ret = lxc_abstract_unix_send_fds(fd, &handler->pidfd, 1, &rsp, sizeof(rsp));
450 if (ret < 0)
451 return log_error(LXC_CMD_REAP_CLIENT_FD, "Failed to send init pidfd");
452
453 return 0;
454}
455
456int lxc_cmd_get_devpts_fd(const char *name, const char *lxcpath)
457{
458 int ret, stopped;
459 struct lxc_cmd_rr cmd = {
460 .req = {
461 .cmd = LXC_CMD_GET_DEVPTS_FD,
462 },
463 };
464
465 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
466 if (ret < 0)
467 return log_debug_errno(-1, errno, "Failed to process devpts fd command");
468
469 if (cmd.rsp.ret < 0)
470 return log_debug_errno(-EBADF, errno, "Failed to receive devpts fd");
471
472 return PTR_TO_INT(cmd.rsp.data);
473}
474
475static int lxc_cmd_get_devpts_fd_callback(int fd, struct lxc_cmd_req *req,
476 struct lxc_handler *handler,
477 struct lxc_epoll_descr *descr)
478{
479 struct lxc_cmd_rsp rsp = {
480 .ret = 0,
481 };
482 int ret;
483
484 if (!handler->conf || handler->conf->devpts_fd < 0)
485 rsp.ret = -EBADF;
486 ret = lxc_abstract_unix_send_fds(fd, &handler->conf->devpts_fd, 1, &rsp, sizeof(rsp));
487 if (ret < 0)
488 return log_error(LXC_CMD_REAP_CLIENT_FD, "Failed to send devpts fd");
489
490 return 0;
491}
492
493/*
494 * lxc_cmd_get_clone_flags: Get clone flags container was spawned with
495 *
496 * @name : name of container to connect to
497 * @lxcpath : the lxcpath in which the container is running
498 *
499 * Returns the clone flags on success, < 0 on failure
500 */
501int lxc_cmd_get_clone_flags(const char *name, const char *lxcpath)
502{
503 int ret, stopped;
504 struct lxc_cmd_rr cmd = {
505 .req = {
506 .cmd = LXC_CMD_GET_CLONE_FLAGS,
507 },
508 };
509
510 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
511 if (ret < 0)
512 return ret;
513
514 return PTR_TO_INT(cmd.rsp.data);
515}
516
517static int lxc_cmd_get_clone_flags_callback(int fd, struct lxc_cmd_req *req,
518 struct lxc_handler *handler,
519 struct lxc_epoll_descr *descr)
520{
521 int ret;
522 struct lxc_cmd_rsp rsp = {
523 .data = INT_TO_PTR(handler->ns_clone_flags),
524 };
525
526 ret = lxc_cmd_rsp_send(fd, &rsp);
527 if (ret < 0)
528 return LXC_CMD_REAP_CLIENT_FD;
529
530 return 0;
531}
532
533static char *lxc_cmd_get_cgroup_path_do(const char *name, const char *lxcpath,
534 const char *subsystem,
535 lxc_cmd_t command)
536{
537 int ret, stopped;
538 struct lxc_cmd_rr cmd = {
539 .req = {
540 .cmd = command,
541 .data = subsystem,
542 .datalen = 0,
543 },
544 };
545
546 cmd.req.data = subsystem;
547 cmd.req.datalen = 0;
548 if (subsystem)
549 cmd.req.datalen = strlen(subsystem) + 1;
550
551 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
552 if (ret < 0)
553 return NULL;
554
555 if (ret == 0) {
556 if (command == LXC_CMD_GET_LIMITING_CGROUP) {
557 /*
558 * This may indicate that the container was started
559 * under an ealier version before
560 * `cgroup_advanced_isolation` as implemented, there
561 * it sees an unknown command and just closes the
562 * socket, sending us an EOF.
563 */
564 return lxc_cmd_get_cgroup_path_do(name, lxcpath,
565 subsystem,
566 LXC_CMD_GET_CGROUP);
567 }
568 return NULL;
569 }
570
571 if (cmd.rsp.ret < 0 || cmd.rsp.datalen < 0)
572 return NULL;
573
574 return cmd.rsp.data;
575}
576
577/*
578 * lxc_cmd_get_cgroup_path: Calculate a container's cgroup path for a
579 * particular subsystem. This is the cgroup path relative to the root
580 * of the cgroup filesystem.
581 *
582 * @name : name of container to connect to
583 * @lxcpath : the lxcpath in which the container is running
584 * @subsystem : the subsystem being asked about
585 *
586 * Returns the path on success, NULL on failure. The caller must free() the
587 * returned path.
588 */
589char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath,
590 const char *subsystem)
591{
592 return lxc_cmd_get_cgroup_path_do(name, lxcpath, subsystem,
593 LXC_CMD_GET_CGROUP);
594}
595
596/*
597 * lxc_cmd_get_limiting_cgroup_path: Calculate a container's limiting cgroup
598 * path for a particular subsystem. This is the cgroup path relative to the
599 * root of the cgroup filesystem. This may be the same as the path returned by
600 * lxc_cmd_get_cgroup_path if the container doesn't have a limiting path prefix
601 * set.
602 *
603 * @name : name of container to connect to
604 * @lxcpath : the lxcpath in which the container is running
605 * @subsystem : the subsystem being asked about
606 *
607 * Returns the path on success, NULL on failure. The caller must free() the
608 * returned path.
609 */
610char *lxc_cmd_get_limiting_cgroup_path(const char *name, const char *lxcpath,
611 const char *subsystem)
612{
613 return lxc_cmd_get_cgroup_path_do(name, lxcpath, subsystem,
614 LXC_CMD_GET_LIMITING_CGROUP);
615}
616
617static int lxc_cmd_get_cgroup_callback_do(int fd, struct lxc_cmd_req *req,
618 struct lxc_handler *handler,
619 struct lxc_epoll_descr *descr,
620 bool limiting_cgroup)
621{
622 int ret;
623 const char *path;
624 const void *reqdata;
625 struct lxc_cmd_rsp rsp;
626 struct cgroup_ops *cgroup_ops = handler->cgroup_ops;
627 const char *(*get_fn)(struct cgroup_ops *ops, const char *controller);
628
629 if (req->datalen > 0) {
630 ret = validate_string_request(fd, req);
631 if (ret != 0)
632 return ret;
633 reqdata = req->data;
634 } else {
635 reqdata = NULL;
636 }
637
638 get_fn = (limiting_cgroup ? cgroup_ops->get_limiting_cgroup
639 : cgroup_ops->get_cgroup);
640
641 path = get_fn(cgroup_ops, reqdata);
642
643 if (!path)
644 return -1;
645
646 rsp.ret = 0;
647 rsp.datalen = strlen(path) + 1;
648 rsp.data = (char *)path;
649
650 ret = lxc_cmd_rsp_send(fd, &rsp);
651 if (ret < 0)
652 return LXC_CMD_REAP_CLIENT_FD;
653
654 return 0;
655}
656
657static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req,
658 struct lxc_handler *handler,
659 struct lxc_epoll_descr *descr)
660{
661 return lxc_cmd_get_cgroup_callback_do(fd, req, handler, descr, false);
662}
663
664static int lxc_cmd_get_limiting_cgroup_callback(int fd, struct lxc_cmd_req *req,
665 struct lxc_handler *handler,
666 struct lxc_epoll_descr *descr)
667{
668 return lxc_cmd_get_cgroup_callback_do(fd, req, handler, descr, true);
669}
670
671/*
672 * lxc_cmd_get_config_item: Get config item the running container
673 *
674 * @name : name of container to connect to
675 * @item : the configuration item to retrieve (ex: lxc.net.0.veth.pair)
676 * @lxcpath : the lxcpath in which the container is running
677 *
678 * Returns the item on success, NULL on failure. The caller must free() the
679 * returned item.
680 */
681char *lxc_cmd_get_config_item(const char *name, const char *item,
682 const char *lxcpath)
683{
684 int ret, stopped;
685 struct lxc_cmd_rr cmd = {
686 .req = { .cmd = LXC_CMD_GET_CONFIG_ITEM,
687 .data = item,
688 .datalen = strlen(item) + 1,
689 },
690 };
691
692 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
693 if (ret < 0)
694 return NULL;
695
696 if (cmd.rsp.ret == 0)
697 return cmd.rsp.data;
698
699 return NULL;
700}
701
702static int lxc_cmd_get_config_item_callback(int fd, struct lxc_cmd_req *req,
703 struct lxc_handler *handler,
704 struct lxc_epoll_descr *descr)
705{
706 __do_free char *cidata = NULL;
707 int cilen;
708 struct lxc_config_t *item;
709 struct lxc_cmd_rsp rsp;
710
711 memset(&rsp, 0, sizeof(rsp));
712 item = lxc_get_config(req->data);
713 if (!item)
714 goto err1;
715
716 cilen = item->get(req->data, NULL, 0, handler->conf, NULL);
717 if (cilen <= 0)
718 goto err1;
719
720 cidata = must_realloc(NULL, cilen + 1);
721 if (item->get(req->data, cidata, cilen + 1, handler->conf, NULL) != cilen)
722 goto err1;
723
724 cidata[cilen] = '\0';
725 rsp.data = cidata;
726 rsp.datalen = cilen + 1;
727 rsp.ret = 0;
728 goto out;
729
730err1:
731 rsp.ret = -1;
732out:
733 cilen = lxc_cmd_rsp_send(fd, &rsp);
734 if (cilen < 0)
735 return LXC_CMD_REAP_CLIENT_FD;
736
737 return 0;
738}
739
740/*
741 * lxc_cmd_get_state: Get current state of the container
742 *
743 * @name : name of container to connect to
744 * @lxcpath : the lxcpath in which the container is running
745 *
746 * Returns the state on success, < 0 on failure
747 */
748int lxc_cmd_get_state(const char *name, const char *lxcpath)
749{
750 int ret, stopped;
751 struct lxc_cmd_rr cmd = {
752 .req = {
753 .cmd = LXC_CMD_GET_STATE,
754 },
755 };
756
757 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
758 if (ret < 0 && stopped)
759 return STOPPED;
760
761 if (ret < 0)
762 return -1;
763
764 if (!ret)
765 return log_warn(-1, "Container \"%s\" has stopped before sending its state", name);
766
767 return log_debug(PTR_TO_INT(cmd.rsp.data),
768 "Container \"%s\" is in \"%s\" state", name,
769 lxc_state2str(PTR_TO_INT(cmd.rsp.data)));
770}
771
772static int lxc_cmd_get_state_callback(int fd, struct lxc_cmd_req *req,
773 struct lxc_handler *handler,
774 struct lxc_epoll_descr *descr)
775{
776 int ret;
777 struct lxc_cmd_rsp rsp = {
778 .data = INT_TO_PTR(handler->state),
779 };
780
781 ret = lxc_cmd_rsp_send(fd, &rsp);
782 if (ret < 0)
783 return LXC_CMD_REAP_CLIENT_FD;
784
785 return 0;
786}
787
788/*
789 * lxc_cmd_stop: Stop the container previously started with lxc_start. All
790 * the processes running inside this container will be killed.
791 *
792 * @name : name of container to connect to
793 * @lxcpath : the lxcpath in which the container is running
794 *
795 * Returns 0 on success, < 0 on failure
796 */
797int lxc_cmd_stop(const char *name, const char *lxcpath)
798{
799 int ret, stopped;
800 struct lxc_cmd_rr cmd = {
801 .req = {
802 .cmd = LXC_CMD_STOP,
803 },
804 };
805
806 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
807 if (ret < 0) {
808 if (stopped)
809 return log_info(0, "Container \"%s\" is already stopped", name);
810
811 return -1;
812 }
813
814 /* We do not expect any answer, because we wait for the connection to be
815 * closed.
816 */
817 if (ret > 0)
818 return log_error_errno(-1, -cmd.rsp.ret, "Failed to stop container \"%s\"", name);
819
820 return log_info(0, "Container \"%s\" has stopped", name);
821}
822
823static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req,
824 struct lxc_handler *handler,
825 struct lxc_epoll_descr *descr)
826{
827 struct lxc_cmd_rsp rsp;
828 int stopsignal = SIGKILL;
829 struct cgroup_ops *cgroup_ops = handler->cgroup_ops;
830 int ret;
831
832 if (handler->conf->stopsignal)
833 stopsignal = handler->conf->stopsignal;
834 memset(&rsp, 0, sizeof(rsp));
835
836 if (handler->pidfd >= 0)
837 rsp.ret = lxc_raw_pidfd_send_signal(handler->pidfd, stopsignal, NULL, 0);
838 else
839 rsp.ret = kill(handler->pid, stopsignal);
840 if (!rsp.ret) {
841 if (handler->pidfd >= 0)
842 TRACE("Sent signal %d to pidfd %d", stopsignal, handler->pidfd);
843 else
844 TRACE("Sent signal %d to pidfd %d", stopsignal, handler->pid);
845
846 rsp.ret = cgroup_ops->unfreeze(cgroup_ops, -1);
847 if (!rsp.ret)
848 return 0;
849
850 ERROR("Failed to unfreeze container \"%s\"", handler->name);
851 rsp.ret = -errno;
852 } else {
853 rsp.ret = -errno;
854 }
855
856 ret = lxc_cmd_rsp_send(fd, &rsp);
857 if (ret < 0)
858 return LXC_CMD_REAP_CLIENT_FD;
859
860 return 0;
861}
862
863/*
864 * lxc_cmd_terminal_winch: noop
865 *
866 * @name : name of container to connect to
867 * @lxcpath : the lxcpath in which the container is running
868 *
869 * Returns 0 on success, < 0 on failure
870 */
871int lxc_cmd_terminal_winch(const char *name, const char *lxcpath)
872{
873 return 0;
874}
875
876static int lxc_cmd_terminal_winch_callback(int fd, struct lxc_cmd_req *req,
877 struct lxc_handler *handler,
878 struct lxc_epoll_descr *descr)
879{
880 /* should never be called */
881 return log_error_errno(-1, ENOSYS, "Called lxc_cmd_terminal_winch_callback()");
882}
883
884/*
885 * lxc_cmd_console: Open an fd to a tty in the container
886 *
887 * @name : name of container to connect to
888 * @ttynum : in: the tty to open or -1 for next available
889 * : out: the tty allocated
890 * @fd : out: file descriptor for ptx side of pty
891 * @lxcpath : the lxcpath in which the container is running
892 *
893 * Returns fd holding tty allocated on success, < 0 on failure
894 */
895int lxc_cmd_console(const char *name, int *ttynum, int *fd, const char *lxcpath)
896{
897 __do_free struct lxc_cmd_console_rsp_data *rspdata = NULL;
898 int ret, stopped;
899 struct lxc_cmd_rr cmd = {
900 .req = {
901 .cmd = LXC_CMD_CONSOLE,
902 .data = INT_TO_PTR(*ttynum),
903 },
904 };
905
906 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
907 if (ret < 0)
908 return ret;
909
910 rspdata = cmd.rsp.data;
911 if (cmd.rsp.ret < 0)
912 return log_error_errno(-1, -cmd.rsp.ret, "Denied access to tty");
913
914 if (ret == 0)
915 return log_error(-1, "tty number %d invalid, busy or all ttys busy", *ttynum);
916
917 if (rspdata->ptxfd < 0)
918 return log_error(-1, "Unable to allocate fd for tty %d", rspdata->ttynum);
919
920 ret = cmd.rsp.ret; /* socket fd */
921 *fd = rspdata->ptxfd;
922 *ttynum = rspdata->ttynum;
923
924 return log_info(ret, "Alloced fd %d for tty %d via socket %d", *fd, rspdata->ttynum, ret);
925}
926
927static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
928 struct lxc_handler *handler,
929 struct lxc_epoll_descr *descr)
930{
931 int ptxfd, ret;
932 struct lxc_cmd_rsp rsp;
933 int ttynum = PTR_TO_INT(req->data);
934
935 ptxfd = lxc_terminal_allocate(handler->conf, fd, &ttynum);
936 if (ptxfd < 0)
937 return LXC_CMD_REAP_CLIENT_FD;
938
939 memset(&rsp, 0, sizeof(rsp));
940 rsp.data = INT_TO_PTR(ttynum);
941 ret = lxc_abstract_unix_send_fds(fd, &ptxfd, 1, &rsp, sizeof(rsp));
942 if (ret < 0) {
943 lxc_terminal_free(handler->conf, fd);
944 return log_error_errno(LXC_CMD_REAP_CLIENT_FD, errno,
945 "Failed to send tty to client");
946 }
947
948 return 0;
949}
950
951/*
952 * lxc_cmd_get_name: Returns the name of the container
953 *
954 * @hashed_sock_name: hashed socket name
955 *
956 * Returns the name on success, NULL on failure.
957 */
958char *lxc_cmd_get_name(const char *hashed_sock_name)
959{
960 int ret, stopped;
961 struct lxc_cmd_rr cmd = {
962 .req = {
963 .cmd = LXC_CMD_GET_NAME,
964 },
965 };
966
967 ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
968 if (ret < 0)
969 return NULL;
970
971 if (cmd.rsp.ret == 0)
972 return cmd.rsp.data;
973
974 return NULL;
975}
976
977static int lxc_cmd_get_name_callback(int fd, struct lxc_cmd_req *req,
978 struct lxc_handler *handler,
979 struct lxc_epoll_descr *descr)
980{
981 int ret;
982 struct lxc_cmd_rsp rsp;
983
984 memset(&rsp, 0, sizeof(rsp));
985
986 rsp.data = (char *)handler->name;
987 rsp.datalen = strlen(handler->name) + 1;
988 rsp.ret = 0;
989
990 ret = lxc_cmd_rsp_send(fd, &rsp);
991 if (ret < 0)
992 return LXC_CMD_REAP_CLIENT_FD;
993
994 return 0;
995}
996
997/*
998 * lxc_cmd_get_lxcpath: Returns the lxcpath of the container
999 *
1000 * @hashed_sock_name: hashed socket name
1001 *
1002 * Returns the lxcpath on success, NULL on failure.
1003 */
1004char *lxc_cmd_get_lxcpath(const char *hashed_sock_name)
1005{
1006 int ret, stopped;
1007 struct lxc_cmd_rr cmd = {
1008 .req = {
1009 .cmd = LXC_CMD_GET_LXCPATH,
1010 },
1011 };
1012
1013 ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
1014 if (ret < 0)
1015 return NULL;
1016
1017 if (cmd.rsp.ret == 0)
1018 return cmd.rsp.data;
1019
1020 return NULL;
1021}
1022
1023static int lxc_cmd_get_lxcpath_callback(int fd, struct lxc_cmd_req *req,
1024 struct lxc_handler *handler,
1025 struct lxc_epoll_descr *descr)
1026{
1027 int ret;
1028 struct lxc_cmd_rsp rsp = {
1029 .ret = 0,
1030 .data = (char *)handler->lxcpath,
1031 .datalen = strlen(handler->lxcpath) + 1,
1032 };
1033
1034 ret = lxc_cmd_rsp_send(fd, &rsp);
1035 if (ret < 0)
1036 return LXC_CMD_REAP_CLIENT_FD;
1037
1038 return 0;
1039}
1040
1041int lxc_cmd_add_state_client(const char *name, const char *lxcpath,
1042 lxc_state_t states[MAX_STATE],
1043 int *state_client_fd)
1044{
1045 __do_close int clientfd = -EBADF;
1046 int state, stopped;
1047 ssize_t ret;
1048 struct lxc_cmd_rr cmd = {
1049 .req = {
1050 .cmd = LXC_CMD_ADD_STATE_CLIENT,
1051 .data = states,
1052 .datalen = (sizeof(lxc_state_t) * MAX_STATE)
1053 },
1054 };
1055
1056 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1057 if (states[STOPPED] != 0 && stopped != 0)
1058 return STOPPED;
1059
1060 if (ret < 0) {
1061 if (errno != ECONNREFUSED)
1062 SYSERROR("Failed to execute command");
1063
1064 return -1;
1065 }
1066
1067 /* We should now be guaranteed to get an answer from the state sending
1068 * function.
1069 */
1070 clientfd = cmd.rsp.ret;
1071 if (clientfd < 0)
1072 return log_error_errno(-1, -clientfd, "Failed to receive socket fd");
1073
1074 state = PTR_TO_INT(cmd.rsp.data);
1075 if (state < MAX_STATE)
1076 return log_trace(state, "Container is already in requested state %s", lxc_state2str(state));
1077
1078 *state_client_fd = move_fd(clientfd);
1079 TRACE("State connection fd %d ready to listen for container state changes", *state_client_fd);
1080 return MAX_STATE;
1081}
1082
1083static int lxc_cmd_add_state_client_callback(__owns int fd, struct lxc_cmd_req *req,
1084 struct lxc_handler *handler,
1085 struct lxc_epoll_descr *descr)
1086{
1087 int ret;
1088 struct lxc_cmd_rsp rsp = {0};
1089
1090 if (req->datalen < 0)
1091 return LXC_CMD_REAP_CLIENT_FD;
1092
1093 if (req->datalen != (sizeof(lxc_state_t) * MAX_STATE))
1094 return LXC_CMD_REAP_CLIENT_FD;
1095
1096 if (!req->data)
1097 return LXC_CMD_REAP_CLIENT_FD;
1098
1099 rsp.ret = lxc_add_state_client(fd, handler, (lxc_state_t *)req->data);
1100 if (rsp.ret < 0)
1101 return LXC_CMD_REAP_CLIENT_FD;
1102
1103 rsp.data = INT_TO_PTR(rsp.ret);
1104
1105 ret = lxc_cmd_rsp_send(fd, &rsp);
1106 if (ret < 0)
1107 return LXC_CMD_REAP_CLIENT_FD;
1108
1109 return 0;
1110}
1111
1112int lxc_cmd_add_bpf_device_cgroup(const char *name, const char *lxcpath,
1113 struct device_item *device)
1114{
1115#ifdef HAVE_STRUCT_BPF_CGROUP_DEV_CTX
1116 int stopped = 0;
1117 struct lxc_cmd_rr cmd = {
1118 .req = {
1119 .cmd = LXC_CMD_ADD_BPF_DEVICE_CGROUP,
1120 .data = device,
1121 .datalen = sizeof(struct device_item),
1122 },
1123 };
1124 int ret;
1125
1126 if (strlen(device->access) > STRLITERALLEN("rwm"))
1127 return log_error_errno(-1, EINVAL, "Invalid access mode specified %s",
1128 device->access);
1129
1130 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1131 if (ret < 0 || cmd.rsp.ret < 0)
1132 return log_error_errno(-1, errno, "Failed to add new bpf device cgroup rule");
1133
1134 return 0;
1135#else
1136 return ret_set_errno(-1, ENOSYS);
1137#endif
1138}
1139
1140static int lxc_cmd_add_bpf_device_cgroup_callback(int fd, struct lxc_cmd_req *req,
1141 struct lxc_handler *handler,
1142 struct lxc_epoll_descr *descr)
1143{
1144#ifdef HAVE_STRUCT_BPF_CGROUP_DEV_CTX
1145 __do_bpf_program_free struct bpf_program *devices = NULL;
1146 struct lxc_cmd_rsp rsp = {0};
1147 struct lxc_conf *conf = handler->conf;
1148 struct hierarchy *unified = handler->cgroup_ops->unified;
1149 int ret;
1150 struct lxc_list *it;
1151 struct device_item *device;
1152 struct bpf_program *devices_old;
1153
1154 if (req->datalen <= 0)
1155 return LXC_CMD_REAP_CLIENT_FD;
1156
1157 if (req->datalen != sizeof(struct device_item))
1158 return LXC_CMD_REAP_CLIENT_FD;
1159
1160 if (!req->data)
1161 return LXC_CMD_REAP_CLIENT_FD;
1162 device = (struct device_item *)req->data;
1163
1164 rsp.ret = -1;
1165 if (!unified)
1166 goto respond;
1167
1168 ret = bpf_list_add_device(conf, device);
1169 if (ret < 0)
1170 goto respond;
1171
1172 devices = bpf_program_new(BPF_PROG_TYPE_CGROUP_DEVICE);
1173 if (!devices)
1174 goto respond;
1175
1176 ret = bpf_program_init(devices);
1177 if (ret)
1178 goto respond;
1179
1180 lxc_list_for_each(it, &conf->devices) {
1181 struct device_item *cur = it->elem;
1182
1183 ret = bpf_program_append_device(devices, cur);
1184 if (ret)
1185 goto respond;
1186 }
1187
1188 ret = bpf_program_finalize(devices);
1189 if (ret)
1190 goto respond;
1191
1192 ret = bpf_program_cgroup_attach(devices, BPF_CGROUP_DEVICE,
1193 unified->container_full_path,
1194 BPF_F_ALLOW_MULTI);
1195 if (ret)
1196 goto respond;
1197
1198 /* Replace old bpf program. */
1199 devices_old = move_ptr(conf->cgroup2_devices);
1200 conf->cgroup2_devices = move_ptr(devices);
1201 devices = move_ptr(devices_old);
1202
1203 rsp.ret = 0;
1204
1205respond:
1206 ret = lxc_cmd_rsp_send(fd, &rsp);
1207 if (ret < 0)
1208 return LXC_CMD_REAP_CLIENT_FD;
1209
1210 return 0;
1211#else
1212 return ret_set_errno(-1, ENOSYS);
1213#endif
1214}
1215
1216int lxc_cmd_console_log(const char *name, const char *lxcpath,
1217 struct lxc_console_log *log)
1218{
1219 int ret, stopped;
1220 struct lxc_cmd_console_log data;
1221 struct lxc_cmd_rr cmd;
1222
1223 data.clear = log->clear;
1224 data.read = log->read;
1225 data.read_max = *log->read_max;
1226
1227 cmd.req.cmd = LXC_CMD_CONSOLE_LOG;
1228 cmd.req.data = &data;
1229 cmd.req.datalen = sizeof(struct lxc_cmd_console_log);
1230
1231 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1232 if (ret < 0)
1233 return ret;
1234
1235 /* There is nothing to be read from the buffer. So clear any values we
1236 * where passed to clearly indicate to the user that nothing went wrong.
1237 */
1238 if (cmd.rsp.ret == -ENODATA || cmd.rsp.ret == -EFAULT || cmd.rsp.ret == -ENOENT) {
1239 *log->read_max = 0;
1240 log->data = NULL;
1241 }
1242
1243 /* This is a proper error so don't touch any values we were passed. */
1244 if (cmd.rsp.ret < 0)
1245 return cmd.rsp.ret;
1246
1247 *log->read_max = cmd.rsp.datalen;
1248 log->data = cmd.rsp.data;
1249
1250 return 0;
1251}
1252
1253static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
1254 struct lxc_handler *handler,
1255 struct lxc_epoll_descr *descr)
1256{
1257 struct lxc_cmd_rsp rsp;
1258 uint64_t buffer_size = handler->conf->console.buffer_size;
1259 const struct lxc_cmd_console_log *log = req->data;
1260 struct lxc_ringbuf *buf = &handler->conf->console.ringbuf;
1261
1262 rsp.ret = -EFAULT;
1263 rsp.datalen = 0;
1264 rsp.data = NULL;
1265 if (buffer_size <= 0)
1266 goto out;
1267
1268 if (log->read || log->write_logfile)
1269 rsp.datalen = lxc_ringbuf_used(buf);
1270
1271 if (log->read)
1272 rsp.data = lxc_ringbuf_get_read_addr(buf);
1273
1274 if (log->read_max > 0 && (log->read_max <= rsp.datalen))
1275 rsp.datalen = log->read_max;
1276
1277 /* there's nothing to read */
1278 rsp.ret = -ENODATA;
1279 if (log->read && (buf->r_off == buf->w_off))
1280 goto out;
1281
1282 rsp.ret = 0;
1283 if (log->clear)
1284 lxc_ringbuf_clear(buf); /* clear the ringbuffer */
1285 else if (rsp.datalen > 0)
1286 lxc_ringbuf_move_read_addr(buf, rsp.datalen);
1287
1288out:
1289 return lxc_cmd_rsp_send(fd, &rsp);
1290}
1291
1292int lxc_cmd_serve_state_clients(const char *name, const char *lxcpath,
1293 lxc_state_t state)
1294{
1295 int stopped;
1296 ssize_t ret;
1297 struct lxc_cmd_rr cmd = {
1298 .req = {
1299 .cmd = LXC_CMD_SERVE_STATE_CLIENTS,
1300 .data = INT_TO_PTR(state)
1301 },
1302 };
1303
1304 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1305 if (ret < 0)
1306 return log_error_errno(-1, errno, "Failed to serve state clients");
1307
1308 return 0;
1309}
1310
1311static int lxc_cmd_serve_state_clients_callback(int fd, struct lxc_cmd_req *req,
1312 struct lxc_handler *handler,
1313 struct lxc_epoll_descr *descr)
1314{
1315 int ret;
1316 lxc_state_t state = PTR_TO_INT(req->data);
1317 struct lxc_cmd_rsp rsp = {0};
1318
1319 ret = lxc_serve_state_clients(handler->name, handler, state);
1320 if (ret < 0)
1321 return LXC_CMD_REAP_CLIENT_FD;
1322
1323 ret = lxc_cmd_rsp_send(fd, &rsp);
1324 if (ret < 0)
1325 return LXC_CMD_REAP_CLIENT_FD;
1326
1327 return 0;
1328}
1329
1330int lxc_cmd_seccomp_notify_add_listener(const char *name, const char *lxcpath,
1331 int fd,
1332 /* unused */ unsigned int command,
1333 /* unused */ unsigned int flags)
1334{
1335
1336#ifdef HAVE_SECCOMP_NOTIFY
1337 int ret, stopped;
1338 struct lxc_cmd_rr cmd = {
1339 .req = {
1340 .cmd = LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER,
1341 .data = INT_TO_PTR(fd),
1342 },
1343 };
1344
1345 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1346 if (ret < 0)
1347 return log_error_errno(-1, errno, "Failed to add seccomp listener");
1348
1349 return cmd.rsp.ret;
1350#else
1351 return ret_set_errno(-1, ENOSYS);
1352#endif
1353}
1354
1355static int lxc_cmd_seccomp_notify_add_listener_callback(int fd,
1356 struct lxc_cmd_req *req,
1357 struct lxc_handler *handler,
1358 struct lxc_epoll_descr *descr)
1359{
1360 struct lxc_cmd_rsp rsp = {0};
1361
1362#ifdef HAVE_SECCOMP_NOTIFY
1363 int ret;
1364 __do_close int recv_fd = -EBADF;
1365
1366 ret = lxc_abstract_unix_recv_fds(fd, &recv_fd, 1, NULL, 0);
1367 if (ret <= 0) {
1368 rsp.ret = -errno;
1369 goto out;
1370 }
1371
1372 if (!handler->conf->seccomp.notifier.wants_supervision ||
1373 handler->conf->seccomp.notifier.proxy_fd < 0) {
1374 SYSERROR("No seccomp proxy fd specified");
1375 rsp.ret = -EINVAL;
1376 goto out;
1377 }
1378
1379 ret = lxc_mainloop_add_handler(descr, recv_fd, seccomp_notify_handler,
1380 handler);
1381 if (ret < 0) {
1382 rsp.ret = -errno;
1383 goto out;
1384 }
1385 move_fd(recv_fd);
1386
1387out:
1388#else
1389 rsp.ret = -ENOSYS;
1390
1391#endif
1392 return lxc_cmd_rsp_send(fd, &rsp);
1393}
1394
1395int lxc_cmd_freeze(const char *name, const char *lxcpath, int timeout)
1396{
1397 int ret, stopped;
1398 struct lxc_cmd_rr cmd = {
1399 .req = {
1400 .cmd = LXC_CMD_FREEZE,
1401 .data = INT_TO_PTR(timeout),
1402 },
1403 };
1404
1405 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1406 if (ret <= 0 || cmd.rsp.ret < 0)
1407 return log_error_errno(-1, errno, "Failed to freeze container");
1408
1409 return cmd.rsp.ret;
1410}
1411
1412static int lxc_cmd_freeze_callback(int fd, struct lxc_cmd_req *req,
1413 struct lxc_handler *handler,
1414 struct lxc_epoll_descr *descr)
1415{
1416 int timeout = PTR_TO_INT(req->data);
1417 struct lxc_cmd_rsp rsp = {
1418 .ret = -ENOENT,
1419 };
1420 struct cgroup_ops *ops = handler->cgroup_ops;
1421
1422 if (pure_unified_layout(ops))
1423 rsp.ret = ops->freeze(ops, timeout);
1424
1425 return lxc_cmd_rsp_send(fd, &rsp);
1426}
1427
1428int lxc_cmd_unfreeze(const char *name, const char *lxcpath, int timeout)
1429{
1430 int ret, stopped;
1431 struct lxc_cmd_rr cmd = {
1432 .req = {
1433 .cmd = LXC_CMD_UNFREEZE,
1434 .data = INT_TO_PTR(timeout),
1435 },
1436 };
1437
1438 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1439 if (ret <= 0 || cmd.rsp.ret < 0)
1440 return log_error_errno(-1, errno, "Failed to unfreeze container");
1441
1442 return cmd.rsp.ret;
1443}
1444
1445static int lxc_cmd_unfreeze_callback(int fd, struct lxc_cmd_req *req,
1446 struct lxc_handler *handler,
1447 struct lxc_epoll_descr *descr)
1448{
1449 int timeout = PTR_TO_INT(req->data);
1450 struct lxc_cmd_rsp rsp = {
1451 .ret = -ENOENT,
1452 };
1453 struct cgroup_ops *ops = handler->cgroup_ops;
1454
1455 if (pure_unified_layout(ops))
1456 rsp.ret = ops->unfreeze(ops, timeout);
1457
1458 return lxc_cmd_rsp_send(fd, &rsp);
1459}
1460
1461int lxc_cmd_get_cgroup2_fd(const char *name, const char *lxcpath)
1462{
1463 int ret, stopped;
1464 struct lxc_cmd_rr cmd = {
1465 .req = {
1466 .cmd = LXC_CMD_GET_CGROUP2_FD,
1467 },
1468 };
1469
1470 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1471 if (ret < 0)
1472 return -1;
1473
1474 if (cmd.rsp.ret < 0)
1475 return log_debug_errno(cmd.rsp.ret, -cmd.rsp.ret, "Failed to receive cgroup2 fd");
1476
1477 return PTR_TO_INT(cmd.rsp.data);
1478}
1479
1480static int lxc_cmd_get_cgroup2_fd_callback_do(int fd, struct lxc_cmd_req *req,
1481 struct lxc_handler *handler,
1482 struct lxc_epoll_descr *descr,
1483 bool limiting_cgroup)
1484{
1485 struct lxc_cmd_rsp rsp = {
1486 .ret = -EINVAL,
1487 };
1488 struct cgroup_ops *ops = handler->cgroup_ops;
1489 int ret, send_fd;
1490
1491 if (!pure_unified_layout(ops) || !ops->unified)
1492 return lxc_cmd_rsp_send(fd, &rsp);
1493
1494 send_fd = limiting_cgroup ? ops->unified->cgfd_limit
1495 : ops->unified->cgfd_con;
1496
1497 rsp.ret = 0;
1498 ret = lxc_abstract_unix_send_fds(fd, &send_fd, 1, &rsp, sizeof(rsp));
1499 if (ret < 0)
1500 return log_error(LXC_CMD_REAP_CLIENT_FD, "Failed to send cgroup2 fd");
1501
1502 return 0;
1503}
1504
1505static int lxc_cmd_get_cgroup2_fd_callback(int fd, struct lxc_cmd_req *req,
1506 struct lxc_handler *handler,
1507 struct lxc_epoll_descr *descr)
1508{
1509 return lxc_cmd_get_cgroup2_fd_callback_do(fd, req, handler, descr,
1510 false);
1511}
1512
1513static int lxc_cmd_get_limiting_cgroup2_fd_callback(int fd,
1514 struct lxc_cmd_req *req,
1515 struct lxc_handler *handler,
1516 struct lxc_epoll_descr *descr)
1517{
1518 return lxc_cmd_get_cgroup2_fd_callback_do(fd, req, handler, descr,
1519 true);
1520}
1521
1522static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
1523 struct lxc_handler *handler,
1524 struct lxc_epoll_descr *descr)
1525{
1526 typedef int (*callback)(int, struct lxc_cmd_req *, struct lxc_handler *,
1527 struct lxc_epoll_descr *);
1528
1529 callback cb[LXC_CMD_MAX] = {
1530 [LXC_CMD_CONSOLE] = lxc_cmd_console_callback,
1531 [LXC_CMD_TERMINAL_WINCH] = lxc_cmd_terminal_winch_callback,
1532 [LXC_CMD_STOP] = lxc_cmd_stop_callback,
1533 [LXC_CMD_GET_STATE] = lxc_cmd_get_state_callback,
1534 [LXC_CMD_GET_INIT_PID] = lxc_cmd_get_init_pid_callback,
1535 [LXC_CMD_GET_CLONE_FLAGS] = lxc_cmd_get_clone_flags_callback,
1536 [LXC_CMD_GET_CGROUP] = lxc_cmd_get_cgroup_callback,
1537 [LXC_CMD_GET_CONFIG_ITEM] = lxc_cmd_get_config_item_callback,
1538 [LXC_CMD_GET_NAME] = lxc_cmd_get_name_callback,
1539 [LXC_CMD_GET_LXCPATH] = lxc_cmd_get_lxcpath_callback,
1540 [LXC_CMD_ADD_STATE_CLIENT] = lxc_cmd_add_state_client_callback,
1541 [LXC_CMD_CONSOLE_LOG] = lxc_cmd_console_log_callback,
1542 [LXC_CMD_SERVE_STATE_CLIENTS] = lxc_cmd_serve_state_clients_callback,
1543 [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER] = lxc_cmd_seccomp_notify_add_listener_callback,
1544 [LXC_CMD_ADD_BPF_DEVICE_CGROUP] = lxc_cmd_add_bpf_device_cgroup_callback,
1545 [LXC_CMD_FREEZE] = lxc_cmd_freeze_callback,
1546 [LXC_CMD_UNFREEZE] = lxc_cmd_unfreeze_callback,
1547 [LXC_CMD_GET_CGROUP2_FD] = lxc_cmd_get_cgroup2_fd_callback,
1548 [LXC_CMD_GET_INIT_PIDFD] = lxc_cmd_get_init_pidfd_callback,
1549 [LXC_CMD_GET_LIMITING_CGROUP] = lxc_cmd_get_limiting_cgroup_callback,
1550 [LXC_CMD_GET_LIMITING_CGROUP2_FD] = lxc_cmd_get_limiting_cgroup2_fd_callback,
1551 [LXC_CMD_GET_DEVPTS_FD] = lxc_cmd_get_devpts_fd_callback,
1552 };
1553
1554 if (req->cmd >= LXC_CMD_MAX)
1555 return log_trace_errno(-1, EINVAL, "Invalid command id %d", req->cmd);
1556
1557 return cb[req->cmd](fd, req, handler, descr);
1558}
1559
1560static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler,
1561 struct lxc_epoll_descr *descr, const lxc_cmd_t cmd)
1562{
1563 lxc_terminal_free(handler->conf, fd);
1564 lxc_mainloop_del_handler(descr, fd);
1565
1566 if (cmd == LXC_CMD_ADD_STATE_CLIENT) {
1567 struct lxc_list *cur, *next;
1568
1569 lxc_list_for_each_safe(cur, &handler->conf->state_clients, next) {
1570 struct lxc_state_client *client = cur->elem;
1571
1572 if (client->clientfd != fd)
1573 continue;
1574
1575 /*
1576 * Only kick client from list so it can't be found
1577 * anymore. The actual close happens, as for all other
1578 * file descriptors, below.
1579 */
1580 lxc_list_del(cur);
1581 free(cur->elem);
1582 free(cur);
1583
1584 /*
1585 * No need to walk the whole list. If we found the state
1586 * client fd there can't be a second one.
1587 */
1588 TRACE("Found state client fd %d in state client list for command \"%s\"", fd, lxc_cmd_str(cmd));
1589 break;
1590 }
1591
1592 /*
1593 * We didn't add the state client to the list. Either because
1594 * we failed to allocate memory (unlikely) or because the state
1595 * was already reached by the time we were ready to add it. So
1596 * fallthrough and clean it up.
1597 */
1598 TRACE("Closing state client fd %d for command \"%s\"", fd, lxc_cmd_str(cmd));
1599 }
1600
1601 TRACE("Closing client fd %d for command \"%s\"", fd, lxc_cmd_str(cmd));
1602 close(fd);
1603}
1604
1605static int lxc_cmd_handler(int fd, uint32_t events, void *data,
1606 struct lxc_epoll_descr *descr)
1607{
1608 __do_free void *reqdata = NULL;
1609 int ret;
1610 struct lxc_cmd_req req;
1611 struct lxc_handler *handler = data;
1612
1613 ret = lxc_abstract_unix_rcv_credential(fd, &req, sizeof(req));
1614 if (ret < 0) {
1615 SYSERROR("Failed to receive data on command socket for command \"%s\"", lxc_cmd_str(req.cmd));
1616
1617 if (errno == EACCES) {
1618 /* We don't care for the peer, just send and close. */
1619 struct lxc_cmd_rsp rsp = {
1620 .ret = -EPERM,
1621 };
1622
1623 lxc_cmd_rsp_send(fd, &rsp);
1624 }
1625
1626 goto out_close;
1627 }
1628
1629 if (ret == 0)
1630 goto out_close;
1631
1632 if (ret != sizeof(req)) {
1633 WARN("Failed to receive full command request. Ignoring request for \"%s\"", lxc_cmd_str(req.cmd));
1634 goto out_close;
1635 }
1636
1637 if ((req.datalen > LXC_CMD_DATA_MAX) && (req.cmd != LXC_CMD_CONSOLE_LOG)) {
1638 ERROR("Received command data length %d is too large for command \"%s\"", req.datalen, lxc_cmd_str(req.cmd));
1639 goto out_close;
1640 }
1641
1642 if (req.datalen > 0) {
1643 reqdata = must_realloc(NULL, req.datalen);
1644 ret = lxc_recv_nointr(fd, reqdata, req.datalen, 0);
1645 if (ret != req.datalen) {
1646 WARN("Failed to receive full command request. Ignoring request for \"%s\"", lxc_cmd_str(req.cmd));
1647 goto out_close;
1648 }
1649
1650 req.data = reqdata;
1651 }
1652
1653 ret = lxc_cmd_process(fd, &req, handler, descr);
1654 if (ret) {
1655 /* This is not an error, but only a request to close fd. */
1656 goto out_close;
1657 }
1658
1659out:
1660 return LXC_MAINLOOP_CONTINUE;
1661
1662out_close:
1663 lxc_cmd_fd_cleanup(fd, handler, descr, req.cmd);
1664 goto out;
1665}
1666
1667static int lxc_cmd_accept(int fd, uint32_t events, void *data,
1668 struct lxc_epoll_descr *descr)
1669{
1670 __do_close int connection = -EBADF;
1671 int opt = 1, ret = -1;
1672
1673 connection = accept(fd, NULL, 0);
1674 if (connection < 0)
1675 return log_error_errno(LXC_MAINLOOP_ERROR, errno, "Failed to accept connection to run command");
1676
1677 ret = fcntl(connection, F_SETFD, FD_CLOEXEC);
1678 if (ret < 0)
1679 return log_error_errno(ret, errno, "Failed to set close-on-exec on incoming command connection");
1680
1681 ret = setsockopt(connection, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt));
1682 if (ret < 0)
1683 return log_error_errno(ret, errno, "Failed to enable necessary credentials on command socket");
1684
1685 ret = lxc_mainloop_add_handler(descr, connection, lxc_cmd_handler, data);
1686 if (ret)
1687 return log_error(ret, "Failed to add command handler");
1688
1689 TRACE("Accepted new client as fd %d on command server fd %d", connection, fd);
1690 move_fd(connection);
1691 return ret;
1692}
1693
1694int lxc_cmd_init(const char *name, const char *lxcpath, const char *suffix)
1695{
1696 __do_close int fd = -EBADF;
1697 int ret;
1698 char path[LXC_AUDS_ADDR_LEN] = {0};
1699
1700 ret = lxc_make_abstract_socket_name(path, sizeof(path), name, lxcpath, NULL, suffix);
1701 if (ret < 0)
1702 return -1;
1703
1704 fd = lxc_abstract_unix_open(path, SOCK_STREAM, 0);
1705 if (fd < 0) {
1706 if (errno == EADDRINUSE)
1707 ERROR("Container \"%s\" appears to be already running", name);
1708
1709 return log_error_errno(-1, errno, "Failed to create command socket %s", &path[1]);
1710 }
1711
1712 ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
1713 if (ret < 0)
1714 return log_error_errno(-1, errno, "Failed to set FD_CLOEXEC on command socket file descriptor");
1715
1716 return log_trace(move_fd(fd), "Created abstract unix socket \"%s\"", &path[1]);
1717}
1718
1719int lxc_cmd_mainloop_add(const char *name, struct lxc_epoll_descr *descr,
1720 struct lxc_handler *handler)
1721{
1722 int ret;
1723
1724 ret = lxc_mainloop_add_handler(descr, handler->conf->maincmd_fd, lxc_cmd_accept, handler);
1725 if (ret < 0)
1726 return log_error(ret, "Failed to add handler for command socket fd %d", handler->conf->maincmd_fd);
1727
1728 return ret;
1729}