| 225 | } |
| 226 | |
| 227 | int |
| 228 | sys___mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) |
| 229 | { |
| 230 | char *elements, *buffer; |
| 231 | struct label *intlabel; |
| 232 | struct file *fp; |
| 233 | struct mac mac; |
| 234 | struct vnode *vp; |
| 235 | struct pipe *pipe; |
| 236 | struct socket *so; |
| 237 | cap_rights_t rights; |
| 238 | int error; |
| 239 | |
| 240 | error = copyin(uap->mac_p, &mac, sizeof(mac)); |
| 241 | if (error) |
| 242 | return (error); |
| 243 | |
| 244 | error = mac_check_structmac_consistent(&mac); |
| 245 | if (error) |
| 246 | return (error); |
| 247 | |
| 248 | elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); |
| 249 | error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); |
| 250 | if (error) { |
| 251 | free(elements, M_MACTEMP); |
| 252 | return (error); |
| 253 | } |
| 254 | |
| 255 | buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); |
| 256 | error = fget(td, uap->fd, cap_rights_init_one(&rights, CAP_MAC_GET), |
| 257 | &fp); |
| 258 | if (error) |
| 259 | goto out; |
| 260 | |
| 261 | switch (fp->f_type) { |
| 262 | case DTYPE_FIFO: |
| 263 | case DTYPE_VNODE: |
| 264 | if (!(mac_labeled & MPC_OBJECT_VNODE)) { |
| 265 | error = EINVAL; |
| 266 | goto out_fdrop; |
| 267 | } |
| 268 | vp = fp->f_vnode; |
| 269 | intlabel = mac_vnode_label_alloc(); |
| 270 | vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
| 271 | mac_vnode_copy_label(vp->v_label, intlabel); |
| 272 | VOP_UNLOCK(vp); |
| 273 | error = mac_vnode_externalize_label(intlabel, elements, |
| 274 | buffer, mac.m_buflen); |
| 275 | mac_vnode_label_free(intlabel); |
| 276 | break; |
| 277 | |
| 278 | case DTYPE_PIPE: |
| 279 | if (!(mac_labeled & MPC_OBJECT_PIPE)) { |
| 280 | error = EINVAL; |
| 281 | goto out_fdrop; |
| 282 | } |
| 283 | pipe = fp->f_data; |
| 284 | intlabel = mac_pipe_label_alloc(); |
nothing calls this directly
no test coverage detected