From: Richard Guy Briggs <rgb(a)redhat.com>
Date: Fri, 18 Apr 2014 13:34:06 -0400
@@ -1449,6 +1453,26 @@ static int netlink_bind(struct socket *sock,
struct sockaddr *addr,
if (!nladdr->nl_groups && (nlk->groups == NULL ||
!(u32)nlk->groups[0]))
return 0;
+ if (nlk->netlink_bind && nladdr->nl_groups) {
+ int i;
+
+ for (i = 0; i < nlk->ngroups; i++) {
+ int undo;
+
+ if (!test_bit(i, (long unsigned int *)&nladdr->nl_groups))
+ continue;
+ err = nlk->netlink_bind(i);
+ if (!err)
+ continue;
+ if (!nlk->portid)
+ netlink_remove(sk);
+ for (undo = 0; undo < i; undo++)
+ if (nlk->netlink_unbind)
+ nlk->netlink_unbind(undo);
+ return err;
+ }
+ }
+
It took me a while to figure out why you need to do the netlink_remove() in
the error path.
I think it's really asking for trouble to allow the socket to have temporary
visibility if we end up signalling an error.
It seems safest if we only do the autobind/insert once we are absolutely
certain that the bind() will fully succeed. This means that you have to
do this bind validation loop before autobind/insert.
Please make this change and resubmit this series, thanks.