tree: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-3.16.y head: 0b9f4cdd4d75131d8886b919bbf6e0c98906d36e commit: 61aa1e63c06961e77b6f63823e05af637c1e3acd [3475/3488] usbip: fix stub_rx: harden CMD_SUBMIT path to handle malicious input
smatch warnings: drivers/staging/usbip/stub_rx.c:360 get_pipe() warn: impossible condition '(pdu->u.cmd_submit.transfer_buffer_length > ((~0 >> 1))) => (s32min-s32max > s32max)' drivers/staging/usbip/stub_rx.c:501 stub_recv_cmd_submit() warn: always true condition '(pdu->u.cmd_submit.transfer_buffer_length <= ((~0 >> 1))) => (s32min-s32max <= s32max)' # https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/commit/?id=61aa1e63c06961e77b6f63823e05af637c1e3acd git remote add linux-stable-rc https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git git remote update linux-stable-rc git checkout 61aa1e63c06961e77b6f63823e05af637c1e3acd vim +360 drivers/staging/usbip/stub_rx.c 4d7b5c7f Takahiro Hirofuchi 2008-07-09 338 61aa1e63 Shuah Khan 2017-12-07 339 static int get_pipe(struct stub_device *sdev, struct usbip_header *pdu) 4d7b5c7f Takahiro Hirofuchi 2008-07-09 340 { 2d8f4595 Max Vozeler 2011-01-12 341 struct usb_device *udev = sdev->udev; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 342 struct usb_host_endpoint *ep; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 343 struct usb_endpoint_descriptor *epd = NULL; 61aa1e63 Shuah Khan 2017-12-07 344 int epnum = pdu->base.ep; 61aa1e63 Shuah Khan 2017-12-07 345 int dir = pdu->base.direction; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 346 65060ba2 Shuah Khan 2017-12-07 347 if (epnum < 0 || epnum > 15) 65060ba2 Shuah Khan 2017-12-07 348 goto err_ret; 65060ba2 Shuah Khan 2017-12-07 349 ab30f12d Endre Kollar 2010-07-27 350 if (dir == USBIP_DIR_IN) ab30f12d Endre Kollar 2010-07-27 351 ep = udev->ep_in[epnum & 0x7f]; ab30f12d Endre Kollar 2010-07-27 352 else ab30f12d Endre Kollar 2010-07-27 353 ep = udev->ep_out[epnum & 0x7f]; 65060ba2 Shuah Khan 2017-12-07 354 if (!ep) 65060ba2 Shuah Khan 2017-12-07 355 goto err_ret; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 356 4d7b5c7f Takahiro Hirofuchi 2008-07-09 357 epd = &ep->desc; 61aa1e63 Shuah Khan 2017-12-07 358 61aa1e63 Shuah Khan 2017-12-07 359 /* validate transfer_buffer_length */ 61aa1e63 Shuah Khan 2017-12-07 @360 if (pdu->u.cmd_submit.transfer_buffer_length > INT_MAX) { 61aa1e63 Shuah Khan 2017-12-07 361 dev_err(&sdev->udev->dev, 61aa1e63 Shuah Khan 2017-12-07 362 "CMD_SUBMIT: -EMSGSIZE transfer_buffer_length %d\n", 61aa1e63 Shuah Khan 2017-12-07 363 pdu->u.cmd_submit.transfer_buffer_length); 61aa1e63 Shuah Khan 2017-12-07 364 return -1; 61aa1e63 Shuah Khan 2017-12-07 365 } 61aa1e63 Shuah Khan 2017-12-07 366 4d7b5c7f Takahiro Hirofuchi 2008-07-09 367 if (usb_endpoint_xfer_control(epd)) { 4d7b5c7f Takahiro Hirofuchi 2008-07-09 368 if (dir == USBIP_DIR_OUT) 4d7b5c7f Takahiro Hirofuchi 2008-07-09 369 return usb_sndctrlpipe(udev, epnum); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 370 else 4d7b5c7f Takahiro Hirofuchi 2008-07-09 371 return usb_rcvctrlpipe(udev, epnum); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 372 } 4d7b5c7f Takahiro Hirofuchi 2008-07-09 373 4d7b5c7f Takahiro Hirofuchi 2008-07-09 374 if (usb_endpoint_xfer_bulk(epd)) { 4d7b5c7f Takahiro Hirofuchi 2008-07-09 375 if (dir == USBIP_DIR_OUT) 4d7b5c7f Takahiro Hirofuchi 2008-07-09 376 return usb_sndbulkpipe(udev, epnum); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 377 else 4d7b5c7f Takahiro Hirofuchi 2008-07-09 378 return usb_rcvbulkpipe(udev, epnum); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 379 } 4d7b5c7f Takahiro Hirofuchi 2008-07-09 380 4d7b5c7f Takahiro Hirofuchi 2008-07-09 381 if (usb_endpoint_xfer_int(epd)) { 4d7b5c7f Takahiro Hirofuchi 2008-07-09 382 if (dir == USBIP_DIR_OUT) 4d7b5c7f Takahiro Hirofuchi 2008-07-09 383 return usb_sndintpipe(udev, epnum); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 384 else 4d7b5c7f Takahiro Hirofuchi 2008-07-09 385 return usb_rcvintpipe(udev, epnum); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 386 } 4d7b5c7f Takahiro Hirofuchi 2008-07-09 387 4d7b5c7f Takahiro Hirofuchi 2008-07-09 388 if (usb_endpoint_xfer_isoc(epd)) { 61aa1e63 Shuah Khan 2017-12-07 389 /* validate packet size and number of packets */ 61aa1e63 Shuah Khan 2017-12-07 390 unsigned int maxp, packets, bytes; 61aa1e63 Shuah Khan 2017-12-07 391 61aa1e63 Shuah Khan 2017-12-07 392 maxp = usb_endpoint_maxp(epd); 61aa1e63 Shuah Khan 2017-12-07 393 maxp *= usb_endpoint_maxp_mult(epd); 61aa1e63 Shuah Khan 2017-12-07 394 bytes = pdu->u.cmd_submit.transfer_buffer_length; 61aa1e63 Shuah Khan 2017-12-07 395 packets = DIV_ROUND_UP(bytes, maxp); 61aa1e63 Shuah Khan 2017-12-07 396 61aa1e63 Shuah Khan 2017-12-07 397 if (pdu->u.cmd_submit.number_of_packets < 0 || 61aa1e63 Shuah Khan 2017-12-07 398 pdu->u.cmd_submit.number_of_packets > packets) { 61aa1e63 Shuah Khan 2017-12-07 399 dev_err(&sdev->udev->dev, 61aa1e63 Shuah Khan 2017-12-07 400 "CMD_SUBMIT: isoc invalid num packets %d\n", 61aa1e63 Shuah Khan 2017-12-07 401 pdu->u.cmd_submit.number_of_packets); 61aa1e63 Shuah Khan 2017-12-07 402 return -1; 61aa1e63 Shuah Khan 2017-12-07 403 } 4d7b5c7f Takahiro Hirofuchi 2008-07-09 404 if (dir == USBIP_DIR_OUT) 4d7b5c7f Takahiro Hirofuchi 2008-07-09 405 return usb_sndisocpipe(udev, epnum); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 406 else 4d7b5c7f Takahiro Hirofuchi 2008-07-09 407 return usb_rcvisocpipe(udev, epnum); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 408 } 4d7b5c7f Takahiro Hirofuchi 2008-07-09 409 65060ba2 Shuah Khan 2017-12-07 410 err_ret: 4d7b5c7f Takahiro Hirofuchi 2008-07-09 411 /* NOT REACHED */ 61aa1e63 Shuah Khan 2017-12-07 412 dev_err(&sdev->udev->dev, "CMD_SUBMIT: invalid epnum %d\n", epnum); 65060ba2 Shuah Khan 2017-12-07 413 return -1; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 414 } 4d7b5c7f Takahiro Hirofuchi 2008-07-09 415 b7a937e9 Endre Kollar 2010-07-27 416 static void masking_bogus_flags(struct urb *urb) b7a937e9 Endre Kollar 2010-07-27 417 { b7a937e9 Endre Kollar 2010-07-27 418 int xfertype; b7a937e9 Endre Kollar 2010-07-27 419 struct usb_device *dev; b7a937e9 Endre Kollar 2010-07-27 420 struct usb_host_endpoint *ep; b7a937e9 Endre Kollar 2010-07-27 421 int is_out; b7a937e9 Endre Kollar 2010-07-27 422 unsigned int allowed; b7a937e9 Endre Kollar 2010-07-27 423 b7a937e9 Endre Kollar 2010-07-27 424 if (!urb || urb->hcpriv || !urb->complete) b7a937e9 Endre Kollar 2010-07-27 425 return; b7a937e9 Endre Kollar 2010-07-27 426 dev = urb->dev; b7a937e9 Endre Kollar 2010-07-27 427 if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED)) b7a937e9 Endre Kollar 2010-07-27 428 return; b7a937e9 Endre Kollar 2010-07-27 429 b7a937e9 Endre Kollar 2010-07-27 430 ep = (usb_pipein(urb->pipe) ? dev->ep_in : dev->ep_out) b7a937e9 Endre Kollar 2010-07-27 431 [usb_pipeendpoint(urb->pipe)]; b7a937e9 Endre Kollar 2010-07-27 432 if (!ep) b7a937e9 Endre Kollar 2010-07-27 433 return; b7a937e9 Endre Kollar 2010-07-27 434 b7a937e9 Endre Kollar 2010-07-27 435 xfertype = usb_endpoint_type(&ep->desc); b7a937e9 Endre Kollar 2010-07-27 436 if (xfertype == USB_ENDPOINT_XFER_CONTROL) { b7a937e9 Endre Kollar 2010-07-27 437 struct usb_ctrlrequest *setup = b7a937e9 Endre Kollar 2010-07-27 438 (struct usb_ctrlrequest *) urb->setup_packet; b7a937e9 Endre Kollar 2010-07-27 439 b7a937e9 Endre Kollar 2010-07-27 440 if (!setup) b7a937e9 Endre Kollar 2010-07-27 441 return; b7a937e9 Endre Kollar 2010-07-27 442 is_out = !(setup->bRequestType & USB_DIR_IN) || b7a937e9 Endre Kollar 2010-07-27 443 !setup->wLength; b7a937e9 Endre Kollar 2010-07-27 444 } else { b7a937e9 Endre Kollar 2010-07-27 445 is_out = usb_endpoint_dir_out(&ep->desc); b7a937e9 Endre Kollar 2010-07-27 446 } b7a937e9 Endre Kollar 2010-07-27 447 b7a937e9 Endre Kollar 2010-07-27 448 /* enforce simple/standard policy */ 3924865f Greg Kroah-Hartman 2010-07-27 449 allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT | 3924865f Greg Kroah-Hartman 2010-07-27 450 URB_DIR_MASK | URB_FREE_BUFFER); b7a937e9 Endre Kollar 2010-07-27 451 switch (xfertype) { b7a937e9 Endre Kollar 2010-07-27 452 case USB_ENDPOINT_XFER_BULK: b7a937e9 Endre Kollar 2010-07-27 453 if (is_out) b7a937e9 Endre Kollar 2010-07-27 454 allowed |= URB_ZERO_PACKET; b7a937e9 Endre Kollar 2010-07-27 455 /* FALLTHROUGH */ b7a937e9 Endre Kollar 2010-07-27 456 case USB_ENDPOINT_XFER_CONTROL: b7a937e9 Endre Kollar 2010-07-27 457 allowed |= URB_NO_FSBR; /* only affects UHCI */ b7a937e9 Endre Kollar 2010-07-27 458 /* FALLTHROUGH */ b7a937e9 Endre Kollar 2010-07-27 459 default: /* all non-iso endpoints */ b7a937e9 Endre Kollar 2010-07-27 460 if (!is_out) b7a937e9 Endre Kollar 2010-07-27 461 allowed |= URB_SHORT_NOT_OK; b7a937e9 Endre Kollar 2010-07-27 462 break; b7a937e9 Endre Kollar 2010-07-27 463 case USB_ENDPOINT_XFER_ISOC: b7a937e9 Endre Kollar 2010-07-27 464 allowed |= URB_ISO_ASAP; b7a937e9 Endre Kollar 2010-07-27 465 break; b7a937e9 Endre Kollar 2010-07-27 466 } b7a937e9 Endre Kollar 2010-07-27 467 urb->transfer_flags &= allowed; b7a937e9 Endre Kollar 2010-07-27 468 } b7a937e9 Endre Kollar 2010-07-27 469 4d7b5c7f Takahiro Hirofuchi 2008-07-09 470 static void stub_recv_cmd_submit(struct stub_device *sdev, 4d7b5c7f Takahiro Hirofuchi 2008-07-09 471 struct usbip_header *pdu) 4d7b5c7f Takahiro Hirofuchi 2008-07-09 472 { 4d7b5c7f Takahiro Hirofuchi 2008-07-09 473 int ret; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 474 struct stub_priv *priv; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 475 struct usbip_device *ud = &sdev->ud; 2d8f4595 Max Vozeler 2011-01-12 476 struct usb_device *udev = sdev->udev; 61aa1e63 Shuah Khan 2017-12-07 477 int pipe = get_pipe(sdev, pdu); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 478 65060ba2 Shuah Khan 2017-12-07 479 if (pipe == -1) 65060ba2 Shuah Khan 2017-12-07 480 return; 65060ba2 Shuah Khan 2017-12-07 481 4d7b5c7f Takahiro Hirofuchi 2008-07-09 482 priv = stub_priv_alloc(sdev, pdu); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 483 if (!priv) 4d7b5c7f Takahiro Hirofuchi 2008-07-09 484 return; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 485 4d7b5c7f Takahiro Hirofuchi 2008-07-09 486 /* setup a urb */ 4d7b5c7f Takahiro Hirofuchi 2008-07-09 487 if (usb_pipeisoc(pipe)) 4d7b5c7f Takahiro Hirofuchi 2008-07-09 488 priv->urb = usb_alloc_urb(pdu->u.cmd_submit.number_of_packets, 4d7b5c7f Takahiro Hirofuchi 2008-07-09 489 GFP_KERNEL); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 490 else 4d7b5c7f Takahiro Hirofuchi 2008-07-09 491 priv->urb = usb_alloc_urb(0, GFP_KERNEL); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 492 4d7b5c7f Takahiro Hirofuchi 2008-07-09 493 if (!priv->urb) { d848638a Alexander Popov 2016-04-28 494 dev_err(&udev->dev, "malloc urb\n"); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 495 usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 496 return; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 497 } 4d7b5c7f Takahiro Hirofuchi 2008-07-09 498 c7f00899 Bart Westgeest 2012-10-10 499 /* allocate urb transfer buffer, if needed */ 61aa1e63 Shuah Khan 2017-12-07 500 if (pdu->u.cmd_submit.transfer_buffer_length > 0 && 61aa1e63 Shuah Khan 2017-12-07 @501 pdu->u.cmd_submit.transfer_buffer_length <= INT_MAX) { 4d7b5c7f Takahiro Hirofuchi 2008-07-09 502 priv->urb->transfer_buffer = 4d7b5c7f Takahiro Hirofuchi 2008-07-09 503 kzalloc(pdu->u.cmd_submit.transfer_buffer_length, 4d7b5c7f Takahiro Hirofuchi 2008-07-09 504 GFP_KERNEL); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 505 if (!priv->urb->transfer_buffer) { 4d7b5c7f Takahiro Hirofuchi 2008-07-09 506 usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 507 return; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 508 } 4d7b5c7f Takahiro Hirofuchi 2008-07-09 509 } 4d7b5c7f Takahiro Hirofuchi 2008-07-09 510 c7f00899 Bart Westgeest 2012-10-10 511 /* copy urb setup packet */ 94002c07 Julia Lawall 2010-05-15 512 priv->urb->setup_packet = kmemdup(&pdu->u.cmd_submit.setup, 8, 94002c07 Julia Lawall 2010-05-15 513 GFP_KERNEL); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 514 if (!priv->urb->setup_packet) { d848638a Alexander Popov 2016-04-28 515 dev_err(&udev->dev, "allocate setup_packet\n"); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 516 usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 517 return; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 518 } 4d7b5c7f Takahiro Hirofuchi 2008-07-09 519 4d7b5c7f Takahiro Hirofuchi 2008-07-09 520 /* set other members from the base header of pdu */ 4d7b5c7f Takahiro Hirofuchi 2008-07-09 521 priv->urb->context = (void *) priv; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 522 priv->urb->dev = udev; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 523 priv->urb->pipe = pipe; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 524 priv->urb->complete = stub_complete; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 525 4d7b5c7f Takahiro Hirofuchi 2008-07-09 526 usbip_pack_pdu(pdu, priv->urb, USBIP_CMD_SUBMIT, 0); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 527 4d7b5c7f Takahiro Hirofuchi 2008-07-09 528 4d7b5c7f Takahiro Hirofuchi 2008-07-09 529 if (usbip_recv_xbuff(ud, priv->urb) < 0) 4d7b5c7f Takahiro Hirofuchi 2008-07-09 530 return; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 531 4d7b5c7f Takahiro Hirofuchi 2008-07-09 532 if (usbip_recv_iso(ud, priv->urb) < 0) 4d7b5c7f Takahiro Hirofuchi 2008-07-09 533 return; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 534 4d7b5c7f Takahiro Hirofuchi 2008-07-09 535 /* no need to submit an intercepted request, but harmless? */ 4d7b5c7f Takahiro Hirofuchi 2008-07-09 536 tweak_special_requests(priv->urb); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 537 b7a937e9 Endre Kollar 2010-07-27 538 masking_bogus_flags(priv->urb); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 539 /* urb is now ready to submit */ 4d7b5c7f Takahiro Hirofuchi 2008-07-09 540 ret = usb_submit_urb(priv->urb, GFP_KERNEL); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 541 4d7b5c7f Takahiro Hirofuchi 2008-07-09 542 if (ret == 0) b8868e45 Brian G. Merrell 2009-07-21 543 usbip_dbg_stub_rx("submit urb ok, seqnum %u\n", b8868e45 Brian G. Merrell 2009-07-21 544 pdu->base.seqnum); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 545 else { d848638a Alexander Popov 2016-04-28 546 dev_err(&udev->dev, "submit_urb error, %d\n", ret); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 547 usbip_dump_header(pdu); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 548 usbip_dump_urb(priv->urb); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 549 4d7b5c7f Takahiro Hirofuchi 2008-07-09 550 /* 4d7b5c7f Takahiro Hirofuchi 2008-07-09 551 * Pessimistic. 4d7b5c7f Takahiro Hirofuchi 2008-07-09 552 * This connection will be discarded. 4d7b5c7f Takahiro Hirofuchi 2008-07-09 553 */ 4d7b5c7f Takahiro Hirofuchi 2008-07-09 554 usbip_event_add(ud, SDEV_EVENT_ERROR_SUBMIT); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 555 } 4d7b5c7f Takahiro Hirofuchi 2008-07-09 556 b8868e45 Brian G. Merrell 2009-07-21 557 usbip_dbg_stub_rx("Leave\n"); 4d7b5c7f Takahiro Hirofuchi 2008-07-09 558 return; 4d7b5c7f Takahiro Hirofuchi 2008-07-09 559 } 4d7b5c7f Takahiro Hirofuchi 2008-07-09 560 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation _______________________________________________ kbuild mailing list kbuild@lists.01.org https://lists.01.org/mailman/listinfo/kbuild