[Xenomai-git] Philippe Gerum : cobalt/posix/signal: drop non-sensical masking with obsolete __SI_MASK
Module: xenomai-3 Branch: wip/kernel-4.14 Commit: dbced92d08b1da430b50de30eaca3a55c196927d URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=dbced92d08b1da430b50de30eaca3a55c196927d Author: Philippe GerumDate: Wed Dec 6 16:51:44 2017 +0100 cobalt/posix/signal: drop non-sensical masking with obsolete __SI_MASK --- kernel/cobalt/posix/compat.c |9 ++--- kernel/cobalt/posix/signal.c |9 ++--- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/kernel/cobalt/posix/compat.c b/kernel/cobalt/posix/compat.c index 44521b5..962465a 100644 --- a/kernel/cobalt/posix/compat.c +++ b/kernel/cobalt/posix/compat.c @@ -301,19 +301,14 @@ int sys32_put_siginfo(void __user *u_si, const struct siginfo *si, int overrun) { struct compat_siginfo __user *u_p = u_si; - int code, ret; + int ret; if (u_p == NULL) return -EFAULT; - /* Translate kernel codes for userland. */ - code = si->si_code; - if (code & __SI_MASK) - code |= __SI_MASK; - ret = __xn_put_user(si->si_signo, _p->si_signo); ret |= __xn_put_user(si->si_errno, _p->si_errno); - ret |= __xn_put_user(code, _p->si_code); + ret |= __xn_put_user(si->si_code, _p->si_code); /* * Copy the generic/standard siginfo bits to userland. diff --git a/kernel/cobalt/posix/signal.c b/kernel/cobalt/posix/signal.c index 416d3e4..e870283 100644 --- a/kernel/cobalt/posix/signal.c +++ b/kernel/cobalt/posix/signal.c @@ -339,16 +339,11 @@ static int signal_put_siginfo(void __user *u_si, const struct siginfo *si, int overrun) { struct siginfo __user *u_p = u_si; - int code, ret; - - /* Translate kernel codes for userland. */ - code = si->si_code; - if (code & __SI_MASK) - code |= __SI_MASK; + int ret; ret = __xn_put_user(si->si_signo, _p->si_signo); ret |= __xn_put_user(si->si_errno, _p->si_errno); - ret |= __xn_put_user(code, _p->si_code); + ret |= __xn_put_user(si->si_code, _p->si_code); /* * Copy the generic/standard siginfo bits to userland. ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : net/iovec: drop useless kernel<-> iovec[] copy helpers
Module: xenomai-3 Branch: wip/rtnet-fixes Commit: c640a6040e72c7597d06b119d3ce30fbf3408e82 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=c640a6040e72c7597d06b119d3ce30fbf3408e82 Author: Philippe GerumDate: Wed Dec 6 13:41:06 2017 +0100 net/iovec: drop useless kernel<-> iovec[] copy helpers No more in-tree users for those, in the wake of dropping the broken direct references from the kernel to user-space memory. --- kernel/drivers/net/stack/include/rtnet_iovec.h | 18 -- kernel/drivers/net/stack/iovec.c | 46 2 files changed, 64 deletions(-) diff --git a/kernel/drivers/net/stack/include/rtnet_iovec.h b/kernel/drivers/net/stack/include/rtnet_iovec.h index 09e86d1..69113f4 100644 --- a/kernel/drivers/net/stack/include/rtnet_iovec.h +++ b/kernel/drivers/net/stack/include/rtnet_iovec.h @@ -28,24 +28,6 @@ struct user_msghdr; struct rtdm_fd; -/*** - * rt_iovec_len - */ -static inline size_t rt_iovec_len(const struct iovec *iov, int iovlen) -{ -int i; -size_t len = 0; - -for (i = 0; i < iovlen; i++) -len += iov[i].iov_len; - -return len; -} - - -extern void rt_memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len); -extern void rt_memcpy_fromkerneliovec(unsigned char *kdata, struct iovec *iov, int len); - ssize_t rtnet_write_to_iov(struct rtdm_fd *fd, struct iovec *iov, int iovlen, const void *data, size_t len); diff --git a/kernel/drivers/net/stack/iovec.c b/kernel/drivers/net/stack/iovec.c index 3164d28..ac7501c 100644 --- a/kernel/drivers/net/stack/iovec.c +++ b/kernel/drivers/net/stack/iovec.c @@ -29,52 +29,6 @@ #include #include - -/*** - * rt_memcpy_tokerneliovec - */ -void rt_memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len) -{ -while (len > 0) -{ -if (iov->iov_len) -{ -int copy = min_t(unsigned int, iov->iov_len, len); - -memcpy(iov->iov_base, kdata, copy); -kdata+=copy; -len-=copy; -iov->iov_len-=copy; -iov->iov_base+=copy; -} -iov++; -} -} -EXPORT_SYMBOL_GPL(rt_memcpy_tokerneliovec); - - -/*** - * rt_memcpy_fromkerneliovec - */ -void rt_memcpy_fromkerneliovec(unsigned char *kdata, struct iovec *iov,int len) -{ -while (len > 0) -{ -if (iov->iov_len) -{ -int copy=min_t(unsigned int, len, iov->iov_len); - -memcpy(kdata, iov->iov_base, copy); -len-=copy; -kdata+=copy; -iov->iov_base+=copy; -iov->iov_len-=copy; -} -iov++; -} -} -EXPORT_SYMBOL_GPL(rt_memcpy_fromkerneliovec); - ssize_t rtnet_write_to_iov(struct rtdm_fd *fd, struct iovec *iov, int iovlen, const void *data, size_t len) ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : net: convert to rtdm_get_iov_flatlen()
Module: xenomai-3 Branch: wip/rtnet-fixes Commit: 64d2b7657ce4bddb2e2cc1a209dfedfa01000502 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=64d2b7657ce4bddb2e2cc1a209dfedfa01000502 Author: Philippe GerumDate: Wed Dec 6 13:40:19 2017 +0100 net: convert to rtdm_get_iov_flatlen() --- kernel/drivers/net/stack/ipv4/udp/udp.c |4 ++-- kernel/drivers/net/stack/packet/af_packet.c |4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/drivers/net/stack/ipv4/udp/udp.c b/kernel/drivers/net/stack/ipv4/udp/udp.c index c460e40..a3fd496 100644 --- a/kernel/drivers/net/stack/ipv4/udp/udp.c +++ b/kernel/drivers/net/stack/ipv4/udp/udp.c @@ -454,7 +454,7 @@ ssize_t rt_udp_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int msg_flag __rtskb_pull(skb, sizeof(struct udphdr)); flags = msg->msg_flags & ~MSG_TRUNC; -len = rt_iovec_len(iov, msg->msg_iovlen); +len = rtdm_get_iov_flatlen(iov, msg->msg_iovlen); /* iterate over all IP fragments */ do { @@ -605,7 +605,7 @@ ssize_t rt_udp_sendmsg(struct rtdm_fd *fd, const struct user_msghdr *msg, int ms if (err) return err; -len = rt_iovec_len(iov, msg->msg_iovlen); +len = rtdm_get_iov_flatlen(iov, msg->msg_iovlen); if ((len < 0) || (len > 0x-sizeof(struct iphdr)-sizeof(struct udphdr))) { err = -EMSGSIZE; goto out; diff --git a/kernel/drivers/net/stack/packet/af_packet.c b/kernel/drivers/net/stack/packet/af_packet.c index 046f380..4fbf523 100644 --- a/kernel/drivers/net/stack/packet/af_packet.c +++ b/kernel/drivers/net/stack/packet/af_packet.c @@ -364,7 +364,7 @@ rt_packet_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int msg_flags) /* The data must not be longer than the available buffer size */ copy_len = rtskb->len; -len = rt_iovec_len(iov, msg->msg_iovlen); +len = rtdm_get_iov_flatlen(iov, msg->msg_iovlen); if (len < 0) { copy_len = len; goto out; @@ -467,7 +467,7 @@ rt_packet_sendmsg(struct rtdm_fd *fd, const struct user_msghdr *msg, int msg_fla goto abort; } -len = rt_iovec_len(iov, msg->msg_iovlen); +len = rtdm_get_iov_flatlen(iov, msg->msg_iovlen); rtskb = alloc_rtskb(rtdev->hard_header_len + len, >skb_pool); if (rtskb == NULL) { ret = -ENOBUFS; ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : net/tcp: recvmsg: remove direct references to user memory
Module: xenomai-3 Branch: wip/rtnet-fixes Commit: 19af2f15dd76bdeb61e9f8e0edf4f4a8060f964f URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=19af2f15dd76bdeb61e9f8e0edf4f4a8060f964f Author: Philippe GerumDate: Wed Dec 6 13:17:20 2017 +0100 net/tcp: recvmsg: remove direct references to user memory --- kernel/drivers/net/stack/ipv4/tcp/tcp.c | 45 +++ 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/kernel/drivers/net/stack/ipv4/tcp/tcp.c b/kernel/drivers/net/stack/ipv4/tcp/tcp.c index f01399d..6c1f38d 100644 --- a/kernel/drivers/net/stack/ipv4/tcp/tcp.c +++ b/kernel/drivers/net/stack/ipv4/tcp/tcp.c @@ -1668,7 +1668,7 @@ static int rt_tcp_accept(struct tcp_socket *ts, struct sockaddr *addr, ts->is_accepted = 1; rtdm_lock_put_irqrestore(>socket_lock, context); -ret = rt_socket_fd(>sock)->fd; +//ret = rt_socket_fd(>sock)->fd; err: /* it is not critical to leave this unlocked @@ -2069,20 +2069,43 @@ static ssize_t rt_tcp_write(struct rtdm_fd *fd, const void *buf, size_t nbyte) */ static ssize_t rt_tcp_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int msg_flags) { -size_t len; -void *buf; + struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov; + struct user_msghdr _msg; + ssize_t ret; + size_t len; + void *buf; -if (msg_flags) - return -EOPNOTSUPP; + if (msg_flags) + return -EOPNOTSUPP; -/* loop over all vectors to be implemented */ -if (msg->msg_iovlen != 1) - return -EOPNOTSUPP; + msg = rtnet_get_arg(fd, &_msg, msg, sizeof(*msg)); + if (IS_ERR(msg)) + return PTR_ERR(msg); -len = msg->msg_iov[0].iov_len; -buf = msg->msg_iov[0].iov_base; + /* loop over all vectors to be implemented */ + if (msg->msg_iovlen != 1) + return -EOPNOTSUPP; + + ret = rtdm_get_iovec(fd, , msg, iov_fast); + if (ret) + return ret; -return rt_tcp_read(fd, buf, len); + len = iov[0].iov_len; + if (len > 0) { + buf = xnmalloc(len); + if (buf == NULL) { + ret = -ENOMEM; + goto out; + } + ret = rtdm_copy_from_user(fd, buf, iov[0].iov_base, len); + if (!ret) + ret = rt_tcp_read(fd, buf, len); + xnfree(buf); + } +out: + rtdm_drop_iovec(iov, iov_fast); + + return ret; } /*** ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : net/tcp: sendmsg: remove direct references to user memory
Module: xenomai-3 Branch: wip/rtnet-fixes Commit: 28f4b34e0b085e6fb662b6d53dfc1b91621e36d4 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=28f4b34e0b085e6fb662b6d53dfc1b91621e36d4 Author: Philippe GerumDate: Wed Dec 6 13:30:29 2017 +0100 net/tcp: sendmsg: remove direct references to user memory --- kernel/drivers/net/stack/ipv4/tcp/tcp.c | 45 +++ 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/kernel/drivers/net/stack/ipv4/tcp/tcp.c b/kernel/drivers/net/stack/ipv4/tcp/tcp.c index 6c1f38d..c5e42bc 100644 --- a/kernel/drivers/net/stack/ipv4/tcp/tcp.c +++ b/kernel/drivers/net/stack/ipv4/tcp/tcp.c @@ -1668,7 +1668,7 @@ static int rt_tcp_accept(struct tcp_socket *ts, struct sockaddr *addr, ts->is_accepted = 1; rtdm_lock_put_irqrestore(>socket_lock, context); -//ret = rt_socket_fd(>sock)->fd; +ret = rt_socket_fd(>sock)->fd; err: /* it is not critical to leave this unlocked @@ -2114,20 +2114,43 @@ out: static ssize_t rt_tcp_sendmsg(struct rtdm_fd *fd, const struct user_msghdr *msg, int msg_flags) { -size_t len; -void *buf; + struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov; + struct user_msghdr _msg; + ssize_t ret; + size_t len; + void *buf; + + if (msg_flags) + return -EOPNOTSUPP; -if (msg_flags) - return -EOPNOTSUPP; + msg = rtnet_get_arg(fd, &_msg, msg, sizeof(*msg)); + if (IS_ERR(msg)) + return PTR_ERR(msg); + + /* loop over all vectors to be implemented */ + if (msg->msg_iovlen != 1) + return -EOPNOTSUPP; -/* loop over all vectors to be implemented */ -if (msg->msg_iovlen != 1) - return -EOPNOTSUPP; + ret = rtdm_get_iovec(fd, , msg, iov_fast); + if (ret) + return ret; -len = msg->msg_iov[0].iov_len; -buf = msg->msg_iov[0].iov_base; + len = iov[0].iov_len; + if (len > 0) { + buf = xnmalloc(len); + if (buf == NULL) { + ret = -ENOMEM; + goto out; + } + ret = rtdm_copy_from_user(fd, buf, iov[0].iov_base, len); + if (!ret) + ret = rt_tcp_write(fd, buf, len); + xnfree(buf); + } +out: + rtdm_drop_iovec(iov, iov_fast); -return rt_tcp_write(fd, (const void*)buf, len); + return ret; } /*** ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : net/udp: recvmsg: write back namelen only if name required
Module: xenomai-3 Branch: wip/rtnet-fixes Commit: 4df6deed0330b500973e5ab3d5b8f10b4b2913de URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=4df6deed0330b500973e5ab3d5b8f10b4b2913de Author: Philippe GerumDate: Wed Dec 6 12:47:55 2017 +0100 net/udp: recvmsg: write back namelen only if name required --- kernel/drivers/net/stack/ipv4/udp/udp.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/kernel/drivers/net/stack/ipv4/udp/udp.c b/kernel/drivers/net/stack/ipv4/udp/udp.c index 8284ff7..4ec5ab3 100644 --- a/kernel/drivers/net/stack/ipv4/udp/udp.c +++ b/kernel/drivers/net/stack/ipv4/udp/udp.c @@ -432,12 +432,7 @@ ssize_t rt_udp_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int msg_flag uh = skb->h.uh; first_skb = skb; -namelen = sizeof(sin); -ret = rtnet_put_arg(fd, >msg_namelen, , sizeof(namelen)); -if (ret) - goto fail; - -/* copy the address */ +/* copy the address if required. */ if (msg->msg_name) { memset(, 0, sizeof(sin)); sin.sin_family = AF_INET; @@ -446,7 +441,12 @@ ssize_t rt_udp_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int msg_flag ret = rtnet_put_arg(fd, >msg_name, , sizeof(sin)); if (ret) goto fail; -} + + namelen = sizeof(sin); + ret = rtnet_put_arg(fd, >msg_namelen, , sizeof(namelen)); + if (ret) + goto fail; + } data_len = ntohs(uh->len) - sizeof(struct udphdr); ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : net/packet: sendmsg: remove direct references to user memory
Module: xenomai-3 Branch: wip/rtnet-fixes Commit: b198c724acd4b3dfc431fd898e20ba635e3d52e8 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=b198c724acd4b3dfc431fd898e20ba635e3d52e8 Author: Philippe GerumDate: 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 | 67 +++ 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/kernel/drivers/net/stack/packet/af_packet.c b/kernel/drivers/net/stack/packet/af_packet.c index f248239..046f380 100644 --- a/kernel/drivers/net/stack/packet/af_packet.c +++ b/kernel/drivers/net/stack/packet/af_packet.c @@ -404,43 +404,70 @@ 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, , 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)) { + ret = PTR_ERR(sll); + goto abort; + } + + 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))) { + ret = -EINVAL; + goto abort; + } + + ifindex = sll->sll_ifindex; + proto = sll->sll_protocol; + addr= sll->sll_addr; } -if ((rtdev = rtdev_get_by_index(ifindex)) == NULL) - return -ENODEV; +if ((rtdev = rtdev_get_by_index(ifindex)) == NULL) { + ret = -ENODEV; + goto abort; +} +len = rt_iovec_len(iov, msg->msg_iovlen); rtskb = alloc_rtskb(rtdev->hard_header_len + len, >skb_pool); if (rtskb == NULL) { ret = -ENOBUFS; @@ -480,7 +507,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,8 +519,10 @@ rt_packet_sendmsg(struct rtdm_fd *fd, const struct user_msghdr *msg, int msg_fla out: rtdev_dereference(rtdev); -return ret; + abort: +rtdm_drop_iovec(iov, iov_fast); +return ret; err: kfree_rtskb(rtskb); goto out; ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : net/udp: sendmsg: remove direct references to user memory
Module: xenomai-3 Branch: wip/rtnet-fixes Commit: b0f7db9663cc59f9d496bd01a687d6cd6560c1ef URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=b0f7db9663cc59f9d496bd01a687d6cd6560c1ef Author: Philippe GerumDate: Wed Dec 6 12:45:58 2017 +0100 net/udp: sendmsg: remove direct references to user memory --- kernel/drivers/net/stack/ipv4/udp/udp.c | 126 +++ 1 file changed, 79 insertions(+), 47 deletions(-) diff --git a/kernel/drivers/net/stack/ipv4/udp/udp.c b/kernel/drivers/net/stack/ipv4/udp/udp.c index 4ec5ab3..c460e40 100644 --- a/kernel/drivers/net/stack/ipv4/udp/udp.c +++ b/kernel/drivers/net/stack/ipv4/udp/udp.c @@ -515,6 +515,7 @@ struct udpfakehdr struct udphdr uh; u32 daddr; u32 saddr; +struct rtdm_fd *fd; struct iovec *iov; int iovlen; u32 wcheck; @@ -529,35 +530,36 @@ static int rt_udp_getfrag(const void *p, unsigned char *to, unsigned int offset, unsigned int fraglen) { struct udpfakehdr *ufh = (struct udpfakehdr *)p; -int i; +int i, ret; // We should optimize this function a bit (copy+csum...)! -if (offset==0) { -/* Checksum of the complete data part of the UDP message: */ -for (i = 0; i < ufh->iovlen; i++) { +if (offset) + return rtnet_read_from_iov(ufh->fd, ufh->iov, ufh->iovlen, to, fraglen); + +/* Checksum of the complete data part of the UDP message: */ +for (i = 0; i < ufh->iovlen; i++) { ufh->wcheck = csum_partial(ufh->iov[i].iov_base, ufh->iov[i].iov_len, ufh->wcheck); -} - -rt_memcpy_fromkerneliovec(to + sizeof(struct udphdr), ufh->iov, - fraglen - sizeof(struct udphdr)); +} -/* Checksum of the udp header: */ -ufh->wcheck = csum_partial((unsigned char *)ufh, - sizeof(struct udphdr), ufh->wcheck); +ret = rtnet_read_from_iov(ufh->fd, ufh->iov, ufh->iovlen, + to + sizeof(struct udphdr), + fraglen - sizeof(struct udphdr)); +if (ret) + return ret; -ufh->uh.check = csum_tcpudp_magic(ufh->saddr, ufh->daddr, ntohs(ufh->uh.len), - IPPROTO_UDP, ufh->wcheck); +/* Checksum of the udp header: */ +ufh->wcheck = csum_partial((unsigned char *)ufh, + sizeof(struct udphdr), ufh->wcheck); + +ufh->uh.check = csum_tcpudp_magic(ufh->saddr, ufh->daddr, ntohs(ufh->uh.len), + IPPROTO_UDP, ufh->wcheck); -if (ufh->uh.check == 0) +if (ufh->uh.check == 0) ufh->uh.check = -1; -memcpy(to, ufh, sizeof(struct udphdr)); -return 0; -} - -rt_memcpy_fromkerneliovec(to, ufh->iov, fraglen); +memcpy(to, ufh, sizeof(struct udphdr)); return 0; } @@ -570,9 +572,9 @@ static int rt_udp_getfrag(const void *p, unsigned char *to, ssize_t rt_udp_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); -int ulen = len + sizeof(struct udphdr); -struct sockaddr_in *usin; +size_t len; +int ulen; +struct sockaddr_in _sin, *sin; struct udpfakehdr ufh; struct dest_route rt; u32 saddr; @@ -580,10 +582,8 @@ ssize_t rt_udp_sendmsg(struct rtdm_fd *fd, const struct user_msghdr *msg, int ms u16 dport; int err; rtdm_lockctx_t context; - - -if ((len < 0) || (len > 0x-sizeof(struct iphdr)-sizeof(struct udphdr))) -return -EMSGSIZE; +struct user_msghdr _msg; +struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov; if (msg_flags & MSG_OOB) /* Mirror BSD error message compatibility */ return -EOPNOTSUPP; @@ -591,39 +591,70 @@ ssize_t rt_udp_sendmsg(struct rtdm_fd *fd, const struct user_msghdr *msg, int ms if (msg_flags & ~(MSG_DONTROUTE|MSG_DONTWAIT) ) return -EINVAL; -if ((msg->msg_name) && (msg->msg_namelen==sizeof(struct sockaddr_in))) { -usin = (struct sockaddr_in*) msg->msg_name; +msg = rtnet_get_arg(fd, &_msg, msg, sizeof(*msg)); +if (IS_ERR(msg)) + return PTR_ERR(msg); -if ((usin->sin_family != AF_INET) && (usin->sin_family != AF_UNSPEC)) -return -EINVAL; +if (msg->msg_iovlen < 0) + return -EINVAL; + +if (msg->msg_iovlen == 0) + return 0; + +err = rtdm_get_iovec(fd, , msg, iov_fast); +if (err) + return err; -daddr = usin->sin_addr.s_addr; -dport = usin->sin_port; +len = rt_iovec_len(iov, msg->msg_iovlen); +if ((len < 0) || (len > 0x-sizeof(struct
[Xenomai-git] Philippe Gerum : net/udp: recvmsg: remove direct references to user memory
Module: xenomai-3 Branch: wip/rtnet-fixes Commit: 6670cf25851d474b3ac1b876d7369e15c6468c75 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=6670cf25851d474b3ac1b876d7369e15c6468c75 Author: Philippe GerumDate: Wed Dec 6 12:45:31 2017 +0100 net/udp: recvmsg: remove direct references to user memory --- kernel/drivers/net/stack/ipv4/udp/udp.c | 95 +-- 1 file changed, 65 insertions(+), 30 deletions(-) diff --git a/kernel/drivers/net/stack/ipv4/udp/udp.c b/kernel/drivers/net/stack/ipv4/udp/udp.c index f8eeadd..8284ff7 100644 --- a/kernel/drivers/net/stack/ipv4/udp/udp.c +++ b/kernel/drivers/net/stack/ipv4/udp/udp.c @@ -377,20 +377,39 @@ int rt_udp_ioctl(struct rtdm_fd *fd, unsigned int request, void __user *arg) /*** * rt_udp_recvmsg */ +/*** + * rt_udp_recvmsg + */ ssize_t rt_udp_recvmsg(struct rtdm_fd *fd, 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); +size_t len; struct rtskb*skb; struct rtskb*first_skb; size_t copied = 0; size_t block_size; size_t data_len; struct udphdr *uh; -struct sockaddr_in *sin; +struct sockaddr_in sin; nanosecs_rel_t timeout = sock->timeout; -int ret; +int ret, flags; +struct user_msghdr _msg; +socklen_t namelen; +struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov; + +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, , msg, iov_fast); +if (ret) + return ret; /* non-blocking receive? */ if (msg_flags & MSG_DONTWAIT) @@ -398,35 +417,44 @@ ssize_t rt_udp_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int msg_flag ret = rtdm_sem_timeddown(>pending_sem, timeout, NULL); if (unlikely(ret < 0)) -switch (ret) { -case -EWOULDBLOCK: -case -ETIMEDOUT: -case -EINTR: -return ret; - -default: -return -EBADF; /* socket has been closed */ -} + switch (ret) { + default: + ret = -EBADF; /* socket has been closed */ + case -EWOULDBLOCK: + case -ETIMEDOUT: + case -EINTR: + rtdm_drop_iovec(iov, iov_fast); + return ret; + } skb = rtskb_dequeue_chain(>incoming); RTNET_ASSERT(skb != NULL, return -EFAULT;); - uh = skb->h.uh; -data_len = ntohs(uh->len) - sizeof(struct udphdr); -sin = msg->msg_name; +first_skb = skb; +namelen = sizeof(sin); +ret = rtnet_put_arg(fd, >msg_namelen, , sizeof(namelen)); +if (ret) + goto fail; + /* copy the address */ -msg->msg_namelen = sizeof(*sin); -if (sin) { -sin->sin_family = AF_INET; -sin->sin_port= uh->source; -sin->sin_addr.s_addr = skb->nh.iph->saddr; +if (msg->msg_name) { + memset(, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port= uh->source; + sin.sin_addr.s_addr = skb->nh.iph->saddr; + ret = rtnet_put_arg(fd, >msg_name, , sizeof(sin)); + if (ret) + goto fail; } +data_len = ntohs(uh->len) - sizeof(struct udphdr); + /* remove the UDP header */ __rtskb_pull(skb, sizeof(struct udphdr)); -first_skb = skb; +flags = msg->msg_flags & ~MSG_TRUNC; +len = rt_iovec_len(iov, msg->msg_iovlen); /* iterate over all IP fragments */ do { @@ -440,25 +468,28 @@ ssize_t rt_udp_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int msg_flag if (copied > len) { block_size -= copied - len; copied = len; -msg->msg_flags |= MSG_TRUNC; - -/* copy the data */ -rt_memcpy_tokerneliovec(msg->msg_iov, skb->data, block_size); - -break; + flags |= MSG_TRUNC; } /* copy the data */ -rt_memcpy_tokerneliovec(msg->msg_iov, skb->data, block_size); + ret = rtnet_write_to_iov(fd, iov, msg->msg_iovlen, skb->data, block_size); + if (ret) + goto fail; /* next fragment */ skb = skb->next; -} while (skb != NULL); +} while (skb && !(flags & MSG_TRUNC)); /* did we copied all bytes? */ if (data_len > 0) -msg->msg_flags |= MSG_TRUNC; + flags |= MSG_TRUNC; +if (flags != msg->msg_flags) { + ret = rtnet_put_arg(fd, >msg_flags, , sizeof(flags)); + if (ret) + goto fail; +} +out: if ((msg_flags &
[Xenomai-git] Philippe Gerum : net/tcp: ioctl: remove direct references to user memory
Module: xenomai-3 Branch: wip/rtnet-fixes Commit: 60b3a9070974f05eb6bfd18e3f37886bd66a5fa9 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=60b3a9070974f05eb6bfd18e3f37886bd66a5fa9 Author: Philippe GerumDate: Mon Dec 4 19:21:18 2017 +0100 net/tcp: ioctl: remove direct references to user memory --- kernel/drivers/net/stack/ipv4/tcp/tcp.c | 82 +-- 1 file changed, 56 insertions(+), 26 deletions(-) diff --git a/kernel/drivers/net/stack/ipv4/tcp/tcp.c b/kernel/drivers/net/stack/ipv4/tcp/tcp.c index b1d01e9..f01399d 100644 --- a/kernel/drivers/net/stack/ipv4/tcp/tcp.c +++ b/kernel/drivers/net/stack/ipv4/tcp/tcp.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -1781,10 +1782,16 @@ static int rt_tcp_ioctl(struct rtdm_fd *fd, unsigned int request, void __user *arg) { struct tcp_socket* ts = rtdm_fd_to_private(fd); -struct _rtdm_setsockaddr_args *setaddr = arg; -struct _rtdm_getsockaddr_args *getaddr = arg; -struct _rtdm_getsockopt_args *getopt = arg; -struct _rtdm_setsockopt_args *setopt = arg; +const struct _rtdm_setsockaddr_args *setaddr; +struct _rtdm_setsockaddr_args _setaddr; +const struct _rtdm_getsockaddr_args *getaddr; +struct _rtdm_getsockaddr_args _getaddr; +const struct _rtdm_getsockopt_args *getopt; +struct _rtdm_getsockopt_args _getopt; +const struct _rtdm_setsockopt_args *setopt; +struct _rtdm_setsockopt_args _setopt; +const long *val; +long _val; int in_rt; /* fast path for common socket IOCTLs */ @@ -1795,42 +1802,65 @@ static int rt_tcp_ioctl(struct rtdm_fd *fd, switch (request) { case _RTIOC_BIND: - return rt_tcp_bind(ts, setaddr->addr, setaddr->addrlen); - + setaddr = rtnet_get_arg(fd, &_setaddr, arg, sizeof(_setaddr)); + if (IS_ERR(setaddr)) + return PTR_ERR(setaddr); + return rt_tcp_bind(ts, setaddr->addr, setaddr->addrlen); case _RTIOC_CONNECT: - if (!in_rt) - return -ENOSYS; - return rt_tcp_connect(ts, setaddr->addr, setaddr->addrlen); + if (!in_rt) + return -ENOSYS; + setaddr = rtnet_get_arg(fd, &_setaddr, arg, sizeof(_setaddr)); + if (IS_ERR(setaddr)) + return PTR_ERR(setaddr); + return rt_tcp_connect(ts, setaddr->addr, setaddr->addrlen); case _RTIOC_LISTEN: - return rt_tcp_listen(ts, (unsigned long)arg); + val = rtnet_get_arg(fd, &_val, arg, sizeof(long)); + if (IS_ERR(val)) + return PTR_ERR(val); + return rt_tcp_listen(ts, *val); case _RTIOC_ACCEPT: - if (!in_rt) - return -ENOSYS; - return rt_tcp_accept(ts, getaddr->addr, getaddr->addrlen); + if (!in_rt) + return -ENOSYS; + getaddr = rtnet_get_arg(fd, &_getaddr, arg, sizeof(_getaddr)); + if (IS_ERR(getaddr)) + return PTR_ERR(getaddr); + return rt_tcp_accept(ts, getaddr->addr, getaddr->addrlen); case _RTIOC_SHUTDOWN: - return rt_tcp_shutdown(ts, (unsigned long)arg); + val = rtnet_get_arg(fd, &_val, arg, sizeof(long)); + if (IS_ERR(val)) + return PTR_ERR(val); + return rt_tcp_shutdown(ts, *val); case _RTIOC_SETSOCKOPT: - if (setopt->level != SOL_SOCKET) - break; + setopt = rtnet_get_arg(fd, &_setopt, arg, sizeof(_setopt)); + if (IS_ERR(setopt)) + return PTR_ERR(setopt); - return rt_tcp_setsockopt(fd, ts, setopt->level, -setopt->optname, setopt->optval, -setopt->optlen); + if (setopt->level != SOL_SOCKET) + break; + + return rt_tcp_setsockopt(fd, ts, setopt->level, +setopt->optname, setopt->optval, +setopt->optlen); case _RTIOC_GETSOCKOPT: - if (getopt->level != SOL_SOCKET) - break; - return rt_tcp_getsockopt(fd, ts, getopt->level, -getopt->optname, getopt->optval, -getopt->optlen); + getopt = rtnet_get_arg(fd, &_getopt, arg, sizeof(_getopt)); + if (IS_ERR(getopt)) + return PTR_ERR(getopt); - default: - break; + if (getopt->level != SOL_SOCKET) + break; + + return rt_tcp_getsockopt(fd, ts, getopt->level, +getopt->optname,
[Xenomai-git] Philippe Gerum : net/packet: recvmsg: write back namelen only if name required
Module: xenomai-3 Branch: wip/rtnet-fixes Commit: 38486323e50c02208e80beb940612555f79fc79f URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=38486323e50c02208e80beb940612555f79fc79f Author: Philippe GerumDate: Tue Dec 5 10:36:07 2017 +0100 net/packet: recvmsg: write back namelen only if name required --- kernel/drivers/net/stack/packet/af_packet.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/kernel/drivers/net/stack/packet/af_packet.c b/kernel/drivers/net/stack/packet/af_packet.c index ff3ef33..f248239 100644 --- a/kernel/drivers/net/stack/packet/af_packet.c +++ b/kernel/drivers/net/stack/packet/af_packet.c @@ -335,12 +335,6 @@ rt_packet_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int msg_flags) rtskb = rtskb_dequeue_chain(>incoming); RTNET_ASSERT(rtskb != NULL, return -EFAULT;); -/* copy the address */ -namelen = sizeof(sll); -ret = rtnet_put_arg(fd, >msg_namelen, , sizeof(namelen)); -if (ret) - goto fail; - /* copy the address if required. */ if (msg->msg_name) { struct rtnet_device *rtdev = rtskb->rtdev; @@ -357,6 +351,11 @@ rt_packet_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int msg_flags) ret = rtnet_put_arg(fd, >msg_name, , sizeof(sll)); if (ret) goto fail; + + namelen = sizeof(sll); + ret = rtnet_put_arg(fd, >msg_namelen, , sizeof(namelen)); + if (ret) + goto fail; } /* Include the header in raw delivery */ ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : net/packet: recvmsg: remove direct references to user memory
Module: xenomai-3 Branch: wip/rtnet-fixes Commit: 90c7e17c8340ae7457ea93a43c68d59c18ed7c7d URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=90c7e17c8340ae7457ea93a43c68d59c18ed7c7d Author: Philippe GerumDate: Tue Dec 5 10:31:32 2017 +0100 net/packet: recvmsg: remove direct references to user memory --- kernel/drivers/net/stack/packet/af_packet.c | 84 +++ 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/kernel/drivers/net/stack/packet/af_packet.c b/kernel/drivers/net/stack/packet/af_packet.c index f6638a7..ff3ef33 100644 --- a/kernel/drivers/net/stack/packet/af_packet.c +++ b/kernel/drivers/net/stack/packet/af_packet.c @@ -292,14 +292,29 @@ static ssize_t rt_packet_recvmsg(struct rtdm_fd *fd, 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); +ssize_t len; size_t copy_len; -size_t real_len; struct rtskb*rtskb; -struct sockaddr_ll *sll; -int ret; +struct sockaddr_ll sll; +intret, flags; nanosecs_rel_t timeout = sock->timeout; +struct user_msghdr _msg; +socklen_t namelen; +struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov; + +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, , msg, iov_fast); +if (ret) + return ret; /* non-blocking receive? */ if (msg_flags & MSG_DONTWAIT) @@ -308,50 +323,64 @@ rt_packet_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int msg_flags) ret = rtdm_sem_timeddown(>pending_sem, timeout, NULL); if (unlikely(ret < 0)) switch (ret) { + default: + ret = -EBADF; /* socket has been closed */ case -EWOULDBLOCK: case -ETIMEDOUT: case -EINTR: + rtdm_drop_iovec(iov, iov_fast); return ret; - - default: - return -EBADF; /* socket has been closed */ } rtskb = rtskb_dequeue_chain(>incoming); RTNET_ASSERT(rtskb != NULL, return -EFAULT;); -sll = msg->msg_name; - /* copy the address */ -msg->msg_namelen = sizeof(*sll); -if (sll != NULL) { - struct rtnet_device *rtdev = rtskb->rtdev; +namelen = sizeof(sll); +ret = rtnet_put_arg(fd, >msg_namelen, , sizeof(namelen)); +if (ret) + goto fail; - sll->sll_family = AF_PACKET; - sll->sll_hatype = rtdev->type; - sll->sll_protocol = rtskb->protocol; - sll->sll_pkttype = rtskb->pkt_type; - sll->sll_ifindex = rtdev->ifindex; +/* copy the address if required. */ +if (msg->msg_name) { + struct rtnet_device *rtdev = rtskb->rtdev; + memset(, 0, sizeof(sll)); + sll.sll_family = AF_PACKET; + sll.sll_hatype = rtdev->type; + sll.sll_protocol = rtskb->protocol; + sll.sll_pkttype = rtskb->pkt_type; + sll.sll_ifindex = rtdev->ifindex; /* Ethernet specific - we rather need some parse handler here */ - memcpy(sll->sll_addr, rtskb->mac.ethernet->h_source, ETH_ALEN); - sll->sll_halen = ETH_ALEN; + memcpy(sll.sll_addr, rtskb->mac.ethernet->h_source, ETH_ALEN); + sll.sll_halen = ETH_ALEN; + ret = rtnet_put_arg(fd, >msg_name, , sizeof(sll)); + if (ret) + goto fail; } /* Include the header in raw delivery */ if (rtdm_fd_to_context(fd)->device->driver->socket_type != SOCK_DGRAM) rtskb_push(rtskb, rtskb->data - rtskb->mac.raw); -copy_len = real_len = rtskb->len; - /* The data must not be longer than the available buffer size */ +copy_len = rtskb->len; +len = rt_iovec_len(iov, msg->msg_iovlen); +if (len < 0) { + copy_len = len; + goto out; +} + if (copy_len > len) { copy_len = len; - msg->msg_flags |= MSG_TRUNC; + flags = msg->msg_flags | MSG_TRUNC; + ret = rtnet_put_arg(fd, >msg_flags, , sizeof(flags)); + if (ret) + goto fail; } -rt_memcpy_tokerneliovec(msg->msg_iov, rtskb->data, copy_len); - +copy_len = rtnet_write_to_iov(fd, iov, msg->msg_iovlen, rtskb->data, copy_len); +out: if ((msg_flags & MSG_PEEK) == 0) { kfree_rtskb(rtskb); } else { @@ -359,7 +388,12 @@ rt_packet_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int msg_flags) rtdm_sem_up(>pending_sem); } -return real_len; +rtdm_drop_iovec(iov, iov_fast); + +return copy_len; +fail: +copy_len = ret; +goto out; } ___ Xenomai-git mailing list
[Xenomai-git] Philippe Gerum : net/iovec: add copy iterators for iovec[]
Module: xenomai-3 Branch: wip/rtnet-fixes Commit: ae039255108bf36a3f500db2ea7bb6dc19e6ccea URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=ae039255108bf36a3f500db2ea7bb6dc19e6ccea Author: Philippe GerumDate: Tue Dec 5 15:34:17 2017 +0100 net/iovec: add copy iterators for iovec[] --- kernel/drivers/net/stack/include/rtnet_iovec.h |8 +++ kernel/drivers/net/stack/iovec.c | 79 +++- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/kernel/drivers/net/stack/include/rtnet_iovec.h b/kernel/drivers/net/stack/include/rtnet_iovec.h index 2b81893..09e86d1 100644 --- a/kernel/drivers/net/stack/include/rtnet_iovec.h +++ b/kernel/drivers/net/stack/include/rtnet_iovec.h @@ -25,6 +25,8 @@ #include +struct user_msghdr; +struct rtdm_fd; /*** * rt_iovec_len @@ -44,7 +46,13 @@ static inline size_t rt_iovec_len(const struct iovec *iov, int iovlen) extern void rt_memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len); extern void rt_memcpy_fromkerneliovec(unsigned char *kdata, struct iovec *iov, int len); +ssize_t rtnet_write_to_iov(struct rtdm_fd *fd, + struct iovec *iov, int iovlen, + const void *data, size_t len); +ssize_t rtnet_read_from_iov(struct rtdm_fd *fd, + struct iovec *iov, int iovlen, + void *data, size_t len); #endif /* __KERNEL__ */ #endif /* __RTNET_IOVEC_H_ */ diff --git a/kernel/drivers/net/stack/iovec.c b/kernel/drivers/net/stack/iovec.c index 24efa87..3164d28 100644 --- a/kernel/drivers/net/stack/iovec.c +++ b/kernel/drivers/net/stack/iovec.c @@ -25,8 +25,9 @@ #include #include #include - +#include #include +#include /*** @@ -49,6 +50,7 @@ void rt_memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len) iov++; } } +EXPORT_SYMBOL_GPL(rt_memcpy_tokerneliovec); /*** @@ -71,7 +73,78 @@ void rt_memcpy_fromkerneliovec(unsigned char *kdata, struct iovec *iov,int len) iov++; } } +EXPORT_SYMBOL_GPL(rt_memcpy_fromkerneliovec); +ssize_t rtnet_write_to_iov(struct rtdm_fd *fd, + struct iovec *iov, int iovlen, + const void *data, size_t len) +{ + ssize_t ret = 0; + size_t nbytes; + int n; -EXPORT_SYMBOL_GPL(rt_memcpy_tokerneliovec); -EXPORT_SYMBOL_GPL(rt_memcpy_fromkerneliovec); + for (n = 0; len > 0 && n < iovlen; n++, iov++) { + if (iov->iov_len == 0) + continue; + + nbytes = iov->iov_len; + if (nbytes > len) + nbytes = len; + + ret = rtnet_put_arg(fd, iov->iov_base, data, nbytes); + if (ret) + break; + + len -= nbytes; + data += nbytes; + iov->iov_len -= nbytes; + iov->iov_base += nbytes; + ret += nbytes; + if (ret < 0) { + ret = -EINVAL; + break; + } + } + + return ret; +} +EXPORT_SYMBOL_GPL(rtnet_write_to_iov); + +ssize_t rtnet_read_from_iov(struct rtdm_fd *fd, + struct iovec *iov, int iovlen, + void *data, size_t len) +{ + ssize_t ret = 0; + size_t nbytes; + int n; + + for (n = 0; len > 0 && n < iovlen; n++, iov++) { + if (iov->iov_len == 0) + continue; + + nbytes = iov->iov_len; + if (nbytes > len) + nbytes = len; + + if (!rtdm_fd_is_user(fd)) + memcpy(data, iov->iov_base, nbytes); + else { + ret = rtdm_copy_from_user(fd, data, iov->iov_base, nbytes); + if (ret) + break; + } + + len -= nbytes; + data += nbytes; + iov->iov_len -= nbytes; + iov->iov_base += nbytes; + ret += nbytes; + if (ret < 0) { + ret = -EINVAL; + break; + } + } + + return ret; +} +EXPORT_SYMBOL_GPL(rtnet_read_from_iov); ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : net/packet: ioctl: remove direct references to user memory
Module: xenomai-3 Branch: wip/rtnet-fixes Commit: 813fe25d1b09756b6233e5a6dd31b6826fd5a2a5 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=813fe25d1b09756b6233e5a6dd31b6826fd5a2a5 Author: Philippe GerumDate: Mon Dec 4 19:40:34 2017 +0100 net/packet: ioctl: remove direct references to user memory --- kernel/drivers/net/stack/packet/af_packet.c | 36 --- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/kernel/drivers/net/stack/packet/af_packet.c b/kernel/drivers/net/stack/packet/af_packet.c index 1e4c2be..f6638a7 100644 --- a/kernel/drivers/net/stack/packet/af_packet.c +++ b/kernel/drivers/net/stack/packet/af_packet.c @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -251,28 +252,35 @@ static void rt_packet_close(struct rtdm_fd *fd) /*** * rt_packet_ioctl */ -static int rt_packet_ioctl(struct rtdm_fd *fd, unsigned int request, void *arg) +static int rt_packet_ioctl(struct rtdm_fd *fd, unsigned int request, void __user *arg) { -struct rtsocket *sock = rtdm_fd_to_private(fd); -struct _rtdm_setsockaddr_args *setaddr = arg; -struct _rtdm_getsockaddr_args *getaddr = arg; - + struct rtsocket *sock = rtdm_fd_to_private(fd); + const struct _rtdm_setsockaddr_args *setaddr; + struct _rtdm_setsockaddr_args _setaddr; + const struct _rtdm_getsockaddr_args *getaddr; + struct _rtdm_getsockaddr_args _getaddr; -/* fast path for common socket IOCTLs */ -if (_IOC_TYPE(request) == RTIOC_TYPE_NETWORK) - return rt_socket_common_ioctl(fd, request, arg); + /* fast path for common socket IOCTLs */ + if (_IOC_TYPE(request) == RTIOC_TYPE_NETWORK) + return rt_socket_common_ioctl(fd, request, arg); -switch (request) { + switch (request) { case _RTIOC_BIND: - return rt_packet_bind(sock, setaddr->addr, setaddr->addrlen); + 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); case _RTIOC_GETSOCKNAME: - return rt_packet_getsockname(sock, getaddr->addr, -getaddr->addrlen); + getaddr = rtnet_get_arg(fd, &_getaddr, arg, sizeof(_getaddr)); + if (IS_ERR(getaddr)) + return PTR_ERR(getaddr); + return rt_packet_getsockname(sock, getaddr->addr, +getaddr->addrlen); default: - return rt_socket_if_ioctl(fd, request, arg); -} + return rt_socket_if_ioctl(fd, request, arg); + } } ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : net/udp: sendmsg: remove direct references to user memory
Module: xenomai-3 Branch: wip/rtnet-fixes Commit: 9f55754417f83f804badb591e1f58daf46e9ce8a URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=9f55754417f83f804badb591e1f58daf46e9ce8a Author: Philippe GerumDate: Tue Dec 5 15:35:32 2017 +0100 net/udp: sendmsg: remove direct references to user memory --- kernel/drivers/net/stack/ipv4/udp/udp.c | 94 +-- 1 file changed, 64 insertions(+), 30 deletions(-) diff --git a/kernel/drivers/net/stack/ipv4/udp/udp.c b/kernel/drivers/net/stack/ipv4/udp/udp.c index f8eeadd..984ef48 100644 --- a/kernel/drivers/net/stack/ipv4/udp/udp.c +++ b/kernel/drivers/net/stack/ipv4/udp/udp.c @@ -380,17 +380,33 @@ int rt_udp_ioctl(struct rtdm_fd *fd, unsigned int request, void __user *arg) ssize_t rt_udp_recvmsg(struct rtdm_fd *fd, 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); +size_t len; struct rtskb*skb; struct rtskb*first_skb; size_t copied = 0; size_t block_size; size_t data_len; struct udphdr *uh; -struct sockaddr_in *sin; +struct sockaddr_in sin; nanosecs_rel_t timeout = sock->timeout; -int ret; +int ret, flags; +struct user_msghdr _msg; +socklen_t namelen; +struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov; + +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, , msg, iov_fast); +if (ret) + return ret; /* non-blocking receive? */ if (msg_flags & MSG_DONTWAIT) @@ -398,35 +414,44 @@ ssize_t rt_udp_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int msg_flag ret = rtdm_sem_timeddown(>pending_sem, timeout, NULL); if (unlikely(ret < 0)) -switch (ret) { -case -EWOULDBLOCK: -case -ETIMEDOUT: -case -EINTR: -return ret; - -default: -return -EBADF; /* socket has been closed */ -} + switch (ret) { + default: + ret = -EBADF; /* socket has been closed */ + case -EWOULDBLOCK: + case -ETIMEDOUT: + case -EINTR: + rtdm_drop_iovec(iov, iov_fast); + return ret; + } skb = rtskb_dequeue_chain(>incoming); RTNET_ASSERT(skb != NULL, return -EFAULT;); - uh = skb->h.uh; -data_len = ntohs(uh->len) - sizeof(struct udphdr); -sin = msg->msg_name; +first_skb = skb; +namelen = sizeof(sin); +ret = rtnet_put_arg(fd, >msg_namelen, , sizeof(namelen)); +if (ret) + goto fail; + /* copy the address */ -msg->msg_namelen = sizeof(*sin); -if (sin) { -sin->sin_family = AF_INET; -sin->sin_port= uh->source; -sin->sin_addr.s_addr = skb->nh.iph->saddr; +if (msg->msg_name) { + memset(, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port= uh->source; + sin.sin_addr.s_addr = skb->nh.iph->saddr; + ret = rtnet_put_arg(fd, >msg_name, , sizeof(sin)); + if (ret) + goto fail; } +data_len = ntohs(uh->len) - sizeof(struct udphdr); + /* remove the UDP header */ __rtskb_pull(skb, sizeof(struct udphdr)); -first_skb = skb; +flags = msg->msg_flags & ~MSG_TRUNC; +len = rt_iovec_len(iov, msg->msg_iovlen); /* iterate over all IP fragments */ do { @@ -440,25 +465,28 @@ ssize_t rt_udp_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int msg_flag if (copied > len) { block_size -= copied - len; copied = len; -msg->msg_flags |= MSG_TRUNC; - -/* copy the data */ -rt_memcpy_tokerneliovec(msg->msg_iov, skb->data, block_size); - -break; + flags |= MSG_TRUNC; } /* copy the data */ -rt_memcpy_tokerneliovec(msg->msg_iov, skb->data, block_size); + ret = rtnet_write_to_iov(fd, iov, msg->msg_iovlen, skb->data, block_size); + if (ret) + goto fail; /* next fragment */ skb = skb->next; -} while (skb != NULL); +} while (skb && !(flags & MSG_TRUNC)); /* did we copied all bytes? */ if (data_len > 0) -msg->msg_flags |= MSG_TRUNC; + flags |= MSG_TRUNC; +if (flags != msg->msg_flags) { + ret = rtnet_put_arg(fd, >msg_flags, , sizeof(flags)); + if (ret) + goto fail; +} +out: if ((msg_flags & MSG_PEEK) == 0) kfree_rtskb(first_skb); else {
[Xenomai-git] Philippe Gerum : net/udp: ioctl: remove direct references to user memory
Module: xenomai-3 Branch: wip/rtnet-fixes Commit: 6bc9349605f82f5713ec19cdc9c54488e6aa9728 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=6bc9349605f82f5713ec19cdc9c54488e6aa9728 Author: Philippe GerumDate: Mon Dec 4 19:21:23 2017 +0100 net/udp: ioctl: remove direct references to user memory --- kernel/drivers/net/stack/ipv4/udp/udp.c | 31 ++- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/kernel/drivers/net/stack/ipv4/udp/udp.c b/kernel/drivers/net/stack/ipv4/udp/udp.c index 01c9d8d..f8eeadd 100644 --- a/kernel/drivers/net/stack/ipv4/udp/udp.c +++ b/kernel/drivers/net/stack/ipv4/udp/udp.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -345,26 +346,30 @@ void rt_udp_close(struct rtdm_fd *fd) -int rt_udp_ioctl(struct rtdm_fd *fd, unsigned int request, void *arg) +int rt_udp_ioctl(struct rtdm_fd *fd, unsigned int request, void __user *arg) { -struct rtsocket *sock = rtdm_fd_to_private(fd); -struct _rtdm_setsockaddr_args *setaddr = arg; - + struct rtsocket *sock = rtdm_fd_to_private(fd); + const struct _rtdm_setsockaddr_args *setaddr; + struct _rtdm_setsockaddr_args *_setaddr; -/* fast path for common socket IOCTLs */ -if (_IOC_TYPE(request) == RTIOC_TYPE_NETWORK) -return rt_socket_common_ioctl(fd, request, arg); + /* fast path for common socket IOCTLs */ + if (_IOC_TYPE(request) == RTIOC_TYPE_NETWORK) + return rt_socket_common_ioctl(fd, request, arg); -switch (request) { + switch (request) { case _RTIOC_BIND: -return rt_udp_bind(sock, setaddr->addr, setaddr->addrlen); - case _RTIOC_CONNECT: -return rt_udp_connect(sock, setaddr->addr, setaddr->addrlen); + setaddr = rtnet_get_arg(fd, &_setaddr, arg, sizeof(_setaddr)); + if (IS_ERR(setaddr)) + return PTR_ERR(setaddr); + if (request == _RTIOC_BIND) + return rt_udp_bind(sock, setaddr->addr, setaddr->addrlen); + + return rt_udp_connect(sock, setaddr->addr, setaddr->addrlen); default: -return rt_ip_ioctl(fd, request, arg); -} + return rt_ip_ioctl(fd, request, arg); + } } ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : net/udp: sendmsg: remove direct references to user memory -WIP
Module: xenomai-3 Branch: wip/rtnet-fixes Commit: 71ba0896be9a96d5abb81cdf08566c4da3e52318 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=71ba0896be9a96d5abb81cdf08566c4da3e52318 Author: Philippe GerumDate: Tue Dec 5 15:35:32 2017 +0100 net/udp: sendmsg: remove direct references to user memory -WIP --- kernel/drivers/net/stack/ipv4/udp/udp.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/drivers/net/stack/ipv4/udp/udp.c b/kernel/drivers/net/stack/ipv4/udp/udp.c index f8eeadd..b4d97c8 100644 --- a/kernel/drivers/net/stack/ipv4/udp/udp.c +++ b/kernel/drivers/net/stack/ipv4/udp/udp.c @@ -480,6 +480,7 @@ struct udpfakehdr struct udphdr uh; u32 daddr; u32 saddr; +struct rtdm_fd *fd; struct iovec *iov; int iovlen; u32 wcheck; @@ -596,6 +597,7 @@ ssize_t rt_udp_sendmsg(struct rtdm_fd *fd, const struct user_msghdr *msg, int ms ufh.uh.dest = dport; ufh.uh.len= htons(ulen); ufh.uh.check = 0; +ufh.fd= fd; ufh.iov = msg->msg_iov; ufh.iovlen= msg->msg_iovlen; ufh.wcheck= 0; ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git