criu/include/sysctl.h
Tycho Andersen f79f4546cf sysctl: move sysctl calls to usernsd
When in a userns, tasks can't write to certain sysctl files:

(00.009653)      1: Error (sysctl.c:142): Can't open sysctl kernel/hostname: Permission denied

See inline comments for details on affected namespaces.

Mostly for my own education in what is required to port something to be
userns restorable, I ported the sysctl stuff. A potential concern for this
patch is that copying structures with pointers around is kind of gory. I
did it ad-hoc here, but it may be worth inventing some mechanisms to make
it easier, although I'm not sure what exactly that would look like
(potentially re-using some of the protobuf bits; I'll investigate this more
if it looks helpful when doing the cgroup user namespaces port?).

Another issue is that there is not a great way to return non-fd stuff in
memory right now from userns_call; one of the little hacks in this code
would be "simplified" if we invented a way to do this.

v2: coalesce the individual struct sysctl_req requests into one big
    sysctl_userns_req that is in a contiguous region of memory so that we
    can pass it via userns_call. Hopefully nobody finds my little ascii
    diagram too offensive :)
v3: use the fork/setns trick to change the syctl values in the right ns for
    IPC/UTS nses; see inline comment for details
v4: only use sysctl_userns_req when actually doing a userns_call.

Signed-off-by: Tycho Andersen <tycho.andersen@canonical.com>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
2015-10-05 13:16:14 +03:00

39 lines
887 B
C

#ifndef __CR_SYSCTL_H__
#define __CR_SYSCTL_H__
struct sysctl_req {
char *name;
void *arg;
int type;
int flags;
};
extern int sysctl_op(struct sysctl_req *req, size_t nr_req, int op, unsigned int ns);
enum {
CTL_READ,
CTL_WRITE,
};
#define CTL_SHIFT 4 /* Up to 16 types */
#define CTL_U32 1 /* Single u32 */
#define CTL_U64 2 /* Single u64 */
#define __CTL_U32A 3 /* Array of u32 */
#define __CTL_U64A 4 /* Array of u64 */
#define __CTL_STR 5 /* String */
#define CTL_32 6 /* Single s32 */
#define CTL_U32A(n) (__CTL_U32A | ((n) << CTL_SHIFT))
#define CTL_U64A(n) (__CTL_U64A | ((n) << CTL_SHIFT))
#define CTL_STR(len) (__CTL_STR | ((len) << CTL_SHIFT))
#define CTL_LEN(t) ((t) >> CTL_SHIFT)
#define CTL_TYPE(t) ((t) & ((1 << CTL_SHIFT) - 1))
/*
* Some entries might be missing mark them as optional.
*/
#define CTL_FLAGS_OPTIONAL 1
#endif /* __CR_SYSCTL_H__ */