]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/commands.c
tree-wide: convert fcntl(FD_CLOEXEC) to SOCK_CLOEXEC
[mirror_lxc.git] / src / lxc / commands.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include "config.h"
4
5 #include <caps.h>
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <malloc.h>
9 #include <poll.h>
10 #include <signal.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <sys/param.h>
14 #include <sys/socket.h>
15 #include <sys/un.h>
16 #include <unistd.h>
17
18 #include "af_unix.h"
19 #include "cgroups/cgroup.h"
20 #include "cgroups/cgroup2_devices.h"
21 #include "commands.h"
22 #include "commands_utils.h"
23 #include "conf.h"
24 #include "confile.h"
25 #include "log.h"
26 #include "lxc.h"
27 #include "lxclock.h"
28 #include "lxcseccomp.h"
29 #include "mainloop.h"
30 #include "memory_utils.h"
31 #include "monitor.h"
32 #include "start.h"
33 #include "terminal.h"
34 #include "utils.h"
35
36 /*
37 * This file provides the different functions for clients to query/command the
38 * server. The client is typically some lxc tool and the server is typically the
39 * container (ie. lxc-start).
40 *
41 * Each command is transactional, the clients send a request to the server and
42 * the server answers the request with a message giving the request's status
43 * (zero or a negative errno value). Both the request and response may contain
44 * additional data.
45 *
46 * Each command is wrapped in a ancillary message in order to pass a credential
47 * making possible to the server to check if the client is allowed to ask for
48 * this command or not.
49 *
50 * IMPORTANTLY: Note that semantics for current commands are fixed. If you wish
51 * to make any changes to how, say, LXC_CMD_GET_CONFIG_ITEM works by adding
52 * information to the end of cmd.data, then you must introduce a new
53 * LXC_CMD_GET_CONFIG_ITEM_V2 define with a new number. You may wish to also
54 * mark LXC_CMD_GET_CONFIG_ITEM deprecated in commands.h.
55 *
56 * This is necessary in order to avoid having a newly compiled lxc command
57 * communicating with a running (old) monitor from crashing the running
58 * container.
59 */
60
61 lxc_log_define(commands, lxc);
62
63 static const char *lxc_cmd_str(lxc_cmd_t cmd)
64 {
65 static const char *const cmdname[LXC_CMD_MAX] = {
66 [LXC_CMD_GET_TTY_FD] = "get_tty_fd",
67 [LXC_CMD_TERMINAL_WINCH] = "terminal_winch",
68 [LXC_CMD_STOP] = "stop",
69 [LXC_CMD_GET_STATE] = "get_state",
70 [LXC_CMD_GET_INIT_PID] = "get_init_pid",
71 [LXC_CMD_GET_CLONE_FLAGS] = "get_clone_flags",
72 [LXC_CMD_GET_CGROUP] = "get_cgroup",
73 [LXC_CMD_GET_CONFIG_ITEM] = "get_config_item",
74 [LXC_CMD_GET_NAME] = "get_name",
75 [LXC_CMD_GET_LXCPATH] = "get_lxcpath",
76 [LXC_CMD_ADD_STATE_CLIENT] = "add_state_client",
77 [LXC_CMD_CONSOLE_LOG] = "console_log",
78 [LXC_CMD_SERVE_STATE_CLIENTS] = "serve_state_clients",
79 [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER] = "seccomp_notify_add_listener",
80 [LXC_CMD_ADD_BPF_DEVICE_CGROUP] = "add_bpf_device_cgroup",
81 [LXC_CMD_FREEZE] = "freeze",
82 [LXC_CMD_UNFREEZE] = "unfreeze",
83 [LXC_CMD_GET_CGROUP2_FD] = "get_cgroup2_fd",
84 [LXC_CMD_GET_INIT_PIDFD] = "get_init_pidfd",
85 [LXC_CMD_GET_LIMIT_CGROUP] = "get_limit_cgroup",
86 [LXC_CMD_GET_LIMIT_CGROUP2_FD] = "get_limit_cgroup2_fd",
87 [LXC_CMD_GET_DEVPTS_FD] = "get_devpts_fd",
88 [LXC_CMD_GET_SECCOMP_NOTIFY_FD] = "get_seccomp_notify_fd",
89 [LXC_CMD_GET_CGROUP_CTX] = "get_cgroup_ctx",
90 [LXC_CMD_GET_CGROUP_FD] = "get_cgroup_fd",
91 [LXC_CMD_GET_LIMIT_CGROUP_FD] = "get_limit_cgroup_fd",
92 [LXC_CMD_GET_SYSTEMD_SCOPE] = "get_systemd_scope",
93 };
94
95 if (cmd >= LXC_CMD_MAX)
96 return "Invalid request";
97
98 return cmdname[cmd];
99 }
100
101 static int __transfer_cgroup_ctx_fds(struct unix_fds *fds, struct cgroup_ctx *ctx)
102 {
103 /* This shouldn't be able to happen but better safe than sorry. */
104 if (ctx->fd_len != fds->fd_count_ret ||
105 fds->fd_count_ret > CGROUP_CTX_MAX_FD)
106 return syswarn_set(-EINVAL, "Unexpected number of file descriptors received %u != %u",
107 ctx->fd_len, fds->fd_count_ret);
108
109 memcpy(ctx->fd, fds->fd, ctx->fd_len * sizeof(__s32));
110 fds->fd_count_ret = 0;
111 return 0;
112 }
113
114 static int __transfer_cgroup_fd(struct unix_fds *fds, struct cgroup_fd *fd)
115 {
116 fd->fd = move_fd(fds->fd[0]);
117 return 0;
118 }
119
120 static ssize_t lxc_cmd_rsp_recv_fds(int fd_sock, struct unix_fds *fds,
121 struct lxc_cmd_rsp *rsp,
122 const char *cur_cmdstr)
123 {
124 ssize_t ret;
125
126 ret = lxc_abstract_unix_recv_fds(fd_sock, fds, rsp, sizeof(*rsp));
127 if (ret < 0)
128 return log_error(ret, "Failed to receive file descriptors for command \"%s\"", cur_cmdstr);
129
130 /*
131 * If we end up here with fewer or more file descriptors the caller
132 * must have set flags to indicate that they are fine with this.
133 * Otherwise the call would have failed.
134 */
135
136 if (fds->flags & UNIX_FDS_RECEIVED_EXACT)
137 return log_debug(ret, "Received exact number of file descriptors %u == %u for command \"%s\"",
138 fds->fd_count_max, fds->fd_count_ret, cur_cmdstr);
139
140 if (fds->flags & UNIX_FDS_RECEIVED_LESS)
141 return log_debug(ret, "Received less file descriptors %u < %u for command \"%s\"",
142 fds->fd_count_ret, fds->fd_count_max, cur_cmdstr);
143
144 if (fds->flags & UNIX_FDS_RECEIVED_MORE)
145 return log_debug(ret, "Received more file descriptors (excessive fds were automatically closed) %u > %u for command \"%s\"",
146 fds->fd_count_ret, fds->fd_count_max, cur_cmdstr);
147
148 DEBUG("Command \"%s\" received response", cur_cmdstr);
149 return ret;
150 }
151
152 /*
153 * lxc_cmd_rsp_recv: Receive a response to a command
154 *
155 * @sock : the socket connected to the container
156 * @cmd : command to put response in
157 *
158 * Returns the size of the response message or < 0 on failure
159 *
160 * Note that if the command response datalen > 0, then data is
161 * a malloc()ed buffer and should be free()ed by the caller. If
162 * the response data is <= a void * worth of data, it will be
163 * stored directly in data and datalen will be 0.
164 *
165 * As a special case, the response for LXC_CMD_GET_TTY_FD is created here as
166 * it contains an fd for the ptx pty passed through the unix socket.
167 */
168 static ssize_t lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
169 {
170 __do_free void *__data = NULL;
171 call_cleaner(put_unix_fds) struct unix_fds *fds = &(struct unix_fds){
172 .fd[0 ... KERNEL_SCM_MAX_FD - 1] = -EBADF,
173 };
174 struct lxc_cmd_rsp *rsp = &cmd->rsp;
175 int cur_cmd = cmd->req.cmd;
176 const char *cur_cmdstr;
177 ssize_t bytes_recv;
178
179 /*
180 * Determine whether this command will receive file descriptors and how
181 * many at most.
182 */
183 cur_cmdstr = lxc_cmd_str(cur_cmd);
184 switch (cur_cmd) {
185 case LXC_CMD_GET_CGROUP_FD:
186 __fallthrough;
187 case LXC_CMD_GET_LIMIT_CGROUP_FD:
188 __fallthrough;
189 case LXC_CMD_GET_CGROUP2_FD:
190 __fallthrough;
191 case LXC_CMD_GET_LIMIT_CGROUP2_FD:
192 __fallthrough;
193 case LXC_CMD_GET_INIT_PIDFD:
194 __fallthrough;
195 case LXC_CMD_GET_SECCOMP_NOTIFY_FD:
196 __fallthrough;
197 case LXC_CMD_GET_DEVPTS_FD:
198 fds->fd_count_max = 1;
199 /*
200 * The kernel might not support the required features or the
201 * server might be too old.
202 */
203 fds->flags = UNIX_FDS_ACCEPT_EXACT | UNIX_FDS_ACCEPT_NONE;
204 break;
205 case LXC_CMD_GET_TTY_FD:
206 /*
207 * The requested terminal can be busy so it's perfectly fine
208 * for LXC_CMD_GET_TTY to receive no file descriptor.
209 */
210 fds->fd_count_max = 1;
211 fds->flags = UNIX_FDS_ACCEPT_EXACT | UNIX_FDS_ACCEPT_NONE;
212 break;
213 case LXC_CMD_GET_CGROUP_CTX:
214 fds->fd_count_max = CGROUP_CTX_MAX_FD;
215 /*
216 * The container might run without any cgroup support at all,
217 * i.e. no writable cgroup hierarchy was found.
218 */
219 fds->flags |= UNIX_FDS_ACCEPT_LESS | UNIX_FDS_ACCEPT_NONE ;
220 break;
221 default:
222 fds->fd_count_max = 0;
223 break;
224 }
225
226 /* Receive the first response including file descriptors if any. */
227 bytes_recv = lxc_cmd_rsp_recv_fds(sock, fds, rsp, cur_cmdstr);
228 if (bytes_recv < 0)
229 return bytes_recv;
230
231 /*
232 * Ensure that no excessive data is sent unless someone retrieves the
233 * console ringbuffer.
234 */
235 if ((rsp->datalen > LXC_CMD_DATA_MAX) &&
236 (cur_cmd != LXC_CMD_CONSOLE_LOG))
237 return syserror_set(-E2BIG, "Response data for command \"%s\" is too long: %d bytes > %d",
238 cur_cmdstr, rsp->datalen, LXC_CMD_DATA_MAX);
239
240 /*
241 * Prepare buffer for any command that expects to receive additional
242 * data. Note that some don't want any additional data.
243 */
244 switch (cur_cmd) {
245 case LXC_CMD_GET_CGROUP2_FD: /* no data */
246 __fallthrough;
247 case LXC_CMD_GET_LIMIT_CGROUP2_FD: /* no data */
248 __fallthrough;
249 case LXC_CMD_GET_INIT_PIDFD: /* no data */
250 __fallthrough;
251 case LXC_CMD_GET_DEVPTS_FD: /* no data */
252 __fallthrough;
253 case LXC_CMD_GET_SECCOMP_NOTIFY_FD: /* no data */
254 rsp->data = INT_TO_PTR(move_fd(fds->fd[0]));
255 return log_debug(0, "Finished processing \"%s\" with file descriptor %d", cur_cmdstr, PTR_TO_INT(rsp->data));
256 case LXC_CMD_GET_CGROUP_FD: /* data */
257 __fallthrough;
258 case LXC_CMD_GET_LIMIT_CGROUP_FD: /* data */
259 if ((size_t)rsp->datalen > sizeof(struct cgroup_fd))
260 return syserror_set(-EINVAL, "Invalid response size from server for \"%s\"", cur_cmdstr);
261
262 /* Don't pointlessly allocate. */
263 rsp->data = (void *)cmd->req.data;
264 break;
265 case LXC_CMD_GET_CGROUP_CTX: /* data */
266 if ((size_t)rsp->datalen > sizeof(struct cgroup_ctx))
267 return syserror_set(-EINVAL, "Invalid response size from server for \"%s\"", cur_cmdstr);
268
269 /* Don't pointlessly allocate. */
270 rsp->data = (void *)cmd->req.data;
271 break;
272 case LXC_CMD_GET_TTY_FD: /* data */
273 /*
274 * recv() returns 0 bytes when a tty cannot be allocated,
275 * rsp->ret is < 0 when the peer permission check failed.
276 */
277 if (bytes_recv == 0 || rsp->ret < 0)
278 return 0;
279
280 __data = malloc(sizeof(struct lxc_cmd_tty_rsp_data));
281 if (__data) {
282 struct lxc_cmd_tty_rsp_data *tty = __data;
283
284 tty->ptxfd = move_fd(fds->fd[0]);
285 tty->ttynum = PTR_TO_INT(rsp->data);
286 rsp->datalen = 0;
287 rsp->data = tty;
288 break;
289 }
290 return syserror_set(-ENOMEM, "Failed to receive response for command \"%s\"", cur_cmdstr);
291 case LXC_CMD_CONSOLE_LOG: /* data */
292 if (rsp->datalen > 0)
293 __data = zalloc(rsp->datalen + 1);
294 rsp->data = __data;
295 break;
296 default: /* catch any additional command */
297 if (rsp->datalen > 0) {
298 __data = zalloc(rsp->datalen);
299 rsp->data = __data;
300 }
301 break;
302 }
303
304 if (rsp->datalen > 0) {
305 int err;
306
307 /*
308 * All commands ending up here expect data so rsp->data must be valid.
309 * Either static or allocated memory.
310 */
311 if (!rsp->data)
312 return syserror_set(-ENOMEM, "Failed to prepare response buffer for command \"%s\"",
313 cur_cmdstr);
314
315 bytes_recv = lxc_recv_nointr(sock, rsp->data, rsp->datalen, 0);
316 if (bytes_recv != rsp->datalen)
317 return syserror("Failed to receive response data for command \"%s\": %zd != %d",
318 cur_cmdstr, bytes_recv, rsp->datalen);
319
320 switch (cur_cmd) {
321 case LXC_CMD_GET_CGROUP_CTX:
322 err = __transfer_cgroup_ctx_fds(fds, rsp->data);
323 break;
324 case LXC_CMD_GET_CGROUP_FD:
325 __fallthrough;
326 case LXC_CMD_GET_LIMIT_CGROUP_FD:
327 err = __transfer_cgroup_fd(fds, rsp->data);
328 break;
329 default:
330 err = 0;
331 }
332 if (err < 0)
333 return syserror_ret(err, "Failed to transfer file descriptors for command \"%s\"", cur_cmdstr);
334 }
335
336 move_ptr(__data);
337 return bytes_recv;
338 }
339
340 /*
341 * lxc_cmd_rsp_send: Send a command response
342 *
343 * @fd : file descriptor of socket to send response on
344 * @rsp : response to send
345 *
346 * Returns 0 on success, < 0 on failure
347 */
348 static int __lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
349 {
350 ssize_t ret;
351
352 ret = lxc_send_nointr(fd, rsp, sizeof(*rsp), MSG_NOSIGNAL);
353 if (ret < 0 || (size_t)ret != sizeof(*rsp))
354 return syserror("Failed to send command response %zd", ret);
355
356 if (!rsp->data || rsp->datalen <= 0)
357 return 0;
358
359 ret = lxc_send_nointr(fd, rsp->data, rsp->datalen, MSG_NOSIGNAL);
360 if (ret < 0 || ret != (ssize_t)rsp->datalen)
361 return syswarn("Failed to send command response %zd", ret);
362
363 return 0;
364 }
365
366 static inline int lxc_cmd_rsp_send_reap(int fd, struct lxc_cmd_rsp *rsp)
367 {
368 int ret;
369
370 ret = __lxc_cmd_rsp_send(fd, rsp);
371 if (ret < 0)
372 return ret;
373
374 return LXC_CMD_REAP_CLIENT_FD;
375 }
376
377 static inline int lxc_cmd_rsp_send_keep(int fd, struct lxc_cmd_rsp *rsp)
378 {
379 int ret;
380
381 ret = __lxc_cmd_rsp_send(fd, rsp);
382 if (ret < 0)
383 return ret;
384
385 return 0;
386 }
387
388 static inline int rsp_one_fd_reap(int fd, int fd_send, struct lxc_cmd_rsp *rsp)
389 {
390 ssize_t ret;
391
392 ret = lxc_abstract_unix_send_fds(fd, &fd_send, 1, rsp, sizeof(*rsp));
393 if (ret < 0)
394 return ret;
395
396 if (rsp->data && rsp->datalen > 0) {
397 ret = lxc_send_nointr(fd, rsp->data, rsp->datalen, MSG_NOSIGNAL);
398 if (ret < 0 || ret != (ssize_t)rsp->datalen)
399 return syswarn("Failed to send command response %zd", ret);
400 }
401
402 return LXC_CMD_REAP_CLIENT_FD;
403 }
404
405 static inline int rsp_one_fd_keep(int fd, int fd_send, struct lxc_cmd_rsp *rsp)
406 {
407 int ret;
408
409 ret = rsp_one_fd_reap(fd, fd_send, rsp);
410 if (ret == LXC_CMD_REAP_CLIENT_FD)
411 ret = LXC_CMD_KEEP_CLIENT_FD;
412
413 return ret;
414 }
415
416 __access_r(3, 2) static int rsp_many_fds_reap(int fd, __u32 fds_len,
417 const __s32 fds[static 2],
418 struct lxc_cmd_rsp *rsp)
419 {
420 ssize_t ret;
421
422 if (fds_len > KERNEL_SCM_MAX_FD) {
423 rsp->ret = -E2BIG;
424 return lxc_cmd_rsp_send_reap(fd, rsp);
425 } else if (fds_len == 0) {
426 rsp->ret = -ENOENT;
427 return lxc_cmd_rsp_send_reap(fd, rsp);
428 }
429
430 ret = lxc_abstract_unix_send_fds(fd, fds, fds_len, rsp, sizeof(*rsp));
431 if (ret < 0)
432 return ret;
433
434 if (rsp->data && rsp->datalen > 0) {
435 ret = lxc_send_nointr(fd, rsp->data, rsp->datalen, MSG_NOSIGNAL);
436 if (ret < 0 || ret != (ssize_t)rsp->datalen)
437 return syswarn("Failed to send command response %zd", ret);
438 }
439
440 return LXC_CMD_REAP_CLIENT_FD;
441 }
442
443 static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
444 const char *lxcpath, const char *hashed_sock_name)
445 {
446 __do_close int client_fd = -EBADF;
447 ssize_t ret = -1;
448
449 client_fd = lxc_cmd_connect(name, lxcpath, hashed_sock_name, "command");
450 if (client_fd < 0)
451 return -1;
452
453 ret = lxc_abstract_unix_send_credential(client_fd, &cmd->req,
454 sizeof(cmd->req));
455 if (ret < 0 || (size_t)ret != sizeof(cmd->req))
456 return -1;
457
458 if (cmd->req.cmd == LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER) {
459 int notify_fd = PTR_TO_INT(cmd->req.data);
460 ret = lxc_abstract_unix_send_fds(client_fd, &notify_fd, 1, NULL, 0);
461 if (ret <= 0)
462 return -1;
463 } else {
464 if (cmd->req.datalen <= 0)
465 return move_fd(client_fd);
466
467 errno = EMSGSIZE;
468 ret = lxc_send_nointr(client_fd, (void *)cmd->req.data,
469 cmd->req.datalen, MSG_NOSIGNAL);
470 if (ret < 0 || ret != (ssize_t)cmd->req.datalen)
471 return -1;
472 }
473
474 return move_fd(client_fd);
475 }
476
477 /*
478 * lxc_cmd: Connect to the specified running container, send it a command
479 * request and collect the response
480 *
481 * @name : name of container to connect to
482 * @cmd : command with initialized request to send
483 * @stopped : output indicator if the container was not running
484 * @lxcpath : the lxcpath in which the container is running
485 *
486 * Returns the size of the response message on success, < 0 on failure
487 *
488 * Note that there is a special case for LXC_CMD_GET_TTY_FD. For this command
489 * the fd cannot be closed because it is used as a placeholder to indicate that
490 * a particular tty slot is in use. The fd is also used as a signal to the
491 * container that when the caller dies or closes the fd, the container will
492 * notice the fd on its side of the socket in its mainloop select and then free
493 * the slot with lxc_cmd_fd_cleanup(). The socket fd will be returned in the
494 * cmd response structure.
495 */
496 static ssize_t lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, bool *stopped,
497 const char *lxcpath, const char *hashed_sock_name)
498 {
499 __do_close int client_fd = -EBADF;
500 bool stay_connected = false;
501 ssize_t ret;
502
503 if (cmd->req.cmd == LXC_CMD_GET_TTY_FD ||
504 cmd->req.cmd == LXC_CMD_ADD_STATE_CLIENT)
505 stay_connected = true;
506
507 *stopped = 0;
508
509 client_fd = lxc_cmd_send(name, cmd, lxcpath, hashed_sock_name);
510 if (client_fd < 0) {
511 if (errno == ECONNREFUSED || errno == EPIPE)
512 *stopped = 1;
513
514 return systrace("Command \"%s\" failed to connect command socket", lxc_cmd_str(cmd->req.cmd));
515 }
516
517 ret = lxc_cmd_rsp_recv(client_fd, cmd);
518 if (ret < 0 && errno == ECONNRESET)
519 *stopped = 1;
520
521 TRACE("Opened new command socket connection fd %d for command \"%s\"",
522 client_fd, lxc_cmd_str(cmd->req.cmd));
523
524 if (stay_connected && ret > 0)
525 cmd->rsp.ret = move_fd(client_fd);
526
527 return ret;
528 }
529
530 int lxc_try_cmd(const char *name, const char *lxcpath)
531 {
532 bool stopped = false;
533 ssize_t ret;
534 struct lxc_cmd_rr cmd;
535
536 lxc_cmd_init(&cmd, LXC_CMD_GET_INIT_PID);
537
538 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
539 if (stopped)
540 return 0;
541 if (ret > 0 && cmd.rsp.ret < 0) {
542 errno = cmd.rsp.ret;
543 return -1;
544 }
545 if (ret > 0)
546 return 0;
547
548 /*
549 * At this point we weren't denied access, and the container *was*
550 * started. There was some inexplicable error in the protocol. I'm not
551 * clear on whether we should return -1 here, but we didn't receive a
552 * -EACCES, so technically it's not that we're not allowed to control
553 * the container - it's just not behaving.
554 */
555 return 0;
556 }
557
558 /*
559 * Validate that the input is a proper string parameter. If not,
560 * send an EINVAL response and return -1.
561 *
562 * Precondition: there is non-zero-length data available.
563 */
564 static int validate_string_request(int fd, const struct lxc_cmd_req *req)
565 {
566 size_t maxlen = req->datalen - 1;
567 const char *data = req->data;
568
569 if (data[maxlen] == 0 && strnlen(data, maxlen) == maxlen)
570 return 0;
571
572 struct lxc_cmd_rsp rsp = {
573 .ret = -EINVAL,
574 .datalen = 0,
575 .data = NULL,
576 };
577
578 return lxc_cmd_rsp_send_reap(fd, &rsp);
579 }
580
581 /* Implementations of the commands and their callbacks */
582
583 /*
584 * lxc_cmd_get_init_pid: Get pid of the container's init process
585 *
586 * @name : name of container to connect to
587 * @lxcpath : the lxcpath in which the container is running
588 *
589 * Returns the pid on success, < 0 on failure
590 */
591 pid_t lxc_cmd_get_init_pid(const char *name, const char *lxcpath)
592 {
593 bool stopped = false;
594 ssize_t ret;
595 pid_t pid;
596 struct lxc_cmd_rr cmd;
597
598 lxc_cmd_init(&cmd, LXC_CMD_GET_INIT_PID);
599
600 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
601 if (ret < 0)
602 return -1;
603
604 pid = PTR_TO_PID(cmd.rsp.data);
605 if (pid < 0)
606 return -1;
607
608 /*
609 * We need to assume that pid_t can actually hold any pid given to us
610 * by the kernel. If it can't it's a libc bug.
611 */
612 return (pid_t)pid;
613 }
614
615 static int lxc_cmd_get_init_pid_callback(int fd, struct lxc_cmd_req *req,
616 struct lxc_handler *handler,
617 struct lxc_async_descr *descr)
618 {
619 struct lxc_cmd_rsp rsp = {
620 .data = PID_TO_PTR(handler->pid),
621 };
622
623 return lxc_cmd_rsp_send_reap(fd, &rsp);
624 }
625
626 int lxc_cmd_get_init_pidfd(const char *name, const char *lxcpath)
627 {
628 bool stopped = false;
629 int fd;
630 ssize_t ret;
631 struct lxc_cmd_rr cmd;
632
633 lxc_cmd_init(&cmd, LXC_CMD_GET_INIT_PIDFD);
634
635 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
636 if (ret < 0)
637 return sysdebug("Failed to process \"%s\"",
638 lxc_cmd_str(LXC_CMD_GET_INIT_PIDFD));
639
640 if (cmd.rsp.ret < 0)
641 return sysdebug_set(cmd.rsp.ret, "Failed to receive file descriptor for \"%s\"",
642 lxc_cmd_str(LXC_CMD_GET_INIT_PIDFD));
643
644 fd = PTR_TO_INT(cmd.rsp.data);
645 if (fd < 0)
646 return sysdebug_set(fd, "Received invalid file descriptor for \"%s\"",
647 lxc_cmd_str(LXC_CMD_GET_INIT_PIDFD));
648
649 return fd;
650 }
651
652 static int lxc_cmd_get_init_pidfd_callback(int fd, struct lxc_cmd_req *req,
653 struct lxc_handler *handler,
654 struct lxc_async_descr *descr)
655 {
656 struct lxc_cmd_rsp rsp = {
657 .ret = -EBADF,
658 };
659
660 if (handler->pidfd < 0)
661 return lxc_cmd_rsp_send_reap(fd, &rsp);
662
663 rsp.ret = 0;
664 return rsp_one_fd_reap(fd, handler->pidfd, &rsp);
665 }
666
667 int lxc_cmd_get_devpts_fd(const char *name, const char *lxcpath)
668 {
669 bool stopped = false;
670 int fd;
671 ssize_t ret;
672 struct lxc_cmd_rr cmd;
673
674 lxc_cmd_init(&cmd, LXC_CMD_GET_DEVPTS_FD);
675
676 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
677 if (ret < 0)
678 return sysdebug("Failed to process \"%s\"",
679 lxc_cmd_str(LXC_CMD_GET_DEVPTS_FD));
680
681 if (cmd.rsp.ret < 0)
682 return sysdebug_set(cmd.rsp.ret, "Failed to receive file descriptor for \"%s\"",
683 lxc_cmd_str(LXC_CMD_GET_DEVPTS_FD));
684
685 fd = PTR_TO_INT(cmd.rsp.data);
686 if (fd < 0)
687 return sysdebug_set(fd, "Received invalid file descriptor for \"%s\"",
688 lxc_cmd_str(LXC_CMD_GET_DEVPTS_FD));
689 return fd;
690 }
691
692 static int lxc_cmd_get_devpts_fd_callback(int fd, struct lxc_cmd_req *req,
693 struct lxc_handler *handler,
694 struct lxc_async_descr *descr)
695 {
696 struct lxc_cmd_rsp rsp = {
697 .ret = -EBADF,
698 };
699
700 if (handler->conf->devpts_fd < 0)
701 return lxc_cmd_rsp_send_reap(fd, &rsp);
702
703 rsp.ret = 0;
704 return rsp_one_fd_reap(fd, handler->conf->devpts_fd, &rsp);
705 }
706
707 int lxc_cmd_get_seccomp_notify_fd(const char *name, const char *lxcpath)
708 {
709 #if HAVE_DECL_SECCOMP_NOTIFY_FD
710 bool stopped = false;
711 int fd;
712 ssize_t ret;
713 struct lxc_cmd_rr cmd;
714
715 lxc_cmd_init(&cmd, LXC_CMD_GET_SECCOMP_NOTIFY_FD);
716
717 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
718 if (ret < 0)
719 return sysdebug("Failed to process \"%s\"",
720 lxc_cmd_str(LXC_CMD_GET_SECCOMP_NOTIFY_FD));
721
722 if (cmd.rsp.ret < 0)
723 return sysdebug_set(cmd.rsp.ret, "Failed to receive file descriptor for \"%s\"",
724 lxc_cmd_str(LXC_CMD_GET_SECCOMP_NOTIFY_FD));
725
726 fd = PTR_TO_INT(cmd.rsp.data);
727 if (fd < 0)
728 return sysdebug_set(fd, "Received invalid file descriptor for \"%s\"",
729 lxc_cmd_str(LXC_CMD_GET_SECCOMP_NOTIFY_FD));
730 return fd;
731 #else
732 return ret_errno(ENOSYS);
733 #endif
734 }
735
736 static int lxc_cmd_get_seccomp_notify_fd_callback(int fd, struct lxc_cmd_req *req,
737 struct lxc_handler *handler,
738 struct lxc_async_descr *descr)
739 {
740 #if HAVE_DECL_SECCOMP_NOTIFY_FD
741 struct lxc_cmd_rsp rsp = {
742 .ret = -EBADF,
743 };
744
745 if (handler->conf->seccomp.notifier.notify_fd < 0)
746 return lxc_cmd_rsp_send_reap(fd, &rsp);
747
748 rsp.ret = 0;
749 return rsp_one_fd_reap(fd, handler->conf->seccomp.notifier.notify_fd, &rsp);
750 #else
751 return syserror_set(-EOPNOTSUPP, "Seccomp notifier not supported");
752 #endif
753 }
754
755 int lxc_cmd_get_cgroup_ctx(const char *name, const char *lxcpath,
756 size_t size_ret_ctx, struct cgroup_ctx *ret_ctx)
757 {
758 bool stopped = false;
759 ssize_t ret;
760 struct lxc_cmd_rr cmd;
761
762 lxc_cmd_init(&cmd, LXC_CMD_GET_CGROUP_CTX);
763 lxc_cmd_data(&cmd, size_ret_ctx, ret_ctx);
764
765 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
766 if (ret < 0)
767 return sysdebug("Failed to process \"%s\"",
768 lxc_cmd_str(LXC_CMD_GET_CGROUP_CTX));
769
770 if (cmd.rsp.ret < 0) {
771 /* Container does not have any writable cgroups. */
772 if (ret_ctx->fd_len == 0)
773 return 0;
774
775 return sysdebug_set(cmd.rsp.ret, "Failed to receive file descriptor for \"%s\"",
776 lxc_cmd_str(LXC_CMD_GET_CGROUP_CTX));
777 }
778
779 return 0;
780 }
781
782 static int lxc_cmd_get_cgroup_ctx_callback(int fd, struct lxc_cmd_req *req,
783 struct lxc_handler *handler,
784 struct lxc_async_descr *descr)
785 {
786 struct lxc_cmd_rsp rsp = {
787 .ret = EINVAL,
788 };
789 struct cgroup_ops *cgroup_ops = handler->cgroup_ops;
790 struct cgroup_ctx ctx_server = {};
791 ssize_t ret;
792
793 ret = copy_struct_from_client(sizeof(struct cgroup_ctx), &ctx_server,
794 req->datalen, req->data);
795 if (ret < 0)
796 return lxc_cmd_rsp_send_reap(fd, &rsp);
797
798 ret = prepare_cgroup_ctx(cgroup_ops, &ctx_server);
799 if (ret < 0) {
800 rsp.ret = ret;
801 return lxc_cmd_rsp_send_reap(fd, &rsp);
802 }
803
804 rsp.ret = 0;
805 rsp.data = &ctx_server;
806 rsp.datalen = min(sizeof(struct cgroup_ctx), (size_t)req->datalen);
807 return rsp_many_fds_reap(fd, ctx_server.fd_len, ctx_server.fd, &rsp);
808 }
809
810 /*
811 * lxc_cmd_get_clone_flags: Get clone flags container was spawned with
812 *
813 * @name : name of container to connect to
814 * @lxcpath : the lxcpath in which the container is running
815 *
816 * Returns the clone flags on success, < 0 on failure
817 */
818 int lxc_cmd_get_clone_flags(const char *name, const char *lxcpath)
819 {
820 bool stopped = false;
821 ssize_t ret;
822 struct lxc_cmd_rr cmd;
823
824 lxc_cmd_init(&cmd, LXC_CMD_GET_CLONE_FLAGS);
825
826 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
827 if (ret < 0)
828 return ret;
829
830 return PTR_TO_INT(cmd.rsp.data);
831 }
832
833 static int lxc_cmd_get_clone_flags_callback(int fd, struct lxc_cmd_req *req,
834 struct lxc_handler *handler,
835 struct lxc_async_descr *descr)
836 {
837 struct lxc_cmd_rsp rsp = {
838 .data = INT_TO_PTR(handler->ns_clone_flags),
839 };
840
841 return lxc_cmd_rsp_send_reap(fd, &rsp);
842 }
843
844 static char *lxc_cmd_get_cgroup_path_callback(const char *name,
845 const char *lxcpath,
846 const char *controller,
847 lxc_cmd_t command)
848 {
849 bool stopped = false;
850 ssize_t ret;
851 struct lxc_cmd_rr cmd;
852
853 lxc_cmd_init(&cmd, command);
854 if (controller)
855 lxc_cmd_data(&cmd, strlen(controller) + 1, controller);
856
857 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
858 if (ret < 0)
859 return NULL;
860
861 if (ret == 0) {
862 if (command == LXC_CMD_GET_LIMIT_CGROUP) {
863 /*
864 * This may indicate that the container was started
865 * under an ealier version before
866 * `cgroup_advanced_isolation` as implemented, there
867 * it sees an unknown command and just closes the
868 * socket, sending us an EOF.
869 */
870 return lxc_cmd_get_cgroup_path_callback(name, lxcpath,
871 controller,
872 LXC_CMD_GET_CGROUP);
873 }
874 return NULL;
875 }
876
877 if (cmd.rsp.ret < 0 || cmd.rsp.datalen < 0)
878 return NULL;
879
880 return cmd.rsp.data;
881 }
882
883 /*
884 * lxc_cmd_get_cgroup_path: Calculate a container's cgroup path for a
885 * particular controller. This is the cgroup path relative to the root
886 * of the cgroup filesystem.
887 *
888 * @name : name of container to connect to
889 * @lxcpath : the lxcpath in which the container is running
890 * @controller : the controller being asked about
891 *
892 * Returns the path on success, NULL on failure. The caller must free() the
893 * returned path.
894 */
895 char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath,
896 const char *controller)
897 {
898 return lxc_cmd_get_cgroup_path_callback(name, lxcpath, controller,
899 LXC_CMD_GET_CGROUP);
900 }
901
902 /*
903 * lxc_cmd_get_limit_cgroup_path: Calculate a container's limit cgroup
904 * path for a particular controller. This is the cgroup path relative to the
905 * root of the cgroup filesystem. This may be the same as the path returned by
906 * lxc_cmd_get_cgroup_path if the container doesn't have a limit path prefix
907 * set.
908 *
909 * @name : name of container to connect to
910 * @lxcpath : the lxcpath in which the container is running
911 * @controller : the controller being asked about
912 *
913 * Returns the path on success, NULL on failure. The caller must free() the
914 * returned path.
915 */
916 char *lxc_cmd_get_limit_cgroup_path(const char *name, const char *lxcpath,
917 const char *controller)
918 {
919 return lxc_cmd_get_cgroup_path_callback(name, lxcpath, controller,
920 LXC_CMD_GET_LIMIT_CGROUP);
921 }
922
923 static int __lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req,
924 struct lxc_handler *handler,
925 struct lxc_async_descr *descr,
926 bool limiting_cgroup)
927 {
928 ssize_t ret;
929 const char *path;
930 const void *reqdata;
931 struct lxc_cmd_rsp rsp;
932 struct cgroup_ops *cgroup_ops = handler->cgroup_ops;
933 const char *(*get_fn)(struct cgroup_ops *ops, const char *controller);
934
935 if (req->datalen > 0) {
936 ret = validate_string_request(fd, req);
937 if (ret != 0)
938 return ret;
939 reqdata = req->data;
940 } else {
941 reqdata = NULL;
942 }
943
944 get_fn = (limiting_cgroup ? cgroup_ops->get_limit_cgroup
945 : cgroup_ops->get_cgroup);
946
947 path = get_fn(cgroup_ops, reqdata);
948
949 if (!path)
950 return -1;
951
952 rsp.ret = 0;
953 rsp.datalen = strlen(path) + 1;
954 rsp.data = (char *)path;
955
956 return lxc_cmd_rsp_send_reap(fd, &rsp);
957 }
958
959 static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req,
960 struct lxc_handler *handler,
961 struct lxc_async_descr *descr)
962 {
963 return __lxc_cmd_get_cgroup_callback(fd, req, handler, descr, false);
964 }
965
966 static int lxc_cmd_get_limit_cgroup_callback(int fd, struct lxc_cmd_req *req,
967 struct lxc_handler *handler,
968 struct lxc_async_descr *descr)
969 {
970 return __lxc_cmd_get_cgroup_callback(fd, req, handler, descr, true);
971 }
972
973 /*
974 * lxc_cmd_get_config_item: Get config item the running container
975 *
976 * @name : name of container to connect to
977 * @item : the configuration item to retrieve (ex: lxc.net.0.veth.pair)
978 * @lxcpath : the lxcpath in which the container is running
979 *
980 * Returns the item on success, NULL on failure. The caller must free() the
981 * returned item.
982 */
983 char *lxc_cmd_get_config_item(const char *name, const char *item,
984 const char *lxcpath)
985 {
986 bool stopped = false;
987 ssize_t ret;
988 struct lxc_cmd_rr cmd;
989
990 if (is_empty_string(item))
991 return NULL;
992
993 lxc_cmd_init(&cmd, LXC_CMD_GET_CONFIG_ITEM);
994 lxc_cmd_data(&cmd, strlen(item) + 1, item);
995
996 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
997 if (ret < 0)
998 return NULL;
999
1000 if (cmd.rsp.ret == 0)
1001 return cmd.rsp.data;
1002
1003 return NULL;
1004 }
1005
1006 static int lxc_cmd_get_config_item_callback(int fd, struct lxc_cmd_req *req,
1007 struct lxc_handler *handler,
1008 struct lxc_async_descr *descr)
1009 {
1010 __do_free char *cidata = NULL;
1011 int cilen;
1012 struct lxc_config_t *item;
1013 struct lxc_cmd_rsp rsp;
1014
1015 memset(&rsp, 0, sizeof(rsp));
1016 item = lxc_get_config(req->data);
1017 cilen = item->get(req->data, NULL, 0, handler->conf, NULL);
1018 if (cilen <= 0)
1019 goto err1;
1020
1021 cidata = must_realloc(NULL, cilen + 1);
1022 if (item->get(req->data, cidata, cilen + 1, handler->conf, NULL) != cilen)
1023 goto err1;
1024
1025 cidata[cilen] = '\0';
1026 rsp.data = cidata;
1027 rsp.datalen = cilen + 1;
1028 rsp.ret = 0;
1029 goto out;
1030
1031 err1:
1032 rsp.ret = -1;
1033 out:
1034 return lxc_cmd_rsp_send_reap(fd, &rsp);
1035 }
1036
1037 /*
1038 * lxc_cmd_get_state: Get current state of the container
1039 *
1040 * @name : name of container to connect to
1041 * @lxcpath : the lxcpath in which the container is running
1042 *
1043 * Returns the state on success, < 0 on failure
1044 */
1045 int lxc_cmd_get_state(const char *name, const char *lxcpath)
1046 {
1047 bool stopped = false;
1048 ssize_t ret;
1049 struct lxc_cmd_rr cmd;
1050
1051 lxc_cmd_init(&cmd, LXC_CMD_GET_STATE);
1052
1053 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1054 if (ret < 0 && stopped)
1055 return STOPPED;
1056
1057 if (ret < 0)
1058 return -1;
1059
1060 if (!ret)
1061 return log_warn(-1, "Container \"%s\" has stopped before sending its state", name);
1062
1063 return log_debug(PTR_TO_INT(cmd.rsp.data),
1064 "Container \"%s\" is in \"%s\" state", name,
1065 lxc_state2str(PTR_TO_INT(cmd.rsp.data)));
1066 }
1067
1068 static int lxc_cmd_get_state_callback(int fd, struct lxc_cmd_req *req,
1069 struct lxc_handler *handler,
1070 struct lxc_async_descr *descr)
1071 {
1072 struct lxc_cmd_rsp rsp = {
1073 .data = INT_TO_PTR(handler->state),
1074 };
1075
1076 return lxc_cmd_rsp_send_reap(fd, &rsp);
1077 }
1078
1079 /*
1080 * lxc_cmd_stop: Stop the container previously started with lxc_start. All
1081 * the processes running inside this container will be killed.
1082 *
1083 * @name : name of container to connect to
1084 * @lxcpath : the lxcpath in which the container is running
1085 *
1086 * Returns 0 on success, < 0 on failure
1087 */
1088 int lxc_cmd_stop(const char *name, const char *lxcpath)
1089 {
1090 bool stopped = false;
1091 ssize_t ret;
1092 struct lxc_cmd_rr cmd;
1093
1094 lxc_cmd_init(&cmd, LXC_CMD_STOP);
1095
1096 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1097 if (ret < 0) {
1098 if (stopped)
1099 return log_info(0, "Container \"%s\" is already stopped", name);
1100
1101 return -1;
1102 }
1103
1104 /* We do not expect any answer, because we wait for the connection to be
1105 * closed.
1106 */
1107 if (ret > 0)
1108 return log_error_errno(-1, -cmd.rsp.ret, "Failed to stop container \"%s\"", name);
1109
1110 return log_info(0, "Container \"%s\" has stopped", name);
1111 }
1112
1113 static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req,
1114 struct lxc_handler *handler,
1115 struct lxc_async_descr *descr)
1116 {
1117 struct lxc_cmd_rsp rsp;
1118 int stopsignal = SIGKILL;
1119 struct cgroup_ops *cgroup_ops = handler->cgroup_ops;
1120 int ret;
1121
1122 if (handler->conf->stopsignal)
1123 stopsignal = handler->conf->stopsignal;
1124 memset(&rsp, 0, sizeof(rsp));
1125
1126 if (handler->pidfd >= 0)
1127 rsp.ret = lxc_raw_pidfd_send_signal(handler->pidfd, stopsignal, NULL, 0);
1128 else
1129 rsp.ret = kill(handler->pid, stopsignal);
1130 if (!rsp.ret) {
1131 if (handler->pidfd >= 0)
1132 TRACE("Sent signal %d to pidfd %d", stopsignal, handler->pidfd);
1133 else
1134 TRACE("Sent signal %d to pidfd %d", stopsignal, handler->pid);
1135
1136 if (pure_unified_layout(cgroup_ops))
1137 ret = __cgroup_unfreeze(cgroup_ops->unified->dfd_lim, -1);
1138 else
1139 ret = cgroup_ops->unfreeze(cgroup_ops, -1);
1140 if (ret)
1141 WARN("Failed to unfreeze container \"%s\"", handler->name);
1142
1143 return 0;
1144 } else {
1145 rsp.ret = -errno;
1146 }
1147
1148 return lxc_cmd_rsp_send_reap(fd, &rsp);
1149 }
1150
1151 /*
1152 * lxc_cmd_terminal_winch: noop
1153 *
1154 * @name : name of container to connect to
1155 * @lxcpath : the lxcpath in which the container is running
1156 *
1157 * Returns 0 on success, < 0 on failure
1158 */
1159 int lxc_cmd_terminal_winch(const char *name, const char *lxcpath)
1160 {
1161 return 0;
1162 }
1163
1164 static int lxc_cmd_terminal_winch_callback(int fd, struct lxc_cmd_req *req,
1165 struct lxc_handler *handler,
1166 struct lxc_async_descr *descr)
1167 {
1168 /* should never be called */
1169 return syserror_set(-ENOSYS, "Called lxc_cmd_terminal_winch_callback()");
1170 }
1171
1172 /*
1173 * lxc_cmd_get_tty_fd: Open an fd to a tty in the container
1174 *
1175 * @name : name of container to connect to
1176 * @ttynum : in: the tty to open or -1 for next available
1177 * : out: the tty allocated
1178 * @fd : out: file descriptor for ptx side of pty
1179 * @lxcpath : the lxcpath in which the container is running
1180 *
1181 * Returns fd holding tty allocated on success, < 0 on failure
1182 */
1183 int lxc_cmd_get_tty_fd(const char *name, int *ttynum, int *fd, const char *lxcpath)
1184 {
1185 __do_free struct lxc_cmd_tty_rsp_data *rspdata = NULL;
1186 bool stopped = false;
1187 ssize_t ret;
1188 struct lxc_cmd_rr cmd;
1189
1190 lxc_cmd_init(&cmd, LXC_CMD_GET_TTY_FD);
1191 lxc_cmd_data(&cmd, ENCODE_INTO_PTR_LEN, INT_TO_PTR(*ttynum));
1192
1193 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1194 if (ret < 0)
1195 return sysdebug("Failed to process \"%s\"",
1196 lxc_cmd_str(LXC_CMD_GET_TTY_FD));
1197
1198 rspdata = cmd.rsp.data;
1199 if (cmd.rsp.ret < 0)
1200 return log_error_errno(-1, -cmd.rsp.ret, "Denied access to tty");
1201
1202 if (ret == 0)
1203 return log_error(-1, "tty number %d invalid, busy or all ttys busy", *ttynum);
1204
1205 if (rspdata->ptxfd < 0)
1206 return log_error(-1, "Unable to allocate fd for tty %d", rspdata->ttynum);
1207
1208 ret = cmd.rsp.ret; /* socket fd */
1209 *fd = rspdata->ptxfd;
1210 *ttynum = rspdata->ttynum;
1211
1212 INFO("Alloced fd %d for tty %d via socket %zd", *fd, rspdata->ttynum, ret);
1213 return ret;
1214 }
1215
1216 static int lxc_cmd_get_tty_fd_callback(int fd, struct lxc_cmd_req *req,
1217 struct lxc_handler *handler,
1218 struct lxc_async_descr *descr)
1219 {
1220 struct lxc_cmd_rsp rsp = {
1221 .ret = -EBADF,
1222 };
1223 int ptxfd, ret, ttynum;
1224
1225 ttynum = PTR_TO_INT(req->data);
1226 ptxfd = lxc_terminal_allocate(handler->conf, fd, &ttynum);
1227 if (ptxfd < 0)
1228 return lxc_cmd_rsp_send_reap(fd, &rsp);
1229
1230 rsp.ret = 0;
1231 rsp.data = INT_TO_PTR(ttynum);
1232 ret = rsp_one_fd_keep(fd, ptxfd, &rsp);
1233 if (ret < 0) {
1234 lxc_terminal_free(handler->conf, fd);
1235 return ret;
1236 }
1237
1238 DEBUG("Send tty to client");
1239 return ret;
1240 }
1241
1242 /*
1243 * lxc_cmd_get_name: Returns the name of the container
1244 *
1245 * @hashed_sock_name: hashed socket name
1246 *
1247 * Returns the name on success, NULL on failure.
1248 */
1249 char *lxc_cmd_get_name(const char *hashed_sock_name)
1250 {
1251 bool stopped = false;
1252 ssize_t ret;
1253 struct lxc_cmd_rr cmd;
1254
1255 lxc_cmd_init(&cmd, LXC_CMD_GET_NAME);
1256
1257 ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
1258 if (ret < 0)
1259 return NULL;
1260
1261 if (cmd.rsp.ret == 0)
1262 return cmd.rsp.data;
1263
1264 return NULL;
1265 }
1266
1267 static int lxc_cmd_get_name_callback(int fd, struct lxc_cmd_req *req,
1268 struct lxc_handler *handler,
1269 struct lxc_async_descr *descr)
1270 {
1271 struct lxc_cmd_rsp rsp;
1272
1273 memset(&rsp, 0, sizeof(rsp));
1274
1275 rsp.data = (char *)handler->name;
1276 rsp.datalen = strlen(handler->name) + 1;
1277 rsp.ret = 0;
1278
1279 return lxc_cmd_rsp_send_reap(fd, &rsp);
1280 }
1281
1282 /*
1283 * lxc_cmd_get_lxcpath: Returns the lxcpath of the container
1284 *
1285 * @hashed_sock_name: hashed socket name
1286 *
1287 * Returns the lxcpath on success, NULL on failure.
1288 */
1289 char *lxc_cmd_get_lxcpath(const char *hashed_sock_name)
1290 {
1291 bool stopped = false;
1292 ssize_t ret;
1293 struct lxc_cmd_rr cmd;
1294
1295 lxc_cmd_init(&cmd, LXC_CMD_GET_LXCPATH);
1296
1297 ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
1298 if (ret < 0)
1299 return NULL;
1300
1301 if (cmd.rsp.ret == 0)
1302 return cmd.rsp.data;
1303
1304 return NULL;
1305 }
1306
1307 static int lxc_cmd_get_lxcpath_callback(int fd, struct lxc_cmd_req *req,
1308 struct lxc_handler *handler,
1309 struct lxc_async_descr *descr)
1310 {
1311 struct lxc_cmd_rsp rsp = {
1312 .ret = 0,
1313 .data = (char *)handler->lxcpath,
1314 .datalen = strlen(handler->lxcpath) + 1,
1315 };
1316
1317 return lxc_cmd_rsp_send_reap(fd, &rsp);
1318 }
1319
1320 char *lxc_cmd_get_systemd_scope(const char *name, const char *lxcpath)
1321 {
1322 bool stopped = false;
1323 ssize_t ret;
1324 struct lxc_cmd_rr cmd;
1325
1326 lxc_cmd_init(&cmd, LXC_CMD_GET_SYSTEMD_SCOPE);
1327
1328 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1329 if (ret < 0)
1330 return NULL;
1331
1332 if (cmd.rsp.ret == 0)
1333 return cmd.rsp.data;
1334
1335 return NULL;
1336 }
1337
1338 static int lxc_cmd_get_systemd_scope_callback(int fd, struct lxc_cmd_req *req,
1339 struct lxc_handler *handler,
1340 struct lxc_async_descr *descr)
1341 {
1342 __do_free char *scope = NULL;
1343 struct lxc_cmd_rsp rsp = {
1344 .ret = -EINVAL,
1345 };
1346
1347 // cgroup_meta.systemd_scope is the full cgroup path to the scope.
1348 // The caller just wants the actual scope name, that is, basename().
1349 // (XXX - or do we want the caller to massage it? I'm undecided)
1350 if (handler->conf->cgroup_meta.systemd_scope) {
1351 scope = strrchr(handler->conf->cgroup_meta.systemd_scope, '/');
1352 if (scope && *scope)
1353 scope++;
1354 if (scope && *scope)
1355 scope = strdup(scope);
1356 }
1357
1358 if (!scope)
1359 goto out;
1360
1361 rsp.ret = 0;
1362 rsp.data = scope;
1363 rsp.datalen = strlen(scope) + 1;
1364
1365 out:
1366 return lxc_cmd_rsp_send_reap(fd, &rsp);
1367 }
1368
1369 int lxc_cmd_add_state_client(const char *name, const char *lxcpath,
1370 lxc_state_t states[static MAX_STATE],
1371 int *state_client_fd)
1372 {
1373 __do_close int clientfd = -EBADF;
1374 bool stopped = false;
1375 int state;
1376 ssize_t ret;
1377 struct lxc_cmd_rr cmd;
1378
1379 lxc_cmd_init(&cmd, LXC_CMD_ADD_STATE_CLIENT);
1380 lxc_cmd_data(&cmd, (sizeof(lxc_state_t) * MAX_STATE), states);
1381
1382 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1383 if (states[STOPPED] != 0 && stopped != 0)
1384 return STOPPED;
1385
1386 if (ret < 0) {
1387 if (errno != ECONNREFUSED)
1388 SYSERROR("Failed to execute command");
1389
1390 return -1;
1391 }
1392
1393 /* We should now be guaranteed to get an answer from the state sending
1394 * function.
1395 */
1396 clientfd = cmd.rsp.ret;
1397 if (clientfd < 0)
1398 return log_error_errno(-1, -clientfd, "Failed to receive socket fd");
1399
1400 state = PTR_TO_INT(cmd.rsp.data);
1401 if (state < MAX_STATE)
1402 return log_trace(state, "Container is already in requested state %s", lxc_state2str(state));
1403
1404 *state_client_fd = move_fd(clientfd);
1405 TRACE("State connection fd %d ready to listen for container state changes", *state_client_fd);
1406 return MAX_STATE;
1407 }
1408
1409 static int lxc_cmd_add_state_client_callback(__owns int fd, struct lxc_cmd_req *req,
1410 struct lxc_handler *handler,
1411 struct lxc_async_descr *descr)
1412 {
1413 struct lxc_cmd_rsp rsp = {
1414 .ret = -EINVAL,
1415 };
1416
1417 if (req->datalen < 0)
1418 goto reap_fd;
1419
1420 if (req->datalen != (sizeof(lxc_state_t) * MAX_STATE))
1421 goto reap_fd;
1422
1423 if (!req->data)
1424 goto reap_fd;
1425
1426 rsp.ret = lxc_add_state_client(fd, handler, (lxc_state_t *)req->data);
1427 if (rsp.ret < 0)
1428 goto reap_fd;
1429
1430 rsp.data = INT_TO_PTR(rsp.ret);
1431
1432 return lxc_cmd_rsp_send_keep(fd, &rsp);
1433
1434 reap_fd:
1435 return lxc_cmd_rsp_send_reap(fd, &rsp);
1436 }
1437
1438 int lxc_cmd_add_bpf_device_cgroup(const char *name, const char *lxcpath,
1439 struct device_item *device)
1440 {
1441 bool stopped = false;
1442 ssize_t ret;
1443 struct lxc_cmd_rr cmd;
1444
1445 if (strlen(device->access) > STRLITERALLEN("rwm"))
1446 return syserror_set(-EINVAL, "Invalid access mode specified %s", device->access);
1447
1448 lxc_cmd_init(&cmd, LXC_CMD_ADD_BPF_DEVICE_CGROUP);
1449 lxc_cmd_data(&cmd, sizeof(struct device_item), device);
1450
1451 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1452 if (ret < 0)
1453 return syserror_set(ret, "Failed to process new bpf device cgroup command");
1454
1455 if (cmd.rsp.ret < 0)
1456 return syserror_set(cmd.rsp.ret, "Failed to add new bpf device cgroup rule");
1457
1458 return 0;
1459 }
1460
1461 static int lxc_cmd_add_bpf_device_cgroup_callback(int fd, struct lxc_cmd_req *req,
1462 struct lxc_handler *handler,
1463 struct lxc_async_descr *descr)
1464 {
1465 struct lxc_cmd_rsp rsp = {
1466 .ret = -EINVAL,
1467 };
1468 struct lxc_conf *conf;
1469
1470 if (req->datalen <= 0)
1471 goto out;
1472
1473 if (req->datalen != sizeof(struct device_item))
1474 goto out;
1475
1476 if (!req->data)
1477 goto out;
1478
1479 conf = handler->conf;
1480 if (!bpf_cgroup_devices_update(handler->cgroup_ops,
1481 &conf->bpf_devices,
1482 (struct device_item *)req->data))
1483 rsp.ret = -1;
1484 else
1485 rsp.ret = 0;
1486
1487 out:
1488 return lxc_cmd_rsp_send_reap(fd, &rsp);
1489 }
1490
1491 int lxc_cmd_console_log(const char *name, const char *lxcpath,
1492 struct lxc_console_log *log)
1493 {
1494 bool stopped = false;
1495 struct lxc_cmd_console_log data = {
1496 .clear = log->clear,
1497 .read = log->read,
1498 .read_max = *log->read_max,
1499 };
1500 ssize_t ret;
1501 struct lxc_cmd_rr cmd;
1502
1503 lxc_cmd_init(&cmd, LXC_CMD_CONSOLE_LOG);
1504 lxc_cmd_data(&cmd, sizeof(struct lxc_cmd_console_log), &data);
1505
1506 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1507 if (ret < 0)
1508 return ret;
1509
1510 /* There is nothing to be read from the buffer. So clear any values we
1511 * where passed to clearly indicate to the user that nothing went wrong.
1512 */
1513 if (cmd.rsp.ret == -ENODATA || cmd.rsp.ret == -EFAULT || cmd.rsp.ret == -ENOENT) {
1514 *log->read_max = 0;
1515 log->data = NULL;
1516 }
1517
1518 /* This is a proper error so don't touch any values we were passed. */
1519 if (cmd.rsp.ret < 0)
1520 return cmd.rsp.ret;
1521
1522 *log->read_max = cmd.rsp.datalen;
1523 log->data = cmd.rsp.data;
1524
1525 return 0;
1526 }
1527
1528 static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
1529 struct lxc_handler *handler,
1530 struct lxc_async_descr *descr)
1531 {
1532 struct lxc_cmd_rsp rsp;
1533 uint64_t buffer_size = handler->conf->console.buffer_size;
1534 const struct lxc_cmd_console_log *log = req->data;
1535 struct lxc_ringbuf *buf = &handler->conf->console.ringbuf;
1536
1537 rsp.ret = -EFAULT;
1538 rsp.datalen = 0;
1539 rsp.data = NULL;
1540 if (buffer_size <= 0)
1541 goto out;
1542
1543 if (log->read || log->write_logfile)
1544 rsp.datalen = lxc_ringbuf_used(buf);
1545
1546 if (log->read)
1547 rsp.data = lxc_ringbuf_get_read_addr(buf);
1548
1549 if (log->read_max > 0 && (log->read_max <= (uint64_t)rsp.datalen))
1550 rsp.datalen = log->read_max;
1551
1552 /* there's nothing to read */
1553 rsp.ret = -ENODATA;
1554 if (log->read && (buf->r_off == buf->w_off))
1555 goto out;
1556
1557 rsp.ret = 0;
1558 if (log->clear)
1559 lxc_ringbuf_clear(buf); /* clear the ringbuffer */
1560 else if (rsp.datalen > 0)
1561 lxc_ringbuf_move_read_addr(buf, rsp.datalen);
1562
1563 out:
1564 return lxc_cmd_rsp_send_reap(fd, &rsp);
1565 }
1566
1567 int lxc_cmd_serve_state_clients(const char *name, const char *lxcpath,
1568 lxc_state_t state)
1569 {
1570 bool stopped = false;
1571 ssize_t ret;
1572 struct lxc_cmd_rr cmd;
1573
1574 lxc_cmd_init(&cmd, LXC_CMD_SERVE_STATE_CLIENTS);
1575 lxc_cmd_data(&cmd, ENCODE_INTO_PTR_LEN, INT_TO_PTR(state));
1576
1577 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1578 if (ret < 0)
1579 return log_error_errno(-1, errno, "Failed to serve state clients");
1580
1581 return 0;
1582 }
1583
1584 static int lxc_cmd_serve_state_clients_callback(int fd, struct lxc_cmd_req *req,
1585 struct lxc_handler *handler,
1586 struct lxc_async_descr *descr)
1587 {
1588 int ret;
1589 lxc_state_t state = PTR_TO_INT(req->data);
1590 struct lxc_cmd_rsp rsp = {0};
1591
1592 ret = lxc_serve_state_clients(handler->name, handler, state);
1593 if (ret < 0)
1594 return ret;
1595
1596 return lxc_cmd_rsp_send_reap(fd, &rsp);
1597 }
1598
1599 int lxc_cmd_seccomp_notify_add_listener(const char *name, const char *lxcpath,
1600 int fd,
1601 /* unused */ unsigned int command,
1602 /* unused */ unsigned int flags)
1603 {
1604
1605 #if HAVE_DECL_SECCOMP_NOTIFY_FD
1606 bool stopped = false;
1607 ssize_t ret;
1608 struct lxc_cmd_rr cmd;
1609
1610 lxc_cmd_init(&cmd, LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER);
1611 lxc_cmd_data(&cmd, ENCODE_INTO_PTR_LEN, INT_TO_PTR(fd));
1612
1613 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1614 if (ret < 0)
1615 return log_error_errno(-1, errno, "Failed to add seccomp listener");
1616
1617 return cmd.rsp.ret;
1618 #else
1619 return ret_set_errno(-1, ENOSYS);
1620 #endif
1621 }
1622
1623 static int lxc_cmd_seccomp_notify_add_listener_callback(int fd,
1624 struct lxc_cmd_req *req,
1625 struct lxc_handler *handler,
1626 struct lxc_async_descr *descr)
1627 {
1628 struct lxc_cmd_rsp rsp = {0};
1629
1630 #if HAVE_DECL_SECCOMP_NOTIFY_FD
1631 int ret;
1632 __do_close int recv_fd = -EBADF;
1633
1634 ret = lxc_abstract_unix_recv_one_fd(fd, &recv_fd, NULL, 0);
1635 if (ret <= 0) {
1636 rsp.ret = -errno;
1637 goto out;
1638 }
1639
1640 if (!handler->conf->seccomp.notifier.wants_supervision ||
1641 handler->conf->seccomp.notifier.proxy_fd < 0) {
1642 SYSERROR("No seccomp proxy fd specified");
1643 rsp.ret = -EINVAL;
1644 goto out;
1645 }
1646
1647 ret = lxc_mainloop_add_handler(descr, recv_fd,
1648 seccomp_notify_handler,
1649 seccomp_notify_cleanup_handler,
1650 handler, "seccomp_notify_handler");
1651 if (ret < 0) {
1652 rsp.ret = -errno;
1653 goto out;
1654 }
1655 move_fd(recv_fd);
1656
1657 out:
1658 #else
1659 rsp.ret = -ENOSYS;
1660
1661 #endif
1662 return lxc_cmd_rsp_send_reap(fd, &rsp);
1663 }
1664
1665 int lxc_cmd_freeze(const char *name, const char *lxcpath, int timeout)
1666 {
1667 bool stopped = false;
1668 ssize_t ret;
1669 struct lxc_cmd_rr cmd;
1670
1671 lxc_cmd_init(&cmd, LXC_CMD_FREEZE);
1672 lxc_cmd_data(&cmd, ENCODE_INTO_PTR_LEN, INT_TO_PTR(timeout));
1673
1674 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1675 if (ret <= 0 || cmd.rsp.ret < 0)
1676 return log_error_errno(-1, errno, "Failed to freeze container");
1677
1678 return cmd.rsp.ret;
1679 }
1680
1681 static int lxc_cmd_freeze_callback(int fd, struct lxc_cmd_req *req,
1682 struct lxc_handler *handler,
1683 struct lxc_async_descr *descr)
1684 {
1685 int timeout = PTR_TO_INT(req->data);
1686 struct lxc_cmd_rsp rsp = {
1687 .ret = -ENOENT,
1688 };
1689 struct cgroup_ops *ops = handler->cgroup_ops;
1690
1691 if (pure_unified_layout(ops))
1692 rsp.ret = ops->freeze(ops, timeout);
1693
1694 return lxc_cmd_rsp_send_reap(fd, &rsp);
1695 }
1696
1697 int lxc_cmd_unfreeze(const char *name, const char *lxcpath, int timeout)
1698 {
1699 bool stopped = false;
1700 ssize_t ret;
1701 struct lxc_cmd_rr cmd;
1702
1703 lxc_cmd_init(&cmd, LXC_CMD_UNFREEZE);
1704 lxc_cmd_data(&cmd, ENCODE_INTO_PTR_LEN, INT_TO_PTR(timeout));
1705
1706 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1707 if (ret <= 0 || cmd.rsp.ret < 0)
1708 return log_error_errno(-1, errno, "Failed to unfreeze container");
1709
1710 return cmd.rsp.ret;
1711 }
1712
1713 static int lxc_cmd_unfreeze_callback(int fd, struct lxc_cmd_req *req,
1714 struct lxc_handler *handler,
1715 struct lxc_async_descr *descr)
1716 {
1717 int timeout = PTR_TO_INT(req->data);
1718 struct lxc_cmd_rsp rsp = {
1719 .ret = -ENOENT,
1720 };
1721 struct cgroup_ops *ops = handler->cgroup_ops;
1722
1723 if (pure_unified_layout(ops))
1724 rsp.ret = ops->unfreeze(ops, timeout);
1725
1726 return lxc_cmd_rsp_send_reap(fd, &rsp);
1727 }
1728
1729 int lxc_cmd_get_cgroup_fd(const char *name, const char *lxcpath,
1730 size_t size_ret_fd, struct cgroup_fd *ret_fd)
1731 {
1732 bool stopped = false;
1733 ssize_t ret;
1734 struct lxc_cmd_rr cmd;
1735
1736 lxc_cmd_init(&cmd, LXC_CMD_GET_CGROUP_FD);
1737 lxc_cmd_data(&cmd, sizeof(struct cgroup_fd), ret_fd);
1738
1739 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1740 if (ret < 0)
1741 return sysdebug("Failed to process \"%s\"",
1742 lxc_cmd_str(LXC_CMD_GET_CGROUP_FD));
1743
1744 if (cmd.rsp.ret < 0)
1745 return sysdebug_set(cmd.rsp.ret, "Failed to receive file descriptor for \"%s\"",
1746 lxc_cmd_str(LXC_CMD_GET_CGROUP_FD));
1747
1748 return 0;
1749 }
1750
1751 int lxc_cmd_get_limit_cgroup_fd(const char *name, const char *lxcpath,
1752 size_t size_ret_fd, struct cgroup_fd *ret_fd)
1753 {
1754 bool stopped = false;
1755 ssize_t ret;
1756 struct lxc_cmd_rr cmd;
1757
1758 lxc_cmd_init(&cmd, LXC_CMD_GET_LIMIT_CGROUP_FD);
1759 lxc_cmd_data(&cmd, sizeof(struct cgroup_fd), ret_fd);
1760
1761 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1762 if (ret < 0)
1763 return sysdebug("Failed to process \"%s\"",
1764 lxc_cmd_str(LXC_CMD_GET_CGROUP_FD));
1765
1766 if (cmd.rsp.ret < 0)
1767 return sysdebug_set(cmd.rsp.ret, "Failed to receive file descriptor for \"%s\"",
1768 lxc_cmd_str(LXC_CMD_GET_CGROUP_FD));
1769
1770 return 0;
1771 }
1772
1773 static int __lxc_cmd_get_cgroup_fd_callback(int fd, struct lxc_cmd_req *req,
1774 struct lxc_handler *handler,
1775 struct lxc_async_descr *descr,
1776 bool limit)
1777 {
1778 struct lxc_cmd_rsp rsp = {
1779 .ret = -EINVAL,
1780 };
1781 struct cgroup_ops *ops = handler->cgroup_ops;
1782 struct cgroup_fd fd_server = {};
1783 int ret;
1784
1785 ret = copy_struct_from_client(sizeof(struct cgroup_fd), &fd_server,
1786 req->datalen, req->data);
1787 if (ret < 0)
1788 return lxc_cmd_rsp_send_reap(fd, &rsp);
1789
1790 if (strnlen(fd_server.controller, MAX_CGROUP_ROOT_NAMELEN) == 0)
1791 return lxc_cmd_rsp_send_reap(fd, &rsp);
1792
1793 ret = prepare_cgroup_fd(ops, &fd_server, limit);
1794 if (ret < 0) {
1795 rsp.ret = ret;
1796 return lxc_cmd_rsp_send_reap(fd, &rsp);
1797 }
1798
1799 rsp.ret = 0;
1800 rsp.data = &fd_server;
1801 rsp.datalen = min(sizeof(struct cgroup_fd), (size_t)req->datalen);
1802 return rsp_one_fd_reap(fd, fd_server.fd, &rsp);
1803 }
1804
1805 static int lxc_cmd_get_cgroup_fd_callback(int fd, struct lxc_cmd_req *req,
1806 struct lxc_handler *handler,
1807 struct lxc_async_descr *descr)
1808 {
1809 return __lxc_cmd_get_cgroup_fd_callback(fd, req, handler, descr, false);
1810 }
1811
1812 static int lxc_cmd_get_limit_cgroup_fd_callback(int fd, struct lxc_cmd_req *req,
1813 struct lxc_handler *handler,
1814 struct lxc_async_descr *descr)
1815 {
1816 return __lxc_cmd_get_cgroup_fd_callback(fd, req, handler, descr, true);
1817 }
1818
1819 int lxc_cmd_get_cgroup2_fd(const char *name, const char *lxcpath)
1820 {
1821 bool stopped = false;
1822 int fd;
1823 ssize_t ret;
1824 struct lxc_cmd_rr cmd;
1825
1826 lxc_cmd_init(&cmd, LXC_CMD_GET_CGROUP2_FD);
1827
1828 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1829 if (ret < 0)
1830 return sysdebug("Failed to process \"%s\"",
1831 lxc_cmd_str(LXC_CMD_GET_CGROUP2_FD));
1832
1833 if (cmd.rsp.ret < 0)
1834 return sysdebug_set(cmd.rsp.ret, "Failed to receive file descriptor for \"%s\"",
1835 lxc_cmd_str(LXC_CMD_GET_CGROUP2_FD));
1836
1837 fd = PTR_TO_INT(cmd.rsp.data);
1838 if (fd < 0)
1839 return sysdebug_set(fd, "Received invalid file descriptor for \"%s\"",
1840 lxc_cmd_str(LXC_CMD_GET_CGROUP2_FD));
1841 return fd;
1842 }
1843
1844 int lxc_cmd_get_limit_cgroup2_fd(const char *name, const char *lxcpath)
1845 {
1846 bool stopped = false;
1847 int fd;
1848 ssize_t ret;
1849 struct lxc_cmd_rr cmd;
1850
1851 lxc_cmd_init(&cmd, LXC_CMD_GET_LIMIT_CGROUP2_FD);
1852
1853 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1854 if (ret < 0)
1855 return sysdebug("Failed to process \"%s\"",
1856 lxc_cmd_str(LXC_CMD_GET_CGROUP2_FD));
1857
1858 if (cmd.rsp.ret < 0)
1859 return sysdebug_set(cmd.rsp.ret, "Failed to receive file descriptor for \"%s\"",
1860 lxc_cmd_str(LXC_CMD_GET_CGROUP2_FD));
1861
1862 fd = PTR_TO_INT(cmd.rsp.data);
1863 if (fd < 0)
1864 return sysdebug_set(fd, "Received invalid file descriptor for \"%s\"",
1865 lxc_cmd_str(LXC_CMD_GET_CGROUP2_FD));
1866 return fd;
1867 }
1868
1869 static int __lxc_cmd_get_cgroup2_fd_callback(int fd, struct lxc_cmd_req *req,
1870 struct lxc_handler *handler,
1871 struct lxc_async_descr *descr,
1872 bool limiting_cgroup)
1873 {
1874 struct lxc_cmd_rsp rsp = {
1875 .ret = -EINVAL,
1876 };
1877 struct cgroup_ops *ops = handler->cgroup_ops;
1878 int send_fd;
1879
1880 if (!pure_unified_layout(ops) || !ops->unified)
1881 return lxc_cmd_rsp_send_reap(fd, &rsp);
1882
1883 send_fd = limiting_cgroup ? ops->unified->dfd_lim
1884 : ops->unified->dfd_con;
1885
1886 if (send_fd < 0) {
1887 rsp.ret = -EBADF;
1888 return lxc_cmd_rsp_send_reap(fd, &rsp);
1889 }
1890
1891 rsp.ret = 0;
1892 return rsp_one_fd_reap(fd, send_fd, &rsp);
1893 }
1894
1895 static int lxc_cmd_get_cgroup2_fd_callback(int fd, struct lxc_cmd_req *req,
1896 struct lxc_handler *handler,
1897 struct lxc_async_descr *descr)
1898 {
1899 return __lxc_cmd_get_cgroup2_fd_callback(fd, req, handler, descr, false);
1900 }
1901
1902 static int lxc_cmd_get_limit_cgroup2_fd_callback(int fd, struct lxc_cmd_req *req,
1903 struct lxc_handler *handler,
1904 struct lxc_async_descr *descr)
1905 {
1906 return __lxc_cmd_get_cgroup2_fd_callback(fd, req, handler, descr, true);
1907 }
1908
1909 static int lxc_cmd_rsp_send_enosys(int fd, int id)
1910 {
1911 struct lxc_cmd_rsp rsp = {
1912 .ret = -ENOSYS,
1913 };
1914
1915 __lxc_cmd_rsp_send(fd, &rsp);
1916 return syserror_set(-ENOSYS, "Invalid command id %d", id);
1917 }
1918
1919 static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
1920 struct lxc_handler *handler,
1921 struct lxc_async_descr *descr)
1922 {
1923 typedef int (*callback)(int, struct lxc_cmd_req *, struct lxc_handler *,
1924 struct lxc_async_descr *);
1925
1926 callback cb[LXC_CMD_MAX] = {
1927 [LXC_CMD_GET_TTY_FD] = lxc_cmd_get_tty_fd_callback,
1928 [LXC_CMD_TERMINAL_WINCH] = lxc_cmd_terminal_winch_callback,
1929 [LXC_CMD_STOP] = lxc_cmd_stop_callback,
1930 [LXC_CMD_GET_STATE] = lxc_cmd_get_state_callback,
1931 [LXC_CMD_GET_INIT_PID] = lxc_cmd_get_init_pid_callback,
1932 [LXC_CMD_GET_CLONE_FLAGS] = lxc_cmd_get_clone_flags_callback,
1933 [LXC_CMD_GET_CGROUP] = lxc_cmd_get_cgroup_callback,
1934 [LXC_CMD_GET_CONFIG_ITEM] = lxc_cmd_get_config_item_callback,
1935 [LXC_CMD_GET_NAME] = lxc_cmd_get_name_callback,
1936 [LXC_CMD_GET_LXCPATH] = lxc_cmd_get_lxcpath_callback,
1937 [LXC_CMD_ADD_STATE_CLIENT] = lxc_cmd_add_state_client_callback,
1938 [LXC_CMD_CONSOLE_LOG] = lxc_cmd_console_log_callback,
1939 [LXC_CMD_SERVE_STATE_CLIENTS] = lxc_cmd_serve_state_clients_callback,
1940 [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER] = lxc_cmd_seccomp_notify_add_listener_callback,
1941 [LXC_CMD_ADD_BPF_DEVICE_CGROUP] = lxc_cmd_add_bpf_device_cgroup_callback,
1942 [LXC_CMD_FREEZE] = lxc_cmd_freeze_callback,
1943 [LXC_CMD_UNFREEZE] = lxc_cmd_unfreeze_callback,
1944 [LXC_CMD_GET_CGROUP2_FD] = lxc_cmd_get_cgroup2_fd_callback,
1945 [LXC_CMD_GET_INIT_PIDFD] = lxc_cmd_get_init_pidfd_callback,
1946 [LXC_CMD_GET_LIMIT_CGROUP] = lxc_cmd_get_limit_cgroup_callback,
1947 [LXC_CMD_GET_LIMIT_CGROUP2_FD] = lxc_cmd_get_limit_cgroup2_fd_callback,
1948 [LXC_CMD_GET_DEVPTS_FD] = lxc_cmd_get_devpts_fd_callback,
1949 [LXC_CMD_GET_SECCOMP_NOTIFY_FD] = lxc_cmd_get_seccomp_notify_fd_callback,
1950 [LXC_CMD_GET_CGROUP_CTX] = lxc_cmd_get_cgroup_ctx_callback,
1951 [LXC_CMD_GET_CGROUP_FD] = lxc_cmd_get_cgroup_fd_callback,
1952 [LXC_CMD_GET_LIMIT_CGROUP_FD] = lxc_cmd_get_limit_cgroup_fd_callback,
1953 [LXC_CMD_GET_SYSTEMD_SCOPE] = lxc_cmd_get_systemd_scope_callback,
1954 };
1955
1956 if (req->cmd >= LXC_CMD_MAX)
1957 return lxc_cmd_rsp_send_enosys(fd, req->cmd);
1958
1959 return cb[req->cmd](fd, req, handler, descr);
1960 }
1961
1962 static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler,
1963 const lxc_cmd_t cmd)
1964 {
1965 if (cmd == LXC_CMD_ADD_STATE_CLIENT) {
1966 struct lxc_state_client *client, *nclient;
1967
1968 list_for_each_entry_safe(client, nclient, &handler->conf->state_clients, head) {
1969 if (client->clientfd != fd)
1970 continue;
1971
1972 list_del(&client->head);
1973 free(client);
1974
1975 /*
1976 * No need to walk the whole list. If we found the state
1977 * client fd there can't be a second one.
1978 */
1979 TRACE("Found state client fd %d in state client list for command \"%s\"", fd, lxc_cmd_str(cmd));
1980 break;
1981 }
1982
1983 /*
1984 * We didn't add the state client to the list. Either because
1985 * we failed to allocate memory (unlikely) or because the state
1986 * was already reached by the time we were ready to add it. So
1987 * fallthrough and clean it up.
1988 */
1989 TRACE("Deleted state client fd %d for command \"%s\"", fd, lxc_cmd_str(cmd));
1990 }
1991
1992 /*
1993 * We're not closing the client fd here. They will instead be notified
1994 * from the mainloop when it calls the cleanup handler. This will cause
1995 * a slight delay but is semantically cleaner then what we used to do.
1996 */
1997 }
1998
1999 static int lxc_cmd_cleanup_handler(int fd, void *data)
2000 {
2001 struct lxc_handler *handler = data;
2002
2003 lxc_terminal_free(handler->conf, fd);
2004 close(fd);
2005 TRACE("Closing client fd %d for \"%s\"", fd, __FUNCTION__);
2006 return 0;
2007
2008 }
2009
2010 static int lxc_cmd_handler(int fd, uint32_t events, void *data,
2011 struct lxc_async_descr *descr)
2012 {
2013 __do_free void *reqdata = NULL;
2014 int ret;
2015 struct lxc_cmd_req req;
2016 struct lxc_handler *handler = data;
2017
2018 ret = lxc_abstract_unix_rcv_credential(fd, &req, sizeof(req));
2019 if (ret < 0) {
2020 SYSERROR("Failed to receive data on command socket for command \"%s\"", lxc_cmd_str(req.cmd));
2021
2022 if (errno == EACCES) {
2023 /* We don't care for the peer, just send and close. */
2024 struct lxc_cmd_rsp rsp = {
2025 .ret = -EPERM,
2026 };
2027
2028 __lxc_cmd_rsp_send(fd, &rsp);
2029 }
2030
2031 goto out;
2032 }
2033
2034 if (ret == 0)
2035 goto out;
2036
2037 if (ret != sizeof(req)) {
2038 WARN("Failed to receive full command request. Ignoring request for \"%s\"", lxc_cmd_str(req.cmd));
2039 goto out;
2040 }
2041
2042 if ((req.datalen > LXC_CMD_DATA_MAX) && (req.cmd != LXC_CMD_CONSOLE_LOG)) {
2043 ERROR("Received command data length %d is too large for command \"%s\"", req.datalen, lxc_cmd_str(req.cmd));
2044 goto out;
2045 }
2046
2047 if (req.datalen > 0) {
2048 reqdata = must_realloc(NULL, req.datalen);
2049 ret = lxc_recv_nointr(fd, reqdata, req.datalen, 0);
2050 if (ret != req.datalen) {
2051 WARN("Failed to receive full command request. Ignoring request for \"%s\"", lxc_cmd_str(req.cmd));
2052 goto out;
2053 }
2054
2055 req.data = reqdata;
2056 }
2057
2058 ret = lxc_cmd_process(fd, &req, handler, descr);
2059 if (ret < 0) {
2060 DEBUG("Failed to process command %s; cleaning up client fd %d", lxc_cmd_str(req.cmd), fd);
2061 goto out;
2062 }
2063
2064 if (ret == LXC_CMD_REAP_CLIENT_FD) {
2065 TRACE("Processed command %s; cleaning up client fd %d", lxc_cmd_str(req.cmd), fd);
2066 goto out;
2067 }
2068
2069 TRACE("Processed command %s; keeping client fd %d", lxc_cmd_str(req.cmd), fd);
2070 return LXC_MAINLOOP_CONTINUE;
2071
2072 out:
2073 lxc_cmd_fd_cleanup(fd, handler, req.cmd);
2074 return LXC_MAINLOOP_DISARM;
2075 }
2076
2077 static int lxc_cmd_accept(int fd, uint32_t events, void *data,
2078 struct lxc_async_descr *descr)
2079 {
2080 __do_close int connection = -EBADF;
2081 int opt = 1, ret = -1;
2082
2083 connection = accept4(fd, NULL, 0, SOCK_CLOEXEC);
2084 if (connection < 0)
2085 return log_error_errno(LXC_MAINLOOP_ERROR, errno, "Failed to accept connection to run command");
2086
2087 ret = setsockopt(connection, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt));
2088 if (ret < 0)
2089 return log_error_errno(ret, errno, "Failed to enable necessary credentials on command socket");
2090
2091 ret = lxc_mainloop_add_oneshot_handler(descr, connection,
2092 lxc_cmd_handler,
2093 lxc_cmd_cleanup_handler,
2094 data, "lxc_cmd_handler");
2095 if (ret)
2096 return log_error(ret, "Failed to add command handler");
2097
2098 TRACE("Accepted new client as fd %d on command server fd %d", connection, fd);
2099 move_fd(connection);
2100 return ret;
2101 }
2102
2103 int lxc_server_init(const char *name, const char *lxcpath, const char *suffix)
2104 {
2105 __do_close int fd = -EBADF;
2106 int ret;
2107 char path[LXC_AUDS_ADDR_LEN] = {0};
2108
2109 ret = lxc_make_abstract_socket_name(path, sizeof(path), name, lxcpath, NULL, suffix);
2110 if (ret < 0)
2111 return -1;
2112
2113 fd = lxc_abstract_unix_open(path, SOCK_STREAM, 0);
2114 if (fd < 0) {
2115 if (errno == EADDRINUSE)
2116 ERROR("Container \"%s\" appears to be already running", name);
2117
2118 return log_error_errno(-1, errno, "Failed to create command socket %s", &path[1]);
2119 }
2120
2121 return log_trace(move_fd(fd), "Created abstract unix socket \"%s\"", &path[1]);
2122 }
2123
2124 int lxc_cmd_mainloop_add(const char *name, struct lxc_async_descr *descr,
2125 struct lxc_handler *handler)
2126 {
2127 int ret;
2128
2129 ret = lxc_mainloop_add_handler(descr, handler->conf->maincmd_fd,
2130 lxc_cmd_accept,
2131 default_cleanup_handler,
2132 handler, "lxc_cmd_accept");
2133 if (ret < 0)
2134 return log_error(ret, "Failed to add handler for command socket fd %d", handler->conf->maincmd_fd);
2135
2136 return ret;
2137 }