Commit 37ea6ed0 authored by Andrei Vagin's avatar Andrei Vagin

kerndat: check the SIOCGSKNS ioctl

This ioctl is called for a socket and returns a file descriptor
for network namespace where a socket has been created.
Acked-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 7a6a42d0
...@@ -1062,6 +1062,17 @@ static int check_can_map_vdso(void) ...@@ -1062,6 +1062,17 @@ static int check_can_map_vdso(void)
return -1; return -1;
} }
static int check_sk_netns(void)
{
if (kerndat_socket_netns() < 0)
return -1;
if (!kdat.sk_ns)
return -1;
return 0;
}
static int (*chk_feature)(void); static int (*chk_feature)(void);
/* /*
...@@ -1168,6 +1179,7 @@ int cr_check(void) ...@@ -1168,6 +1179,7 @@ int cr_check(void)
ret |= check_can_map_vdso(); ret |= check_can_map_vdso();
ret |= check_uffd(); ret |= check_uffd();
ret |= check_uffd_noncoop(); ret |= check_uffd_noncoop();
ret |= check_sk_netns();
} }
/* /*
...@@ -1220,6 +1232,7 @@ static struct feature_list feature_list[] = { ...@@ -1220,6 +1232,7 @@ static struct feature_list feature_list[] = {
{ "uffd", check_uffd }, { "uffd", check_uffd },
{ "uffd-noncoop", check_uffd_noncoop }, { "uffd-noncoop", check_uffd_noncoop },
{ "can_map_vdso", check_can_map_vdso}, { "can_map_vdso", check_can_map_vdso},
{ "sk_ns", check_sk_netns },
{ NULL, NULL }, { NULL, NULL },
}; };
......
...@@ -46,6 +46,7 @@ struct kerndat_s { ...@@ -46,6 +46,7 @@ struct kerndat_s {
bool ipv6; bool ipv6;
enum loginuid_func luid; enum loginuid_func luid;
bool compat_cr; bool compat_cr;
bool sk_ns;
enum pagemap_func pmap; enum pagemap_func pmap;
unsigned int has_xtlocks; unsigned int has_xtlocks;
unsigned long mmap_min_addr; unsigned long mmap_min_addr;
......
...@@ -87,4 +87,10 @@ static inline int sk_decode_shutdown(int val) ...@@ -87,4 +87,10 @@ static inline int sk_decode_shutdown(int val)
extern int set_netns(uint32_t ns_id); extern int set_netns(uint32_t ns_id);
#ifndef SIOCGSKNS
#define SIOCGSKNS 0x894C /* get socket network namespace */
#endif
extern int kerndat_socket_netns(void);
#endif /* __CR_SOCKETS_H__ */ #endif /* __CR_SOCKETS_H__ */
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "lsm.h" #include "lsm.h"
#include "proc_parse.h" #include "proc_parse.h"
#include "sk-inet.h" #include "sk-inet.h"
#include "sockets.h"
#include <compel/plugins/std/syscall-codes.h> #include <compel/plugins/std/syscall-codes.h>
#include <compel/compel.h> #include <compel/compel.h>
#include "netfilter.h" #include "netfilter.h"
...@@ -873,6 +874,8 @@ int kerndat_init(void) ...@@ -873,6 +874,8 @@ int kerndat_init(void)
/* Depends on kerndat_vdso_fill_symtable() */ /* Depends on kerndat_vdso_fill_symtable() */
if (!ret) if (!ret)
ret = kerndat_vdso_preserves_hint(); ret = kerndat_vdso_preserves_hint();
if (!ret)
ret = kerndat_socket_netns();
kerndat_lsm(); kerndat_lsm();
kerndat_mmap_min_addr(); kerndat_mmap_min_addr();
......
...@@ -2297,6 +2297,30 @@ struct ns_id *get_socket_ns(int lfd) ...@@ -2297,6 +2297,30 @@ struct ns_id *get_socket_ns(int lfd)
return NULL; return NULL;
} }
int kerndat_socket_netns(void)
{
int sk, ns_fd;
sk = socket(AF_UNIX, SOCK_DGRAM, 0);
if (sk < 0) {
pr_perror("Unable to create socket");
return -1;
}
ns_fd = ioctl(sk, SIOCGSKNS);
if (ns_fd < 0) {
pr_warn("Unable to get a socket network namespace\n");
kdat.sk_ns = false;
close(sk);
return 0;
}
close(sk);
close(ns_fd);
kdat.sk_ns = true;
return 0;
}
static int move_to_bridge(struct external *ext, void *arg) static int move_to_bridge(struct external *ext, void *arg)
{ {
int s = *(int *)arg; int s = *(int *)arg;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment