Peter Maydell <peter.mayd...@linaro.org> wrote on 2014/07/11 19:02:30: > > > > hmm, should we not pass through as is to the kernel? > > Since we don't copy anything we could just remove this > > check and let the kernel decide policy? > > I thought about that, but there's a corner case: > the kernel does the clamping of the optlen before the > copy_from_user(), which means if you have: > [interface name] [unreadable memory] > and optlen is long enough that optval_addr + optlen > reaches into the unreadable memory, then QEMU will return > EFAULT (whereas the native kernel implementation will > succeed) unless we do the clamping of the optlen ourselves.
hmm, this kernel code: if (optlen > IFNAMSIZ - 1) optlen = IFNAMSIZ - 1; memset(devname, 0, sizeof(devname)); ret = -EFAULT; if (copy_from_user(devname, optval, optlen)) goto out; suggests to me that the qemu code could be written: case TARGET_SO_BINDTODEVICE: { char *dev_ifname; if (optlen > IFNAMSIZ - 1) { optlen = IFNAMSIZ - 1; } dev_ifname = lock_user(VERIFY_READ, optval_addr, optlen, 1); if (!dev_ifname) { return -TARGET_EFAULT; } optname = SO_BINDTODEVICE; ret = get_errno(setsockopt(sockfd, level, optname, dev_ifname, optlen)); unlock_user (dev_ifname, optval_addr, 0); return ret; } Not a big deal, I just wanted to improve my understanding of the kernel/qemu code. Jocke