2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-25 03:18:36 +00:00
criu/include/namespaces.h

111 lines
3.1 KiB
C
Raw Permalink Normal View History

#ifndef __CR_NS_H__
#define __CR_NS_H__
#include "files.h"
struct ns_desc {
unsigned int cflag;
char *str;
size_t len;
};
struct ns_id {
unsigned int kid;
unsigned int id;
pid_t pid;
struct ns_desc *nd;
struct ns_id *next;
/*
* For mount namespaces on restore -- indicates that
* the namespace in question is created (all mounts
* are mounted) and other tasks may do setns on it
* and proceed.
*/
futex_t ns_created;
union {
struct {
struct mount_info *mntinfo_list;
struct mount_info *mntinfo_tree;
} mnt;
struct {
int nlsk; /* for sockets collection */
int seqsk; /* to talk to parasite daemons */
} net;
};
};
extern struct ns_id *ns_ids;
#define NS_DESC_ENTRY(_cflag, _str) \
{ \
.cflag = _cflag, \
.str = _str, \
.len = sizeof(_str) - 1, \
}
extern bool check_ns_proc(struct fd_link *link);
extern struct ns_desc pid_ns_desc;
extern struct ns_desc user_ns_desc;
extern unsigned long root_ns_mask;
extern const struct fdtype_ops nsfile_dump_ops;
extern struct collect_image_info nsfile_cinfo;
extern int walk_namespaces(struct ns_desc *nd, int (*cb)(struct ns_id *, void *), void *oarg);
extern int collect_namespaces(bool for_dump);
extern int collect_mnt_namespaces(bool for_dump);
extern int dump_mnt_namespaces(void);
extern int dump_namespaces(struct pstree_item *item, unsigned int ns_flags);
extern int prepare_namespace(struct pstree_item *item, unsigned long clone_flags);
extern int try_show_namespaces(int pid);
extern int switch_ns(int pid, struct ns_desc *nd, int *rst);
extern int restore_ns(int rst, struct ns_desc *nd);
extern int dump_task_ns_ids(struct pstree_item *);
extern int predump_task_ns_ids(struct pstree_item *);
extern struct ns_id *rst_new_ns_id(unsigned int id, pid_t pid, struct ns_desc *nd);
extern int rst_add_ns_id(unsigned int id, pid_t pid, struct ns_desc *nd);
extern struct ns_id *lookup_ns_by_id(unsigned int id, struct ns_desc *nd);
extern int collect_user_namespaces(bool for_dump);
extern int prepare_userns(struct pstree_item *item);
usernsd: The way to restore priviledged stuff in userns We have collected a good set of calls that cannot be done inside user namespaces, but we need to [1]. Some of them has already being addressed, like prctl mm bits restore, but some are not. I'm pretty sceptical about the ability to relax the security checks on quite a lot of them (e.g. open-by-handle is indeed a very dangerous operation if allowed to unpriviledged user), so we need some way to call those things even in user namespaces. The good news about it its that all the calls I've found operate on file descriptors this way or another. So if we had a process, that lived outside of user namespace, we could ask one to do the high priority operation we need and exchange the affected file descriptor via unix socket. So the usernsd is the one doing exactly this. It starts before we create the user namespace and accepts requests via unix socket. Clients (the processes we restore) send him the functions they want to call, the descriptor they want to operate on and the arguments blob. Optionally, they can request some file descriptor back after the call. In non usernamespace case the daemon is not started and the calls are done right in the requestor's process environment. In the next patch there's an example of how to use this daemon to do the priviledged SO_SNDBUFFORCE/_RCVBUFFORCE sockopt on a socket. [1] http://criu.org/UserNamespace Signed-off-by: Pavel Emelyanov <xemul@parallels.com> Acked-by: Andrew Vagin <avagin@openvz.org>
2015-02-13 16:05:24 +04:00
extern int start_usernsd(void);
extern int stop_usernsd(void);
extern int userns_uid(int uid);
extern int userns_gid(int gid);
extern int dump_user_ns(pid_t pid, int ns_id);
extern void free_userns_maps(void);
usernsd: The way to restore priviledged stuff in userns We have collected a good set of calls that cannot be done inside user namespaces, but we need to [1]. Some of them has already being addressed, like prctl mm bits restore, but some are not. I'm pretty sceptical about the ability to relax the security checks on quite a lot of them (e.g. open-by-handle is indeed a very dangerous operation if allowed to unpriviledged user), so we need some way to call those things even in user namespaces. The good news about it its that all the calls I've found operate on file descriptors this way or another. So if we had a process, that lived outside of user namespace, we could ask one to do the high priority operation we need and exchange the affected file descriptor via unix socket. So the usernsd is the one doing exactly this. It starts before we create the user namespace and accepts requests via unix socket. Clients (the processes we restore) send him the functions they want to call, the descriptor they want to operate on and the arguments blob. Optionally, they can request some file descriptor back after the call. In non usernamespace case the daemon is not started and the calls are done right in the requestor's process environment. In the next patch there's an example of how to use this daemon to do the priviledged SO_SNDBUFFORCE/_RCVBUFFORCE sockopt on a socket. [1] http://criu.org/UserNamespace Signed-off-by: Pavel Emelyanov <xemul@parallels.com> Acked-by: Andrew Vagin <avagin@openvz.org>
2015-02-13 16:05:24 +04:00
typedef int (*uns_call_t)(void *arg, int fd);
/*
* Async call -- The call is guaranteed to be done till the
* CR_STATE_COMPLETE happens. The function may return even
* before the call starts.
* W/o flag the call is synchronous -- this function returns
* strictly after the call finishes.
*/
#define UNS_ASYNC 0x1
/*
* The call returns an FD which should be sent back. Conflicts
* with UNS_ASYNC.
*/
#define UNS_FDOUT 0x2
/*
* When we're restoring inside user namespace, some things are
* not allowed to be done there due to insufficient capabilities.
* If the operation in question can be offloaded to another process,
* this call allows to do that.
*
* In case we're not in userns, just call the callback immediatelly
* in the context of calling task.
*/
int userns_call(uns_call_t call, int flags,
void *arg, size_t arg_size, int fd);
#endif /* __CR_NS_H__ */