| 1092 | } |
| 1093 | |
| 1094 | int |
| 1095 | kern_openat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, |
| 1096 | int flags, int mode) |
| 1097 | { |
| 1098 | struct proc *p = td->td_proc; |
| 1099 | struct filedesc *fdp; |
| 1100 | struct pwddesc *pdp; |
| 1101 | struct file *fp; |
| 1102 | struct vnode *vp; |
| 1103 | struct nameidata nd; |
| 1104 | cap_rights_t rights; |
| 1105 | int cmode, error, indx; |
| 1106 | |
| 1107 | indx = -1; |
| 1108 | fdp = p->p_fd; |
| 1109 | pdp = p->p_pd; |
| 1110 | |
| 1111 | AUDIT_ARG_FFLAGS(flags); |
| 1112 | AUDIT_ARG_MODE(mode); |
| 1113 | cap_rights_init_one(&rights, CAP_LOOKUP); |
| 1114 | flags_to_rights(flags, &rights); |
| 1115 | /* |
| 1116 | * Only one of the O_EXEC, O_RDONLY, O_WRONLY and O_RDWR flags |
| 1117 | * may be specified. |
| 1118 | */ |
| 1119 | if (flags & O_EXEC) { |
| 1120 | if (flags & O_ACCMODE) |
| 1121 | return (EINVAL); |
| 1122 | } else if ((flags & O_ACCMODE) == O_ACCMODE) { |
| 1123 | return (EINVAL); |
| 1124 | } else { |
| 1125 | flags = FFLAGS(flags); |
| 1126 | } |
| 1127 | |
| 1128 | /* |
| 1129 | * Allocate a file structure. The descriptor to reference it |
| 1130 | * is allocated and used by finstall_refed() below. |
| 1131 | */ |
| 1132 | error = falloc_noinstall(td, &fp); |
| 1133 | if (error != 0) |
| 1134 | return (error); |
| 1135 | /* Set the flags early so the finit in devfs can pick them up. */ |
| 1136 | fp->f_flag = flags & FMASK; |
| 1137 | cmode = ((mode & ~pdp->pd_cmask) & ALLPERMS) & ~S_ISTXT; |
| 1138 | NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, fd, |
| 1139 | &rights, td); |
| 1140 | td->td_dupfd = -1; /* XXX check for fdopen */ |
| 1141 | error = vn_open(&nd, &flags, cmode, fp); |
| 1142 | if (error != 0) { |
| 1143 | /* |
| 1144 | * If the vn_open replaced the method vector, something |
| 1145 | * wonderous happened deep below and we just pass it up |
| 1146 | * pretending we know what we do. |
| 1147 | */ |
| 1148 | if (error == ENXIO && fp->f_ops != &badfileops) |
| 1149 | goto success; |
| 1150 | |
| 1151 | /* |
no test coverage detected