Module: xenomai-3 Branch: wip/rtnet-fixes Commit: 3811a60a333a76756dd6aa2cb1e649b721fb8191 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=3811a60a333a76756dd6aa2cb1e649b721fb8191
Author: Philippe Gerum <[email protected]> Date: Tue Dec 5 18:56:12 2017 +0100 net/packet: sendmsg: remove direct references to user memory --- kernel/drivers/net/stack/packet/af_packet.c | 55 +++++++++++++++++++-------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/kernel/drivers/net/stack/packet/af_packet.c b/kernel/drivers/net/stack/packet/af_packet.c index f248239..bf5294f 100644 --- a/kernel/drivers/net/stack/packet/af_packet.c +++ b/kernel/drivers/net/stack/packet/af_packet.c @@ -404,43 +404,64 @@ static ssize_t rt_packet_sendmsg(struct rtdm_fd *fd, const struct user_msghdr *msg, int msg_flags) { struct rtsocket *sock = rtdm_fd_to_private(fd); - size_t len = rt_iovec_len(msg->msg_iov, msg->msg_iovlen); - struct sockaddr_ll *sll = (struct sockaddr_ll*)msg->msg_name; + size_t len; + struct sockaddr_ll _sll, *sll; struct rtnet_device *rtdev; struct rtskb *rtskb; unsigned short proto; unsigned char *addr; int ifindex; - int ret = 0; - + ssize_t ret; + struct user_msghdr _msg; + struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov; if (msg_flags & MSG_OOB) /* Mirror BSD error message compatibility */ return -EOPNOTSUPP; if (msg_flags & ~MSG_DONTWAIT) return -EINVAL; - if (sll == NULL) { + msg = rtnet_get_arg(fd, &_msg, msg, sizeof(*msg)); + if (IS_ERR(msg)) + return PTR_ERR(msg); + + if (msg->msg_iovlen < 0) + return -EINVAL; + + if (msg->msg_iovlen == 0) + return 0; + + ret = rtdm_get_iovec(fd, &iov, msg, iov_fast); + if (ret) + return ret; + + if (msg->msg_name == NULL) { /* Note: We do not care about races with rt_packet_bind here - the user has to do so. */ ifindex = sock->prot.packet.ifindex; proto = sock->prot.packet.packet_type.type; addr = NULL; + sll = NULL; } else { - if ((msg->msg_namelen < sizeof(struct sockaddr_ll)) || - (msg->msg_namelen < - (sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) || - ((sll->sll_family != AF_PACKET) && - (sll->sll_family != AF_UNSPEC))) - return -EINVAL; - - ifindex = sll->sll_ifindex; - proto = sll->sll_protocol; - addr = sll->sll_addr; + sll = rtnet_get_arg(fd, &_sll, msg->msg_name, sizeof(_sll)); + if (IS_ERR(sll)) + return PTR_ERR(sll); + + if ((msg->msg_namelen < sizeof(struct sockaddr_ll)) || + (msg->msg_namelen < + (sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) || + ((sll->sll_family != AF_PACKET) && + (sll->sll_family != AF_UNSPEC))) + return -EINVAL; + + ifindex = sll->sll_ifindex; + proto = sll->sll_protocol; + addr = sll->sll_addr; } if ((rtdev = rtdev_get_by_index(ifindex)) == NULL) return -ENODEV; + len = rt_iovec_len(iov, msg->msg_iovlen); rtskb = alloc_rtskb(rtdev->hard_header_len + len, &sock->skb_pool); if (rtskb == NULL) { ret = -ENOBUFS; @@ -480,7 +501,7 @@ rt_packet_sendmsg(struct rtdm_fd *fd, const struct user_msghdr *msg, int msg_fla goto err; } - rt_memcpy_fromkerneliovec(rtskb_put(rtskb, len), msg->msg_iov, len); + ret = rtnet_read_from_iov(fd, iov, msg->msg_iovlen, rtskb_put(rtskb, len), len); if ((rtdev->flags & IFF_UP) != 0) { if ((ret = rtdev_xmit(rtskb)) == 0) @@ -492,6 +513,8 @@ rt_packet_sendmsg(struct rtdm_fd *fd, const struct user_msghdr *msg, int msg_fla out: rtdev_dereference(rtdev); + rtdm_drop_iovec(iov, iov_fast); + return ret; err: _______________________________________________ Xenomai-git mailing list [email protected] https://xenomai.org/mailman/listinfo/xenomai-git
