Commit fb5a5671 authored by Pavel Emelyanov's avatar Pavel Emelyanov

sock: Do strict socket family checks when looking up collected socket

We hash socket with inode and family, but search only by inode. Well,
yes, family should match, since all sockets are in one sockfs in kernel,
but let's make sure _we_ did things right by checking the family as well.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent da2ebabf
...@@ -47,9 +47,10 @@ extern char *sktype2s(u32 t); ...@@ -47,9 +47,10 @@ extern char *sktype2s(u32 t);
extern char *skproto2s(u32 p); extern char *skproto2s(u32 p);
extern char *skstate2s(u32 state); extern char *skstate2s(u32 state);
extern struct socket_desc *lookup_socket(int ino); extern struct socket_desc *lookup_socket(int ino, int family);
extern int dump_one_inet(struct fd_parms *p, int lfd, const struct cr_fdset *set); extern int dump_one_inet(struct fd_parms *p, int lfd, const struct cr_fdset *set);
extern int dump_one_inet6(struct fd_parms *p, int lfd, const struct cr_fdset *set);
extern int dump_one_unix(struct fd_parms *p, int lfd, const struct cr_fdset *set); extern int dump_one_unix(struct fd_parms *p, int lfd, const struct cr_fdset *set);
extern int inet_collect_one(struct nlmsghdr *h, int family, int type, int proto); extern int inet_collect_one(struct nlmsghdr *h, int family, int type, int proto);
......
...@@ -168,14 +168,14 @@ err: ...@@ -168,14 +168,14 @@ err:
return NULL; return NULL;
} }
static int dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p) static int do_dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p, int family)
{ {
struct inet_sk_desc *sk; struct inet_sk_desc *sk;
InetSkEntry ie = INET_SK_ENTRY__INIT; InetSkEntry ie = INET_SK_ENTRY__INIT;
SkOptsEntry skopts = SK_OPTS_ENTRY__INIT; SkOptsEntry skopts = SK_OPTS_ENTRY__INIT;
int ret = -1; int ret = -1;
sk = (struct inet_sk_desc *)lookup_socket(p->stat.st_ino); sk = (struct inet_sk_desc *)lookup_socket(p->stat.st_ino, family);
if (!sk) { if (!sk) {
sk = gen_uncon_sk(lfd, p); sk = gen_uncon_sk(lfd, p);
if (!sk) if (!sk)
...@@ -189,7 +189,7 @@ static int dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p) ...@@ -189,7 +189,7 @@ static int dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p)
ie.id = id; ie.id = id;
ie.ino = sk->sd.ino; ie.ino = sk->sd.ino;
ie.family = sk->sd.family; ie.family = family;
ie.type = sk->type; ie.type = sk->type;
ie.proto = sk->proto; ie.proto = sk->proto;
ie.state = sk->state; ie.state = sk->state;
...@@ -247,6 +247,11 @@ err: ...@@ -247,6 +247,11 @@ err:
return ret; return ret;
} }
static int dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p)
{
return do_dump_one_inet_fd(lfd, id, p, PF_INET);
}
static const struct fdtype_ops inet_dump_ops = { static const struct fdtype_ops inet_dump_ops = {
.type = FD_TYPES__INETSK, .type = FD_TYPES__INETSK,
.dump = dump_one_inet_fd, .dump = dump_one_inet_fd,
...@@ -257,6 +262,21 @@ int dump_one_inet(struct fd_parms *p, int lfd, const struct cr_fdset *set) ...@@ -257,6 +262,21 @@ int dump_one_inet(struct fd_parms *p, int lfd, const struct cr_fdset *set)
return do_dump_gen_file(p, lfd, &inet_dump_ops, set); return do_dump_gen_file(p, lfd, &inet_dump_ops, set);
} }
static int dump_one_inet6_fd(int lfd, u32 id, const struct fd_parms *p)
{
return do_dump_one_inet_fd(lfd, id, p, PF_INET6);
}
static const struct fdtype_ops inet6_dump_ops = {
.type = FD_TYPES__INETSK,
.dump = dump_one_inet6_fd,
};
int dump_one_inet6(struct fd_parms *p, int lfd, const struct cr_fdset *set)
{
return do_dump_gen_file(p, lfd, &inet6_dump_ops, set);
}
int inet_collect_one(struct nlmsghdr *h, int family, int type, int proto) int inet_collect_one(struct nlmsghdr *h, int family, int type, int proto)
{ {
struct inet_sk_desc *d; struct inet_sk_desc *d;
......
...@@ -39,7 +39,7 @@ static int dump_one_packet_fd(int lfd, u32 id, const struct fd_parms *p) ...@@ -39,7 +39,7 @@ static int dump_one_packet_fd(int lfd, u32 id, const struct fd_parms *p)
SkOptsEntry skopts = SK_OPTS_ENTRY__INIT; SkOptsEntry skopts = SK_OPTS_ENTRY__INIT;
struct packet_sock_desc *sd; struct packet_sock_desc *sd;
sd = (struct packet_sock_desc *)lookup_socket(p->stat.st_ino); sd = (struct packet_sock_desc *)lookup_socket(p->stat.st_ino, PF_PACKET);
if (sd < 0) if (sd < 0)
return -1; return -1;
......
...@@ -115,7 +115,7 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p) ...@@ -115,7 +115,7 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
UnixSkEntry ue = UNIX_SK_ENTRY__INIT; UnixSkEntry ue = UNIX_SK_ENTRY__INIT;
SkOptsEntry skopts = SK_OPTS_ENTRY__INIT; SkOptsEntry skopts = SK_OPTS_ENTRY__INIT;
sk = (struct unix_sk_desc *)lookup_socket(p->stat.st_ino); sk = (struct unix_sk_desc *)lookup_socket(p->stat.st_ino, PF_UNIX);
if (!sk) if (!sk)
goto err; goto err;
...@@ -141,7 +141,7 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p) ...@@ -141,7 +141,7 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
if (ue.peer) { if (ue.peer) {
struct unix_sk_desc *peer; struct unix_sk_desc *peer;
peer = (struct unix_sk_desc *)lookup_socket(ue.peer); peer = (struct unix_sk_desc *)lookup_socket(ue.peer, PF_UNIX);
if (!peer) { if (!peer) {
pr_err("Unix socket %#x without peer %#x\n", pr_err("Unix socket %#x without peer %#x\n",
ue.ino, ue.peer); ue.ino, ue.peer);
......
...@@ -31,13 +31,17 @@ ...@@ -31,13 +31,17 @@
static struct socket_desc *sockets[SK_HASH_SIZE]; static struct socket_desc *sockets[SK_HASH_SIZE];
struct socket_desc *lookup_socket(int ino) struct socket_desc *lookup_socket(int ino, int family)
{ {
struct socket_desc *sd; struct socket_desc *sd;
pr_debug("\tSearching for socket %x (family %d)\n", ino, family);
for (sd = sockets[ino % SK_HASH_SIZE]; sd; sd = sd->next) for (sd = sockets[ino % SK_HASH_SIZE]; sd; sd = sd->next)
if (sd->ino == ino) if (sd->ino == ino) {
BUG_ON(sd->family != family);
return sd; return sd;
}
return NULL; return NULL;
} }
...@@ -133,8 +137,9 @@ int dump_socket(struct fd_parms *p, int lfd, const struct cr_fdset *cr_fdset) ...@@ -133,8 +137,9 @@ int dump_socket(struct fd_parms *p, int lfd, const struct cr_fdset *cr_fdset)
case AF_UNIX: case AF_UNIX:
return dump_one_unix(p, lfd, cr_fdset); return dump_one_unix(p, lfd, cr_fdset);
case AF_INET: case AF_INET:
case AF_INET6:
return dump_one_inet(p, lfd, cr_fdset); return dump_one_inet(p, lfd, cr_fdset);
case AF_INET6:
return dump_one_inet6(p, lfd, cr_fdset);
case AF_PACKET: case AF_PACKET:
return dump_one_packet_sk(p, lfd, cr_fdset); return dump_one_packet_sk(p, lfd, cr_fdset);
default: default:
......
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