- retval = copy_strings_kernel(1, &bprm->interp, bprm);
- if (retval < 0) goto _ret;
- bprm->argc++;
- retval = copy_strings_kernel(1, &iname_addr, bprm);
- if (retval < 0) goto _ret;
+
+ if (fmt->flags & MISC_FMT_OPEN_BINARY) {
+
+ files = current->files;
+ retval = unshare_files();
+ if (retval < 0)
+ goto _ret;
+ if (files == current->files) {
+ put_files_struct(files);
+ files = NULL;
+ }
+ /* if the binary should be opened on behalf of the
+ * interpreter than keep it open and assign descriptor
+ * to it */
+ fd_binary = get_unused_fd();
+ if (fd_binary < 0) {
+ retval = fd_binary;
+ goto _unshare;
+ }
+ fd_install(fd_binary, bprm->file);
+
+ /* if the binary is not readable than enforce mm->dumpable=0
+ regardless of the interpreter's permissions */
+ if (file_permission(bprm->file, MAY_READ))
+ bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
+
+ allow_write_access(bprm->file);
+ bprm->file = NULL;
+
+ /* mark the bprm that fd should be passed to interp */
+ bprm->interp_flags |= BINPRM_FLAGS_EXECFD;
+ bprm->interp_data = fd_binary;
+
+ } else {
+ allow_write_access(bprm->file);
+ fput(bprm->file);
+ bprm->file = NULL;
+ }
+ /* make argv[1] be the path to the binary */
+ retval = copy_strings_kernel (1, &bprm->interp, bprm);
+ if (retval < 0)
+ goto _error;