- * Extract the CodeDirectory of the vnode associated with
- * the file descriptor and copy it back to user space
- */
- case F_GETCODEDIR: {
- struct user_fcodeblobs args;
-
- if (fp->f_type != DTYPE_VNODE) {
- error = EBADF;
- goto out;
- }
-
- vp = (struct vnode *)fp->f_data;
- proc_fdunlock(p);
-
- if ((fp->f_flag & FREAD) == 0) {
- error = EBADF;
- goto outdrop;
- }
-
- if (IS_64BIT_PROCESS(p)) {
- struct user64_fcodeblobs args64;
-
- error = copyin(argp, &args64, sizeof(args64));
- if (error)
- goto outdrop;
-
- args.f_cd_hash = args64.f_cd_hash;
- args.f_hash_size = args64.f_hash_size;
- args.f_cd_buffer = args64.f_cd_buffer;
- args.f_cd_size = args64.f_cd_size;
- args.f_out_size = args64.f_out_size;
- args.f_arch = args64.f_arch;
- } else {
- struct user32_fcodeblobs args32;
-
- error = copyin(argp, &args32, sizeof(args32));
- if (error)
- goto outdrop;
-
- args.f_cd_hash = CAST_USER_ADDR_T(args32.f_cd_hash);
- args.f_hash_size = args32.f_hash_size;
- args.f_cd_buffer = CAST_USER_ADDR_T(args32.f_cd_buffer);
- args.f_cd_size = args32.f_cd_size;
- args.f_out_size = CAST_USER_ADDR_T(args32.f_out_size);
- args.f_arch = args32.f_arch;
- }
-
- if (vp->v_ubcinfo == NULL) {
- error = EINVAL;
- goto outdrop;
- }
-
- struct cs_blob *t_blob = vp->v_ubcinfo->cs_blobs;
-
- /*
- * This call fails if there is no cs_blob corresponding to the
- * vnode, or if there are multiple cs_blobs present, and the caller
- * did not specify which cpu_type they want the cs_blob for
- */
- if (t_blob == NULL) {
- error = ENOENT; /* there is no codesigning blob for this process */
- goto outdrop;
- } else if (args.f_arch == 0 && t_blob->csb_next != NULL) {
- error = ENOENT; /* too many architectures and none specified */
- goto outdrop;
- }
-
- /* If the user specified an architecture, find the right blob */
- if (args.f_arch != 0) {
- while (t_blob) {
- if (t_blob->csb_cpu_type == args.f_arch)
- break;
- t_blob = t_blob->csb_next;
- }
- /* The cpu_type the user requested could not be found */
- if (t_blob == NULL) {
- error = ENOENT;
- goto outdrop;
- }
- }
-
- const CS_SuperBlob *super_blob = (void *)t_blob->csb_mem_kaddr;
- const CS_CodeDirectory *cd = findCodeDirectory(super_blob,
- (const char *) super_blob,
- (const char *) super_blob + t_blob->csb_mem_size);
- if (cd == NULL) {
- error = ENOENT;
- goto outdrop;
- }
-
- uint64_t buffer_size = ntohl(cd->length);
-
- if (buffer_size > UINT_MAX) {
- error = ERANGE;
- goto outdrop;
- }
-
- error = copyout(&buffer_size, args.f_out_size, sizeof(unsigned int));
- if (error)
- goto outdrop;
-
- if (sizeof(t_blob->csb_cdhash) > args.f_hash_size ||
- buffer_size > args.f_cd_size) {
- error = ERANGE;
- goto outdrop;
- }
-
- error = copyout(t_blob->csb_cdhash, args.f_cd_hash, sizeof(t_blob->csb_cdhash));
- if (error)
- goto outdrop;
- error = copyout(cd, args.f_cd_buffer, buffer_size);
- if (error)
- goto outdrop;
-
- break;
- }
-
- /*