Commit 0286752b authored by Andrey Vagin's avatar Andrey Vagin Committed by Andrei Vagin

kerndat: check the SIOCUNIXFILE ioctl for unix sockets

This ioctl opens a file to which a socket is bound and
returns a file descriptor. This file descriptor can be used to get
mnt_id and a file path.
Acked-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 8ebf1c48
......@@ -1073,6 +1073,14 @@ static int check_sk_netns(void)
return 0;
}
static int check_sk_unix_file(void)
{
if (!kdat.sk_unix_file)
return -1;
return 0;
}
static int (*chk_feature)(void);
/*
......@@ -1267,6 +1275,7 @@ static struct feature_list feature_list[] = {
{ "uffd-noncoop", check_uffd_noncoop },
{ "can_map_vdso", check_can_map_vdso},
{ "sk_ns", check_sk_netns },
{ "sk_unix_file", check_sk_unix_file },
{ "nsid", check_nsid },
{ "link_nsid", check_link_nsid},
{ NULL, NULL },
......
......@@ -48,6 +48,7 @@ struct kerndat_s {
enum loginuid_func luid;
bool compat_cr;
bool sk_ns;
bool sk_unix_file;
bool tun_ns;
enum pagemap_func pmap;
unsigned int has_xtlocks;
......
......@@ -93,5 +93,6 @@ extern int set_netns(uint32_t ns_id);
#endif
extern int kerndat_socket_netns(void);
extern int kerndat_socket_unix_file(void);
#endif /* __CR_SOCKETS_H__ */
......@@ -1003,6 +1003,8 @@ int kerndat_init(void)
ret = kerndat_socket_netns();
if (!ret)
ret = kerndat_tun_netns();
if (!ret)
ret = kerndat_socket_unix_file();
if (!ret)
ret = kerndat_nsid();
if (!ret)
......
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <libnl3/netlink/msg.h>
......@@ -29,6 +30,7 @@
#include "external.h"
#include "crtools.h"
#include "fdstore.h"
#include "kerndat.h"
#include "protobuf.h"
#include "images/sk-unix.pb-c.h"
......@@ -196,6 +198,34 @@ static int write_unix_entry(struct unix_sk_desc *sk)
return ret;
}
#ifndef SIOCUNIXFILE
#define SIOCUNIXFILE (SIOCPROTOPRIVATE + 0) /* open a socket file with O_PATH */
#endif
int kerndat_socket_unix_file(void)
{
int sk, fd;
sk = socket(AF_UNIX, SOCK_DGRAM, 0);
if (sk < 0) {
pr_perror("Unable to create socket");
return -1;
}
fd = ioctl(sk, SIOCUNIXFILE);
if (fd < 0 && errno != ENOENT) {
pr_warn("Unable to open a socket file: %m\n");
kdat.sk_unix_file = false;
close(sk);
return 0;
}
close(sk);
close(fd);
kdat.sk_unix_file = true;
return 0;
}
static int resolve_rel_name(struct unix_sk_desc *sk, const struct fd_parms *p)
{
rel_name_desc_t *rel_name = sk->rel_name;
......
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