| 1028 | } |
| 1029 | |
| 1030 | int |
| 1031 | kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode, |
| 1032 | int shmflags, struct filecaps *fcaps, const char *name __unused) |
| 1033 | { |
| 1034 | struct pwddesc *pdp; |
| 1035 | struct shmfd *shmfd; |
| 1036 | struct file *fp; |
| 1037 | char *path; |
| 1038 | void *rl_cookie; |
| 1039 | Fnv32_t fnv; |
| 1040 | mode_t cmode; |
| 1041 | int error, fd, initial_seals; |
| 1042 | bool largepage; |
| 1043 | |
| 1044 | if ((shmflags & ~(SHM_ALLOW_SEALING | SHM_GROW_ON_WRITE | |
| 1045 | SHM_LARGEPAGE)) != 0) |
| 1046 | return (EINVAL); |
| 1047 | |
| 1048 | initial_seals = F_SEAL_SEAL; |
| 1049 | if ((shmflags & SHM_ALLOW_SEALING) != 0) |
| 1050 | initial_seals &= ~F_SEAL_SEAL; |
| 1051 | |
| 1052 | #ifdef CAPABILITY_MODE |
| 1053 | /* |
| 1054 | * shm_open(2) is only allowed for anonymous objects. |
| 1055 | */ |
| 1056 | if (IN_CAPABILITY_MODE(td) && (userpath != SHM_ANON)) |
| 1057 | return (ECAPMODE); |
| 1058 | #endif |
| 1059 | |
| 1060 | AUDIT_ARG_FFLAGS(flags); |
| 1061 | AUDIT_ARG_MODE(mode); |
| 1062 | |
| 1063 | if ((flags & O_ACCMODE) != O_RDONLY && (flags & O_ACCMODE) != O_RDWR) |
| 1064 | return (EINVAL); |
| 1065 | |
| 1066 | if ((flags & ~(O_ACCMODE | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC)) != 0) |
| 1067 | return (EINVAL); |
| 1068 | |
| 1069 | largepage = (shmflags & SHM_LARGEPAGE) != 0; |
| 1070 | if (largepage && !PMAP_HAS_LARGEPAGES) |
| 1071 | return (ENOTTY); |
| 1072 | |
| 1073 | /* |
| 1074 | * Currently only F_SEAL_SEAL may be set when creating or opening shmfd. |
| 1075 | * If the decision is made later to allow additional seals, care must be |
| 1076 | * taken below to ensure that the seals are properly set if the shmfd |
| 1077 | * already existed -- this currently assumes that only F_SEAL_SEAL can |
| 1078 | * be set and doesn't take further precautions to ensure the validity of |
| 1079 | * the seals being added with respect to current mappings. |
| 1080 | */ |
| 1081 | if ((initial_seals & ~F_SEAL_SEAL) != 0) |
| 1082 | return (EINVAL); |
| 1083 | |
| 1084 | pdp = td->td_proc->p_pd; |
| 1085 | cmode = (mode & ~pdp->pd_cmask) & ACCESSPERMS; |
| 1086 | |
| 1087 | /* |
no test coverage detected