aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Hartkopp <socketcan@hartkopp.net>2016-10-24 15:11:26 -0400
committerMarc Kleine-Budde <mkl@pengutronix.de>2016-10-31 15:48:19 -0400
commitdeb507f91f1adbf64317ad24ac46c56eeccfb754 (patch)
treeb8fb378600f3f87550ba29171f0993a1f10fe7b4
parent460d2830b00db407be2b72ed792eb3596f245192 (diff)
can: bcm: fix warning in bcm_connect/proc_register
Andrey Konovalov reported an issue with proc_register in bcm.c. As suggested by Cong Wang this patch adds a lock_sock() protection and a check for unsuccessful proc_create_data() in bcm_connect(). Reference: http://marc.info/?l=linux-netdev&m=147732648731237 Reported-by: Andrey Konovalov <andreyknvl@google.com> Suggested-by: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net> Acked-by: Cong Wang <xiyou.wangcong@gmail.com> Tested-by: Andrey Konovalov <andreyknvl@google.com> Cc: linux-stable <stable@vger.kernel.org> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
-rw-r--r--net/can/bcm.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 8e999ffdf28b..8af9d25ff988 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -1549,24 +1549,31 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
1549 struct sockaddr_can *addr = (struct sockaddr_can *)uaddr; 1549 struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
1550 struct sock *sk = sock->sk; 1550 struct sock *sk = sock->sk;
1551 struct bcm_sock *bo = bcm_sk(sk); 1551 struct bcm_sock *bo = bcm_sk(sk);
1552 int ret = 0;
1552 1553
1553 if (len < sizeof(*addr)) 1554 if (len < sizeof(*addr))
1554 return -EINVAL; 1555 return -EINVAL;
1555 1556
1556 if (bo->bound) 1557 lock_sock(sk);
1557 return -EISCONN; 1558
1559 if (bo->bound) {
1560 ret = -EISCONN;
1561 goto fail;
1562 }
1558 1563
1559 /* bind a device to this socket */ 1564 /* bind a device to this socket */
1560 if (addr->can_ifindex) { 1565 if (addr->can_ifindex) {
1561 struct net_device *dev; 1566 struct net_device *dev;
1562 1567
1563 dev = dev_get_by_index(&init_net, addr->can_ifindex); 1568 dev = dev_get_by_index(&init_net, addr->can_ifindex);
1564 if (!dev) 1569 if (!dev) {
1565 return -ENODEV; 1570 ret = -ENODEV;
1566 1571 goto fail;
1572 }
1567 if (dev->type != ARPHRD_CAN) { 1573 if (dev->type != ARPHRD_CAN) {
1568 dev_put(dev); 1574 dev_put(dev);
1569 return -ENODEV; 1575 ret = -ENODEV;
1576 goto fail;
1570 } 1577 }
1571 1578
1572 bo->ifindex = dev->ifindex; 1579 bo->ifindex = dev->ifindex;
@@ -1577,17 +1584,24 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
1577 bo->ifindex = 0; 1584 bo->ifindex = 0;
1578 } 1585 }
1579 1586
1580 bo->bound = 1;
1581
1582 if (proc_dir) { 1587 if (proc_dir) {
1583 /* unique socket address as filename */ 1588 /* unique socket address as filename */
1584 sprintf(bo->procname, "%lu", sock_i_ino(sk)); 1589 sprintf(bo->procname, "%lu", sock_i_ino(sk));
1585 bo->bcm_proc_read = proc_create_data(bo->procname, 0644, 1590 bo->bcm_proc_read = proc_create_data(bo->procname, 0644,
1586 proc_dir, 1591 proc_dir,
1587 &bcm_proc_fops, sk); 1592 &bcm_proc_fops, sk);
1593 if (!bo->bcm_proc_read) {
1594 ret = -ENOMEM;
1595 goto fail;
1596 }
1588 } 1597 }
1589 1598
1590 return 0; 1599 bo->bound = 1;
1600
1601fail:
1602 release_sock(sk);
1603
1604 return ret;
1591} 1605}
1592 1606
1593static int bcm_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, 1607static int bcm_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,