| 485 | } |
| 486 | |
| 487 | int |
| 488 | sys_cap_ioctls_get(struct thread *td, struct cap_ioctls_get_args *uap) |
| 489 | { |
| 490 | struct filedesc *fdp; |
| 491 | struct filedescent *fdep; |
| 492 | u_long *cmdsp, *dstcmds; |
| 493 | size_t maxcmds, ncmds; |
| 494 | int16_t count; |
| 495 | int error, fd; |
| 496 | |
| 497 | fd = uap->fd; |
| 498 | dstcmds = uap->cmds; |
| 499 | maxcmds = uap->maxcmds; |
| 500 | |
| 501 | AUDIT_ARG_FD(fd); |
| 502 | |
| 503 | fdp = td->td_proc->p_fd; |
| 504 | |
| 505 | cmdsp = NULL; |
| 506 | if (dstcmds != NULL) { |
| 507 | cmdsp = malloc(sizeof(cmdsp[0]) * IOCTLS_MAX_COUNT, M_FILECAPS, |
| 508 | M_WAITOK | M_ZERO); |
| 509 | } |
| 510 | |
| 511 | FILEDESC_SLOCK(fdp); |
| 512 | fdep = fdeget_locked(fdp, fd); |
| 513 | if (fdep == NULL) { |
| 514 | error = EBADF; |
| 515 | FILEDESC_SUNLOCK(fdp); |
| 516 | goto out; |
| 517 | } |
| 518 | count = fdep->fde_nioctls; |
| 519 | if (count != -1 && cmdsp != NULL) { |
| 520 | ncmds = MIN(count, maxcmds); |
| 521 | memcpy(cmdsp, fdep->fde_ioctls, sizeof(cmdsp[0]) * ncmds); |
| 522 | } |
| 523 | FILEDESC_SUNLOCK(fdp); |
| 524 | |
| 525 | /* |
| 526 | * If all ioctls are allowed (fde_nioctls == -1 && fde_ioctls == NULL) |
| 527 | * the only sane thing we can do is to not populate the given array and |
| 528 | * return CAP_IOCTLS_ALL. |
| 529 | */ |
| 530 | if (count != -1) { |
| 531 | if (cmdsp != NULL) { |
| 532 | error = copyout(cmdsp, dstcmds, |
| 533 | sizeof(cmdsp[0]) * ncmds); |
| 534 | if (error != 0) |
| 535 | goto out; |
| 536 | } |
| 537 | td->td_retval[0] = count; |
| 538 | } else { |
| 539 | td->td_retval[0] = CAP_IOCTLS_ALL; |
| 540 | } |
| 541 | |
| 542 | error = 0; |
| 543 | out: |
| 544 | free(cmdsp, M_FILECAPS); |
nothing calls this directly
no test coverage detected