Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit df88912a authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds
Browse files

[PATCH] binfmt_flat: don't check for EMFILE



Bernd Schmidt points out that binfmt_flat is now leaving the exec file open
while the application runs.  This offsets all the application's fd numbers.
We should have closed the file within exec(), not at exit()-time.

But there doesn't seem to be a lot of point in doing all this just to avoid
going over RLIMIT_NOFILE by one fd for a few microseconds.  So take the EMFILE
checking out again.  This will cause binfmt_flat to again fail LTP's
exec-should-return-EMFILE-when-fdtable-is-full test.  That test appears to be
wrong anyway - Open Group specs say nothing about exec() returning EMFILE.

Cc: Bernd Schmidt <bernd.schmidt@analog.com>
Cc: Greg Ungerer <gerg@uclinux.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 48d70552
Loading
Loading
Loading
Loading
+9 −21
Original line number Original line Diff line number Diff line
@@ -428,7 +428,6 @@ static int load_flat_file(struct linux_binprm * bprm,
	loff_t fpos;
	loff_t fpos;
	unsigned long start_code, end_code;
	unsigned long start_code, end_code;
	int ret;
	int ret;
	int exec_fileno;


	hdr = ((struct flat_hdr *) bprm->buf);		/* exec-header */
	hdr = ((struct flat_hdr *) bprm->buf);		/* exec-header */
	inode = bprm->file->f_dentry->d_inode;
	inode = bprm->file->f_dentry->d_inode;
@@ -502,21 +501,12 @@ static int load_flat_file(struct linux_binprm * bprm,
		goto err;
		goto err;
	}
	}


	/* check file descriptor */
	exec_fileno = get_unused_fd();
	if (exec_fileno < 0) {
		ret = -EMFILE;
		goto err;
	}
	get_file(bprm->file);
	fd_install(exec_fileno, bprm->file);

	/* Flush all traces of the currently running executable */
	/* Flush all traces of the currently running executable */
	if (id == 0) {
	if (id == 0) {
		result = flush_old_exec(bprm);
		result = flush_old_exec(bprm);
		if (result) {
		if (result) {
			ret = result;
			ret = result;
			goto err_close;
			goto err;
		}
		}


		/* OK, This is the point of no return */
		/* OK, This is the point of no return */
@@ -548,7 +538,7 @@ static int load_flat_file(struct linux_binprm * bprm,
				textpos = (unsigned long) -ENOMEM;
				textpos = (unsigned long) -ENOMEM;
			printk("Unable to mmap process text, errno %d\n", (int)-textpos);
			printk("Unable to mmap process text, errno %d\n", (int)-textpos);
			ret = textpos;
			ret = textpos;
			goto err_close;
			goto err;
		}
		}


		down_write(&current->mm->mmap_sem);
		down_write(&current->mm->mmap_sem);
@@ -564,7 +554,7 @@ static int load_flat_file(struct linux_binprm * bprm,
					(int)-datapos);
					(int)-datapos);
			do_munmap(current->mm, textpos, text_len);
			do_munmap(current->mm, textpos, text_len);
			ret = realdatastart;
			ret = realdatastart;
			goto err_close;
			goto err;
		}
		}
		datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
		datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);


@@ -587,7 +577,7 @@ static int load_flat_file(struct linux_binprm * bprm,
			do_munmap(current->mm, textpos, text_len);
			do_munmap(current->mm, textpos, text_len);
			do_munmap(current->mm, realdatastart, data_len + extra);
			do_munmap(current->mm, realdatastart, data_len + extra);
			ret = result;
			ret = result;
			goto err_close;
			goto err;
		}
		}


		reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len));
		reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len));
@@ -606,7 +596,7 @@ static int load_flat_file(struct linux_binprm * bprm,
			printk("Unable to allocate RAM for process text/data, errno %d\n",
			printk("Unable to allocate RAM for process text/data, errno %d\n",
					(int)-textpos);
					(int)-textpos);
			ret = textpos;
			ret = textpos;
			goto err_close;
			goto err;
		}
		}


		realdatastart = textpos + ntohl(hdr->data_start);
		realdatastart = textpos + ntohl(hdr->data_start);
@@ -652,7 +642,7 @@ static int load_flat_file(struct linux_binprm * bprm,
			do_munmap(current->mm, textpos, text_len + data_len + extra +
			do_munmap(current->mm, textpos, text_len + data_len + extra +
				MAX_SHARED_LIBS * sizeof(unsigned long));
				MAX_SHARED_LIBS * sizeof(unsigned long));
			ret = result;
			ret = result;
			goto err_close;
			goto err;
		}
		}
	}
	}


@@ -717,7 +707,7 @@ static int load_flat_file(struct linux_binprm * bprm,
				addr = calc_reloc(*rp, libinfo, id, 0);
				addr = calc_reloc(*rp, libinfo, id, 0);
				if (addr == RELOC_FAILED) {
				if (addr == RELOC_FAILED) {
					ret = -ENOEXEC;
					ret = -ENOEXEC;
					goto err_close;
					goto err;
				}
				}
				*rp = addr;
				*rp = addr;
			}
			}
@@ -747,7 +737,7 @@ static int load_flat_file(struct linux_binprm * bprm,
			rp = (unsigned long *) calc_reloc(addr, libinfo, id, 1);
			rp = (unsigned long *) calc_reloc(addr, libinfo, id, 1);
			if (rp == (unsigned long *)RELOC_FAILED) {
			if (rp == (unsigned long *)RELOC_FAILED) {
				ret = -ENOEXEC;
				ret = -ENOEXEC;
				goto err_close;
				goto err;
			}
			}


			/* Get the pointer's value.  */
			/* Get the pointer's value.  */
@@ -762,7 +752,7 @@ static int load_flat_file(struct linux_binprm * bprm,
				addr = calc_reloc(addr, libinfo, id, 0);
				addr = calc_reloc(addr, libinfo, id, 0);
				if (addr == RELOC_FAILED) {
				if (addr == RELOC_FAILED) {
					ret = -ENOEXEC;
					ret = -ENOEXEC;
					goto err_close;
					goto err;
				}
				}


				/* Write back the relocated pointer.  */
				/* Write back the relocated pointer.  */
@@ -783,8 +773,6 @@ static int load_flat_file(struct linux_binprm * bprm,
			stack_len);
			stack_len);


	return 0;
	return 0;
err_close:
	sys_close(exec_fileno);
err:
err:
	return ret;
	return ret;
}
}