Module: xenomai-3 Branch: wip/rtnet-fixes Commit: 98d70068cdcbbfb1791c7cd2a7f97ae8ccbe98d3 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=98d70068cdcbbfb1791c7cd2a7f97ae8ccbe98d3
Author: Philippe Gerum <r...@xenomai.org> Date: Wed Dec 20 11:45:16 2017 +0100 net/packet: ioctl: remove direct references to user memory (2) --- kernel/drivers/net/stack/packet/af_packet.c | 156 +++++++++++++++------------ 1 file changed, 86 insertions(+), 70 deletions(-) diff --git a/kernel/drivers/net/stack/packet/af_packet.c b/kernel/drivers/net/stack/packet/af_packet.c index 4fbf523..56daba8 100644 --- a/kernel/drivers/net/stack/packet/af_packet.c +++ b/kernel/drivers/net/stack/packet/af_packet.c @@ -101,45 +101,50 @@ static void rt_packet_unlock(struct rtpacket_type *pt) /*** * rt_packet_bind */ -static int rt_packet_bind(struct rtsocket *sock, const struct sockaddr *addr, - socklen_t addrlen) +static int rt_packet_bind(struct rtdm_fd *fd, struct rtsocket *sock, + const struct sockaddr *addr, socklen_t addrlen) { - struct sockaddr_ll *sll = (struct sockaddr_ll *)addr; - struct rtpacket_type *pt = &sock->prot.packet.packet_type; - int new_type; - int ret; - rtdm_lockctx_t context; - - - if ((addrlen < (int)sizeof(struct sockaddr_ll)) || - (sll->sll_family != AF_PACKET)) - return -EINVAL; - - new_type = (sll->sll_protocol != 0) ? sll->sll_protocol : sock->protocol; - - rtdm_lock_get_irqsave(&sock->param_lock, context); - - /* release existing binding */ - if (pt->type != 0) - rtdev_remove_pack(pt); - - pt->type = new_type; - sock->prot.packet.ifindex = sll->sll_ifindex; + struct sockaddr_ll _sll, *sll; + struct rtpacket_type *pt = &sock->prot.packet.packet_type; + int new_type; + int ret; + rtdm_lockctx_t context; + + if (addrlen < sizeof(struct sockaddr_ll)) + return -EINVAL; + + sll = rtnet_get_arg(fd, &_sll, addr, sizeof(_sll)); + if (IS_ERR(sll)) + return PTR_ERR(sll); + + if (sll->sll_family != AF_PACKET) + return -EINVAL; + + new_type = (sll->sll_protocol != 0) ? sll->sll_protocol : sock->protocol; + + rtdm_lock_get_irqsave(&sock->param_lock, context); + + /* release existing binding */ + if (pt->type != 0) + rtdev_remove_pack(pt); + + pt->type = new_type; + sock->prot.packet.ifindex = sll->sll_ifindex; + + /* if protocol is non-zero, register the packet type */ + if (new_type != 0) { + pt->handler = rt_packet_rcv; + pt->err_handler = NULL; + pt->trylock = rt_packet_trylock; + pt->unlock = rt_packet_unlock; + + ret = rtdev_add_pack(pt); + } else + ret = 0; + + rtdm_lock_put_irqrestore(&sock->param_lock, context); - /* if protocol is non-zero, register the packet type */ - if (new_type != 0) { - pt->handler = rt_packet_rcv; - pt->err_handler = NULL; - pt->trylock = rt_packet_trylock; - pt->unlock = rt_packet_unlock; - - ret = rtdev_add_pack(pt); - } else - ret = 0; - - rtdm_lock_put_irqrestore(&sock->param_lock, context); - - return ret; + return ret; } @@ -147,41 +152,52 @@ static int rt_packet_bind(struct rtsocket *sock, const struct sockaddr *addr, /*** * rt_packet_getsockname */ -static int rt_packet_getsockname(struct rtsocket *sock, struct sockaddr *addr, - socklen_t *addrlen) +static int rt_packet_getsockname(struct rtdm_fd *fd, struct rtsocket *sock, + struct sockaddr *addr, socklen_t *addrlen) { - struct sockaddr_ll *sll = (struct sockaddr_ll*)addr; - struct rtnet_device *rtdev; - rtdm_lockctx_t context; - - - if (*addrlen < sizeof(struct sockaddr_ll)) - return -EINVAL; - - rtdm_lock_get_irqsave(&sock->param_lock, context); - - sll->sll_family = AF_PACKET; - sll->sll_ifindex = sock->prot.packet.ifindex; - sll->sll_protocol = sock->protocol; - - rtdm_lock_put_irqrestore(&sock->param_lock, context); - - rtdev = rtdev_get_by_index(sll->sll_ifindex); - if (rtdev != NULL) { - sll->sll_hatype = rtdev->type; - sll->sll_halen = rtdev->addr_len; - - memcpy(sll->sll_addr, rtdev->dev_addr, rtdev->addr_len); + struct sockaddr_ll _sll, *sll; + struct rtnet_device *rtdev; + rtdm_lockctx_t context; + socklen_t _namelen, *namelen; + int ret; + + namelen = rtnet_get_arg(fd, &_namelen, addrlen, sizeof(_namelen)); + if (IS_ERR(namelen)) + return PTR_ERR(namelen); + + if (*namelen < sizeof(struct sockaddr_ll)) + return -EINVAL; + + sll = rtnet_get_arg(fd, &_sll, addr, sizeof(_sll)); + if (IS_ERR(sll)) + return PTR_ERR(sll); + + rtdm_lock_get_irqsave(&sock->param_lock, context); + + sll->sll_family = AF_PACKET; + sll->sll_ifindex = sock->prot.packet.ifindex; + sll->sll_protocol = sock->protocol; + + rtdm_lock_put_irqrestore(&sock->param_lock, context); + + rtdev = rtdev_get_by_index(sll->sll_ifindex); + if (rtdev != NULL) { + sll->sll_hatype = rtdev->type; + sll->sll_halen = rtdev->addr_len; + memcpy(sll->sll_addr, rtdev->dev_addr, rtdev->addr_len); + rtdev_dereference(rtdev); + } else { + sll->sll_hatype = 0; + sll->sll_halen = 0; + } - rtdev_dereference(rtdev); - } else { - sll->sll_hatype = 0; - sll->sll_halen = 0; - } + *namelen = sizeof(struct sockaddr_ll); - *addrlen = sizeof(struct sockaddr_ll); + ret = rtnet_put_arg(fd, addr, sll, sizeof(*sll)); + if (ret) + return ret; - return 0; + return rtnet_put_arg(fd, addrlen, namelen, sizeof(*namelen)); } @@ -269,13 +285,13 @@ static int rt_packet_ioctl(struct rtdm_fd *fd, unsigned int request, void __user setaddr = rtnet_get_arg(fd, &_setaddr, arg, sizeof(_setaddr)); if (IS_ERR(setaddr)) return PTR_ERR(setaddr); - return rt_packet_bind(sock, setaddr->addr, setaddr->addrlen); + return rt_packet_bind(fd, sock, setaddr->addr, setaddr->addrlen); case _RTIOC_GETSOCKNAME: getaddr = rtnet_get_arg(fd, &_getaddr, arg, sizeof(_getaddr)); if (IS_ERR(getaddr)) return PTR_ERR(getaddr); - return rt_packet_getsockname(sock, getaddr->addr, + return rt_packet_getsockname(fd, sock, getaddr->addr, getaddr->addrlen); default: _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git