aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink/af_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/netlink/af_netlink.c')
-rw-r--r--net/netlink/af_netlink.c80
1 files changed, 75 insertions, 5 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 894cda0206bb..f22757a29cd0 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1360,7 +1360,74 @@ retry:
1360 return err; 1360 return err;
1361} 1361}
1362 1362
1363static inline int netlink_capable(const struct socket *sock, unsigned int flag) 1363/**
1364 * __netlink_ns_capable - General netlink message capability test
1365 * @nsp: NETLINK_CB of the socket buffer holding a netlink command from userspace.
1366 * @user_ns: The user namespace of the capability to use
1367 * @cap: The capability to use
1368 *
1369 * Test to see if the opener of the socket we received the message
1370 * from had when the netlink socket was created and the sender of the
1371 * message has has the capability @cap in the user namespace @user_ns.
1372 */
1373bool __netlink_ns_capable(const struct netlink_skb_parms *nsp,
1374 struct user_namespace *user_ns, int cap)
1375{
1376 return ((nsp->flags & NETLINK_SKB_DST) ||
1377 file_ns_capable(nsp->sk->sk_socket->file, user_ns, cap)) &&
1378 ns_capable(user_ns, cap);
1379}
1380EXPORT_SYMBOL(__netlink_ns_capable);
1381
1382/**
1383 * netlink_ns_capable - General netlink message capability test
1384 * @skb: socket buffer holding a netlink command from userspace
1385 * @user_ns: The user namespace of the capability to use
1386 * @cap: The capability to use
1387 *
1388 * Test to see if the opener of the socket we received the message
1389 * from had when the netlink socket was created and the sender of the
1390 * message has has the capability @cap in the user namespace @user_ns.
1391 */
1392bool netlink_ns_capable(const struct sk_buff *skb,
1393 struct user_namespace *user_ns, int cap)
1394{
1395 return __netlink_ns_capable(&NETLINK_CB(skb), user_ns, cap);
1396}
1397EXPORT_SYMBOL(netlink_ns_capable);
1398
1399/**
1400 * netlink_capable - Netlink global message capability test
1401 * @skb: socket buffer holding a netlink command from userspace
1402 * @cap: The capability to use
1403 *
1404 * Test to see if the opener of the socket we received the message
1405 * from had when the netlink socket was created and the sender of the
1406 * message has has the capability @cap in all user namespaces.
1407 */
1408bool netlink_capable(const struct sk_buff *skb, int cap)
1409{
1410 return netlink_ns_capable(skb, &init_user_ns, cap);
1411}
1412EXPORT_SYMBOL(netlink_capable);
1413
1414/**
1415 * netlink_net_capable - Netlink network namespace message capability test
1416 * @skb: socket buffer holding a netlink command from userspace
1417 * @cap: The capability to use
1418 *
1419 * Test to see if the opener of the socket we received the message
1420 * from had when the netlink socket was created and the sender of the
1421 * message has has the capability @cap over the network namespace of
1422 * the socket we received the message from.
1423 */
1424bool netlink_net_capable(const struct sk_buff *skb, int cap)
1425{
1426 return netlink_ns_capable(skb, sock_net(skb->sk)->user_ns, cap);
1427}
1428EXPORT_SYMBOL(netlink_net_capable);
1429
1430static inline int netlink_allowed(const struct socket *sock, unsigned int flag)
1364{ 1431{
1365 return (nl_table[sock->sk->sk_protocol].flags & flag) || 1432 return (nl_table[sock->sk->sk_protocol].flags & flag) ||
1366 ns_capable(sock_net(sock->sk)->user_ns, CAP_NET_ADMIN); 1433 ns_capable(sock_net(sock->sk)->user_ns, CAP_NET_ADMIN);
@@ -1428,7 +1495,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
1428 1495
1429 /* Only superuser is allowed to listen multicasts */ 1496 /* Only superuser is allowed to listen multicasts */
1430 if (nladdr->nl_groups) { 1497 if (nladdr->nl_groups) {
1431 if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV)) 1498 if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV))
1432 return -EPERM; 1499 return -EPERM;
1433 err = netlink_realloc_groups(sk); 1500 err = netlink_realloc_groups(sk);
1434 if (err) 1501 if (err)
@@ -1490,7 +1557,7 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
1490 return -EINVAL; 1557 return -EINVAL;
1491 1558
1492 if ((nladdr->nl_groups || nladdr->nl_pid) && 1559 if ((nladdr->nl_groups || nladdr->nl_pid) &&
1493 !netlink_capable(sock, NL_CFG_F_NONROOT_SEND)) 1560 !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
1494 return -EPERM; 1561 return -EPERM;
1495 1562
1496 if (!nlk->portid) 1563 if (!nlk->portid)
@@ -2096,7 +2163,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
2096 break; 2163 break;
2097 case NETLINK_ADD_MEMBERSHIP: 2164 case NETLINK_ADD_MEMBERSHIP:
2098 case NETLINK_DROP_MEMBERSHIP: { 2165 case NETLINK_DROP_MEMBERSHIP: {
2099 if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV)) 2166 if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV))
2100 return -EPERM; 2167 return -EPERM;
2101 err = netlink_realloc_groups(sk); 2168 err = netlink_realloc_groups(sk);
2102 if (err) 2169 if (err)
@@ -2228,6 +2295,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
2228 struct sk_buff *skb; 2295 struct sk_buff *skb;
2229 int err; 2296 int err;
2230 struct scm_cookie scm; 2297 struct scm_cookie scm;
2298 u32 netlink_skb_flags = 0;
2231 2299
2232 if (msg->msg_flags&MSG_OOB) 2300 if (msg->msg_flags&MSG_OOB)
2233 return -EOPNOTSUPP; 2301 return -EOPNOTSUPP;
@@ -2247,8 +2315,9 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
2247 dst_group = ffs(addr->nl_groups); 2315 dst_group = ffs(addr->nl_groups);
2248 err = -EPERM; 2316 err = -EPERM;
2249 if ((dst_group || dst_portid) && 2317 if ((dst_group || dst_portid) &&
2250 !netlink_capable(sock, NL_CFG_F_NONROOT_SEND)) 2318 !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
2251 goto out; 2319 goto out;
2320 netlink_skb_flags |= NETLINK_SKB_DST;
2252 } else { 2321 } else {
2253 dst_portid = nlk->dst_portid; 2322 dst_portid = nlk->dst_portid;
2254 dst_group = nlk->dst_group; 2323 dst_group = nlk->dst_group;
@@ -2278,6 +2347,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
2278 NETLINK_CB(skb).portid = nlk->portid; 2347 NETLINK_CB(skb).portid = nlk->portid;
2279 NETLINK_CB(skb).dst_group = dst_group; 2348 NETLINK_CB(skb).dst_group = dst_group;
2280 NETLINK_CB(skb).creds = siocb->scm->creds; 2349 NETLINK_CB(skb).creds = siocb->scm->creds;
2350 NETLINK_CB(skb).flags = netlink_skb_flags;
2281 2351
2282 err = -EFAULT; 2352 err = -EFAULT;
2283 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { 2353 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {