| 589 | } |
| 590 | |
| 591 | static int |
| 592 | shm_copyin_path(struct thread *td, const char *userpath_in, char **path_out) { |
| 593 | int error; |
| 594 | char *path; |
| 595 | const char *pr_path; |
| 596 | size_t pr_pathlen; |
| 597 | |
| 598 | path = malloc(MAXPATHLEN, M_SHMFD, M_WAITOK); |
| 599 | pr_path = td->td_ucred->cr_prison->pr_path; |
| 600 | |
| 601 | /* Construct a full pathname for jailed callers. */ |
| 602 | pr_pathlen = strcmp(pr_path, "/") == |
| 603 | 0 ? 0 : strlcpy(path, pr_path, MAXPATHLEN); |
| 604 | error = copyinstr(userpath_in, path + pr_pathlen, |
| 605 | MAXPATHLEN - pr_pathlen, NULL); |
| 606 | if (error != 0) |
| 607 | goto out; |
| 608 | |
| 609 | #ifdef KTRACE |
| 610 | if (KTRPOINT(curthread, KTR_NAMEI)) |
| 611 | ktrnamei(path); |
| 612 | #endif |
| 613 | |
| 614 | /* Require paths to start with a '/' character. */ |
| 615 | if (path[pr_pathlen] != '/') { |
| 616 | error = EINVAL; |
| 617 | goto out; |
| 618 | } |
| 619 | |
| 620 | *path_out = path; |
| 621 | |
| 622 | out: |
| 623 | if (error != 0) |
| 624 | free(path, M_SHMFD); |
| 625 | |
| 626 | return (error); |
| 627 | } |
| 628 | |
| 629 | static int |
| 630 | shm_dotruncate_locked(struct shmfd *shmfd, off_t length, void *rl_cookie) |