diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2010-06-12 23:31:06 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-16 17:55:56 -0400 |
commit | b47030c71dfd6c8cd5cb6e551b6f7f7cfc96f6a6 (patch) | |
tree | f9c1e24e6e3da8ae1de1bd50be3e7ef0d81269ae /net/netlink | |
parent | 109f6e39fa07c48f580125f531f46cb7c245b528 (diff) |
af_netlink: Add needed scm_destroy after scm_send.
scm_send occasionally allocates state in the scm_cookie, so I have
modified netlink_sendmsg to guarantee that when scm_send succeeds
scm_destory will be called to free that state.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Reviewed-by: Daniel Lezcano <daniel.lezcano@free.fr>
Acked-by: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netlink')
-rw-r--r-- | net/netlink/af_netlink.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index a2eb965207d3..7aeaa83193db 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1323,19 +1323,23 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1323 | if (msg->msg_flags&MSG_OOB) | 1323 | if (msg->msg_flags&MSG_OOB) |
1324 | return -EOPNOTSUPP; | 1324 | return -EOPNOTSUPP; |
1325 | 1325 | ||
1326 | if (NULL == siocb->scm) | 1326 | if (NULL == siocb->scm) { |
1327 | siocb->scm = &scm; | 1327 | siocb->scm = &scm; |
1328 | memset(&scm, 0, sizeof(scm)); | ||
1329 | } | ||
1328 | err = scm_send(sock, msg, siocb->scm); | 1330 | err = scm_send(sock, msg, siocb->scm); |
1329 | if (err < 0) | 1331 | if (err < 0) |
1330 | return err; | 1332 | return err; |
1331 | 1333 | ||
1332 | if (msg->msg_namelen) { | 1334 | if (msg->msg_namelen) { |
1335 | err = -EINVAL; | ||
1333 | if (addr->nl_family != AF_NETLINK) | 1336 | if (addr->nl_family != AF_NETLINK) |
1334 | return -EINVAL; | 1337 | goto out; |
1335 | dst_pid = addr->nl_pid; | 1338 | dst_pid = addr->nl_pid; |
1336 | dst_group = ffs(addr->nl_groups); | 1339 | dst_group = ffs(addr->nl_groups); |
1340 | err = -EPERM; | ||
1337 | if (dst_group && !netlink_capable(sock, NL_NONROOT_SEND)) | 1341 | if (dst_group && !netlink_capable(sock, NL_NONROOT_SEND)) |
1338 | return -EPERM; | 1342 | goto out; |
1339 | } else { | 1343 | } else { |
1340 | dst_pid = nlk->dst_pid; | 1344 | dst_pid = nlk->dst_pid; |
1341 | dst_group = nlk->dst_group; | 1345 | dst_group = nlk->dst_group; |
@@ -1387,6 +1391,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1387 | err = netlink_unicast(sk, skb, dst_pid, msg->msg_flags&MSG_DONTWAIT); | 1391 | err = netlink_unicast(sk, skb, dst_pid, msg->msg_flags&MSG_DONTWAIT); |
1388 | 1392 | ||
1389 | out: | 1393 | out: |
1394 | scm_destroy(siocb->scm); | ||
1390 | return err; | 1395 | return err; |
1391 | } | 1396 | } |
1392 | 1397 | ||