On Wed, 2021-11-03 at 23:49 -0700, C Smith wrote: > I was able to make the CAN transmit work successfully from my 32 bit > compile of rtcansend.c, by adding rtdm_get_iovec() to the code. I'll > submit a patch once both transmit and receive are working, but I'm > still having trouble receiving data in the rtcanrecv app. I added > rtdm_get_iovec() to rtcan_raw_recvmsg() so that may ultimately work > but the driver is already giving up during the bind. I get this > error: > > [root@pc can]# /usr/xenomai/bin/rtcanrecv rtcan0 -v > interface rtcan0 > s=3, ifr_name=rtcan0 > bind: Invalid argument > Cleaning up... > > Here's the ioctl with extra printk()s, which executes during the > bind: > > int rtcan_raw_ioctl(struct rtdm_fd *fd,unsigned int request, void > *arg) > { > int ret = 0; > > switch (request) { > COMPAT_CASE(_RTIOC_BIND): { > struct _rtdm_setsockaddr_args *setaddr, setaddr_buf; > struct sockaddr_can *sockaddr, sockaddr_buf; > > if (rtdm_fd_is_user(fd)) { > /* Copy argument structure from userspace */ > printk("rtcan_raw.c, 421: rtcan_raw_ioctl\n"); > > if (rtdm_safe_copy_from_user(fd, &setaddr_buf, arg, > sizeof(struct _rtdm_setsockaddr_args))) > return -EFAULT;
That should be the source of your problem. It looks like rtcan never had a compat interface. (Jan should confirm first...) You have a 64 bit kernel, so the pointer width (in struct _rtdm_setsockaddr_args) is considered to be 8 bytes but userspace only provided 4. The copy operation still succeeds, but reading from this struct is now broken because of wrong offsets. Reading struct _rtdm_setsockaddr_args has be wrapped into a helper similar to rtdm_get_iovec(). > > setaddr = &setaddr_buf; > printk("rtcan_raw.c, 427: rtcan_raw_ioctl\n"); > printk("rtcan_raw.c, 428: setaddr->addrlen: %d\n", setaddr- > >addrlen); > > /* Check size */ > if (setaddr->addrlen != sizeof(struct sockaddr_can)) > return -EINVAL; > > The resultant print statements in dmesg : > [27177.480980] rtcan_raw.c, 421: rtcan_raw_ioctl > [27177.480987] rtcan_raw.c, 427: rtcan_raw_ioctl > [27177.480994] rtcan_raw.c, 428: setaddr->addrlen: -6084360 > > Do you have any idea why addrlen is corrupt ? > Thanks, -C Smith > > On Wed, Nov 3, 2021 at 4:09 AM Bezdeka, Florian > <florian.bezd...@siemens.com> wrote: > > On Wed, 2021-11-03 at 11:46 +0100, Jan Kiszka via Xenomai wrote: > > > On 03.11.21 07:59, Jan Kiszka wrote: > > > > On 02.11.21 23:57, C Smith via Xenomai wrote: > > > > > I added some printf/printk to rtcansend.c as well as > > rtcan_raw.c: > > > > > > > > > > rtcan_raw.c: > > > > > /* Check size of buffer */ > > > > > if (iov->iov_len != sizeof(can_frame_t)) { > > > > > printk("rtcan_raw.c, 850: sizeof(can_frame_t): > > %ld\n", > > > > > sizeof(can_frame_t)); > > > > > printk("rtcan_raw.c, 852: iov->iov_len: > > > > > %ld\n", > > > > > iov->iov_len); > > > > > return -EMSGSIZE; > > > > > } > > > > > > > > > > when running rtcansend (32-bit compile, which fails with > > EMSGSIZE): > > > > > [root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 -s > > 0xde 0xad > > > > > sizeof(can_frame_t): 16 > > > > > send: Message too long > > > > > > > > > > [root@pc can]# dmesg > > > > > [11275.197125] rtcan_raw.c, 850: > > > > > sizeof(can_frame_t): > > 16 > > > > > [11275.197133] rtcan_raw.c, 852: iov->iov_len: > > 34494267600 > > > > > > > > > > when running rtcansend (64-bit compile, sends out can msg > > > > > OK): > > > > > [root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 -s > > 0xde 0xad > > > > > sizeof(can_frame_t): 16 > > > > > > > > > > [root@pc can]# dmesg > > > > > [12476.571032] rtcan_raw.c, 850: > > > > > sizeof(can_frame_t): > > 16 > > > > > [12476.571040] rtcan_raw.c, 852: iov->iov_len: 16 > > > > > > > > > > It looks like the struct user_msghdr *msg passed into > > rtcan_raw_sendmsg() > > > > > is corrupt. > > > > > I'm using Xenomai 3.1, with kernel 4.19.989 x86_64 > > > > > -C Smith > > > > > > > > OK, my guess was wrong. Let me see where we corrupt this. > > > > > > > > Brings > > https://gitlab.com/Xenomai/xenomai-hacker-space/-/issues/21 into > > > > memory... > > > > > > > > > > Found it: We are lacking use of rtdm_get_iovec in rtcan - in > > contrast to > > > RTnet (see e.g. rt_packet_sendmsg). Would you feel like looking > > into > > > such a change? > > > > Just a note: rtcan_raw_sendmsg() and rtcan_raw_recvmsg() are both > > affected. Both should be using rtdm_get_iovec(). > > > > > > > > Jan > > > > >