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

Commit 08a6fac1 authored by Al Viro's avatar Al Viro
Browse files

[PATCH] get rid of leak in compat_execve()



Even though copy_compat_strings() doesn't cache the pages,
copy_strings_kernel() and stuff indirectly called by e.g.
->load_binary() is doing that, so we need to drop the
cache contents in the end.

[found by WANG Cong <wangcong@zeuux.org>]

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 5f719558
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1405,7 +1405,7 @@ int compat_do_execve(char * filename,
		/* execve success */
		security_bprm_free(bprm);
		acct_update_integrals(current);
		kfree(bprm);
		free_bprm(bprm);
		return retval;
	}

@@ -1424,7 +1424,7 @@ int compat_do_execve(char * filename,
	}

out_kfree:
	kfree(bprm);
	free_bprm(bprm);

out_ret:
	return retval;
+8 −4
Original line number Diff line number Diff line
@@ -1251,6 +1251,12 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)

EXPORT_SYMBOL(search_binary_handler);

void free_bprm(struct linux_binprm *bprm)
{
	free_arg_pages(bprm);
	kfree(bprm);
}

/*
 * sys_execve() executes a new program.
 */
@@ -1320,17 +1326,15 @@ int do_execve(char * filename,
	retval = search_binary_handler(bprm,regs);
	if (retval >= 0) {
		/* execve success */
		free_arg_pages(bprm);
		security_bprm_free(bprm);
		acct_update_integrals(current);
		kfree(bprm);
		free_bprm(bprm);
		if (displaced)
			put_files_struct(displaced);
		return retval;
	}

out:
	free_arg_pages(bprm);
	if (bprm->security)
		security_bprm_free(bprm);

@@ -1344,7 +1348,7 @@ int do_execve(char * filename,
		fput(bprm->file);
	}
out_kfree:
	kfree(bprm);
	free_bprm(bprm);

out_files:
	if (displaced)
+1 −0
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm);
extern void compute_creds(struct linux_binprm *binprm);
extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
extern int set_binfmt(struct linux_binfmt *new);
extern void free_bprm(struct linux_binprm *);

#endif /* __KERNEL__ */
#endif /* _LINUX_BINFMTS_H */