|
@@ -506,6 +506,7 @@ static int __unix_perm(struct sockaddr *address, int addrlen)
|
|
|
{
|
|
|
struct graphene_info *gi = get_graphene_info(current->graphene);
|
|
|
const char *path, *sun_path;
|
|
|
+ int path_len;
|
|
|
|
|
|
if (!gi->gi_unix)
|
|
|
return -EPERM;
|
|
@@ -517,7 +518,7 @@ static int __unix_perm(struct sockaddr *address, int addrlen)
|
|
|
int err;
|
|
|
|
|
|
err = kern_path_parent(path, &nd);
|
|
|
- if (!err)
|
|
|
+ if (err)
|
|
|
return err;
|
|
|
|
|
|
if (!path_equal(&gi->gi_unix->root, &nd.path)) {
|
|
@@ -527,12 +528,17 @@ static int __unix_perm(struct sockaddr *address, int addrlen)
|
|
|
|
|
|
path_put(&nd.path);
|
|
|
path = nd.last.name;
|
|
|
+ path_len = nd.last.len;
|
|
|
+ } else {
|
|
|
+ path_len = strlen(path);
|
|
|
}
|
|
|
|
|
|
if (!gi->gi_unix->prefix.len)
|
|
|
return 0;
|
|
|
|
|
|
- if (!memcmp(path, gi->gi_unix->prefix.name,
|
|
|
+ if (gi->gi_unix->prefix.len < path_len &&
|
|
|
+ !memcmp(path,
|
|
|
+ gi->gi_unix->prefix.name,
|
|
|
gi->gi_unix->prefix.len))
|
|
|
return 0;
|
|
|
|
|
@@ -554,12 +560,12 @@ static int net_cmp(int family, int addr_any, int port_any,
|
|
|
|
|
|
if (!addr_any) {
|
|
|
if (a->sin_addr.s_addr != ga->addr.sin_addr.s_addr)
|
|
|
- return -EPERM;
|
|
|
+ return 1;
|
|
|
}
|
|
|
if (!port_any) {
|
|
|
unsigned short port = ntohs(a->sin_port);
|
|
|
if (!(port >= ga->port_begin && port <= ga->port_end))
|
|
|
- return -EPERM;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
break;
|
|
@@ -571,12 +577,12 @@ static int net_cmp(int family, int addr_any, int port_any,
|
|
|
if (!addr_any) {
|
|
|
if (memcmp(&a6->sin6_addr, &ga->addr.sin6_addr,
|
|
|
sizeof(struct in6_addr)))
|
|
|
- return -EPERM;
|
|
|
+ return 1;
|
|
|
}
|
|
|
if (!port_any) {
|
|
|
unsigned short port = ntohs(a6->sin6_port);
|
|
|
if (!(port >= ga->port_begin && port <= ga->port_end))
|
|
|
- return -EPERM;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
break;
|
|
@@ -726,7 +732,7 @@ int __common_net_perm(struct graphene_info *gi, int op, struct socket *sock,
|
|
|
local_needcmp = 1;
|
|
|
|
|
|
err = sock->ops->getname(sock, local_addr, &local_addrlen, 0);
|
|
|
- if (err < 0)
|
|
|
+ if (err)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
@@ -745,18 +751,16 @@ int __common_net_perm(struct graphene_info *gi, int op, struct socket *sock,
|
|
|
continue;
|
|
|
|
|
|
if (local_needcmp) {
|
|
|
- err = net_cmp(sk->sk_family, gn->flags & LOCAL_ADDR_ANY,
|
|
|
- gn->flags & LOCAL_PORT_ANY,
|
|
|
- &gn->local, local_addr, local_addrlen);
|
|
|
- if (err < 0)
|
|
|
+ if (net_cmp(sk->sk_family, gn->flags & LOCAL_ADDR_ANY,
|
|
|
+ gn->flags & LOCAL_PORT_ANY,
|
|
|
+ &gn->local, local_addr, local_addrlen))
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
if (peer_needcmp) {
|
|
|
- err = net_cmp(sk->sk_family, gn->flags & PEER_ADDR_ANY,
|
|
|
- gn->flags & PEER_PORT_ANY,
|
|
|
- &gn->peer, peer_addr, peer_addrlen);
|
|
|
- if (err < 0)
|
|
|
+ if (net_cmp(sk->sk_family, gn->flags & PEER_ADDR_ANY,
|
|
|
+ gn->flags & PEER_PORT_ANY,
|
|
|
+ &gn->peer, peer_addr, peer_addrlen))
|
|
|
continue;
|
|
|
}
|
|
|
|
|
@@ -1119,8 +1123,10 @@ int set_graphene(struct task_struct *current_tsk,
|
|
|
int type, flags;
|
|
|
rv = copy_from_user(&ptmp, policies + i,
|
|
|
sizeof(struct graphene_user_policy));
|
|
|
- if (rv < 0)
|
|
|
+ if (rv) {
|
|
|
+ rv = -EFAULT;
|
|
|
goto err;
|
|
|
+ }
|
|
|
|
|
|
if (!ptmp.value) {
|
|
|
rv = -EINVAL;
|
|
@@ -1243,11 +1249,13 @@ int set_graphene(struct task_struct *current_tsk,
|
|
|
|
|
|
rv = copy_from_user(&np, ptmp.value,
|
|
|
sizeof(struct graphene_net_policy));
|
|
|
- if (rv < 0)
|
|
|
+ if (rv) {
|
|
|
+ rv = -EFAULT;
|
|
|
goto err;
|
|
|
+ }
|
|
|
|
|
|
rv = set_net_rule(&np, gi);
|
|
|
- if (rv < 0)
|
|
|
+ if (rv)
|
|
|
goto err;
|
|
|
|
|
|
break;
|
|
@@ -1298,7 +1306,7 @@ int set_graphene(struct task_struct *current_tsk,
|
|
|
|
|
|
if (gi->gi_unix) {
|
|
|
rv = add_graphene_unix(gi->gi_unix);
|
|
|
- if (rv < 0)
|
|
|
+ if (rv)
|
|
|
goto err;
|
|
|
}
|
|
|
|
|
@@ -1357,14 +1365,10 @@ static int do_close_sock(struct graphene_info *gi, struct socket *sock,
|
|
|
inet = inet_sk(sk);
|
|
|
if (inet->inet_dport) {
|
|
|
err = sock->ops->getname(sock, addr, &len, 1);
|
|
|
- if (err < 0)
|
|
|
- return err;
|
|
|
-
|
|
|
- err = __common_net_perm(gi, OP_CONNECT, sock, addr, len);
|
|
|
- if (err < 0)
|
|
|
+ if (err)
|
|
|
return err;
|
|
|
|
|
|
- return 0;
|
|
|
+ return __common_net_perm(gi, OP_CONNECT, sock, addr, len);
|
|
|
}
|
|
|
|
|
|
if (!inet->inet_num)
|
|
@@ -1374,7 +1378,7 @@ static int do_close_sock(struct graphene_info *gi, struct socket *sock,
|
|
|
err = __common_net_perm(gi, OP_LISTEN, sock, NULL, 0);
|
|
|
} else {
|
|
|
err = sock->ops->getname(sock, addr, &len, 0);
|
|
|
- if (err < 0)
|
|
|
+ if (err)
|
|
|
return err;
|
|
|
|
|
|
err = __common_net_perm(gi, OP_BIND, sock, addr, len);
|
|
@@ -1512,7 +1516,7 @@ static int update_graphene(struct task_struct *current_tsk,
|
|
|
}
|
|
|
if (new->gi_unix->prefix.len) {
|
|
|
int err = add_graphene_unix(new->gi_unix);
|
|
|
- if (err < 0)
|
|
|
+ if (err)
|
|
|
return err;
|
|
|
}
|
|
|
close_unix = 1;
|