fo_ioctl always EFAULT (from kernel module)

  • Thread starter Thread starter rr
  • Start date Start date
Hello.

I'm trying to fix devel/linux-js.
Code:
  struct usb_gen_descriptor ugd;

  kern_open(curthread, '/dev/uhid0', UIO_SYSSPACE, O_RDWR | O_NONBLOCK,0);
  fd = curthread->td_retval[0];

  memset(&ugd, 0, sizeof(ugd));
  ugd.ugd_data = NULL;
  ugd.ugd_maxlen = 65534;

  js_kern_ioctl(fd, USB_GET_REPORT_DESC, &ugd);

  ugd.ugd_data = malloc(ugd.ugd_actlen, M_DEVBUF, M_WAITOK | M_ZERO);
  ugd.ugd_maxlen = ugd.ugd_actlen;

  js_kern_ioctl(fd, USB_GET_REPORT_DESC, &ugd);

...

int js_kern_ioctl (int fd, u_long com, void *data)
{
  int error;
  struct file *fp;

  fget(curthread, fd, CAP_IOCTL, &fp);
  error = fo_ioctl(fp, com, data, curthread->td_ucred, curthread);
  fdrop(fp, curthread);
  return error;
}
What happens here is:
On the first js_kern_ioctl() call we get only ugd.ugd_actlen filled because ugd.ugd_data == NULL (info).

The second fo_ioctl() call produces an EFAULT error (ugd.ugd_actlen is really filled after the first call).

If I pre-allocate a big enough ugd.ugd_data buffer and try to get usb_gen_descriptor it will EFAULT from the first fo_ioctl(,USB_GET_REPORT_DESC,) call. If I use kern_ioctl() instead of js_kern_ioctl() it "works" in exactly the same way.

Am I missing something? Mostly the same code does well outside the kernel space (libusbhid / hid_get_report_desc() / usbhidctl -r).

FreeBSD 9.1-STABLE r248950M: amd64, gcc 4.2.1

Please, help.
 
Back
Top