Pretend that there is some security when executing in direct mode.
Do not allow direct exec if we the process is suid. Try to follow Unix permission checks for DACs, ignore ACLs. Reviewed by: emaste Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Differential revision: https://reviews.freebsd.org/D10750
This commit is contained in:
parent
4dd362f93f
commit
da403aea11
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=318380
@ -345,12 +345,14 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
|||||||
const Elf_Phdr *phdr;
|
const Elf_Phdr *phdr;
|
||||||
Objlist initlist;
|
Objlist initlist;
|
||||||
RtldLockState lockstate;
|
RtldLockState lockstate;
|
||||||
|
struct stat st;
|
||||||
Elf_Addr *argcp;
|
Elf_Addr *argcp;
|
||||||
char **argv, *argv0, **env, **envp, *kexecpath, *library_path_rpath;
|
char **argv, *argv0, **env, **envp, *kexecpath, *library_path_rpath;
|
||||||
caddr_t imgentry;
|
caddr_t imgentry;
|
||||||
char buf[MAXPATHLEN];
|
char buf[MAXPATHLEN];
|
||||||
int argc, fd, i, mib[2], phnum;
|
int argc, fd, i, mib[2], phnum;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
bool dir_enable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On entry, the dynamic linker itself has not been relocated yet.
|
* On entry, the dynamic linker itself has not been relocated yet.
|
||||||
@ -419,6 +421,11 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
|||||||
assert(aux_info[AT_PHDR] != NULL);
|
assert(aux_info[AT_PHDR] != NULL);
|
||||||
phdr = (const Elf_Phdr *)aux_info[AT_PHDR]->a_un.a_ptr;
|
phdr = (const Elf_Phdr *)aux_info[AT_PHDR]->a_un.a_ptr;
|
||||||
if (phdr == obj_rtld.phdr) {
|
if (phdr == obj_rtld.phdr) {
|
||||||
|
if (!trust) {
|
||||||
|
rtld_printf("Tainted process refusing to run binary %s\n",
|
||||||
|
argv0);
|
||||||
|
rtld_die();
|
||||||
|
}
|
||||||
dbg("opening main program in direct exec mode");
|
dbg("opening main program in direct exec mode");
|
||||||
if (argc >= 2) {
|
if (argc >= 2) {
|
||||||
argv0 = argv[1];
|
argv0 = argv[1];
|
||||||
@ -428,6 +435,37 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
|||||||
rtld_strerror(errno));
|
rtld_strerror(errno));
|
||||||
rtld_die();
|
rtld_die();
|
||||||
}
|
}
|
||||||
|
if (fstat(fd, &st) == -1) {
|
||||||
|
rtld_printf("Stat %s: %s\n", argv0,
|
||||||
|
rtld_strerror(errno));
|
||||||
|
rtld_die();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Rough emulation of the permission checks done by
|
||||||
|
* execve(2), only Unix DACs are checked, ACLs are
|
||||||
|
* ignored. Preserve the semantic of disabling owner
|
||||||
|
* to execute if owner x bit is cleared, even if
|
||||||
|
* others x bit is enabled.
|
||||||
|
* mmap(2) does not allow to mmap with PROT_EXEC if
|
||||||
|
* binary' file comes from noexec mount. We cannot
|
||||||
|
* set VV_TEXT on the binary.
|
||||||
|
*/
|
||||||
|
dir_enable = false;
|
||||||
|
if (st.st_uid == geteuid()) {
|
||||||
|
if ((st.st_mode & S_IXUSR) != 0)
|
||||||
|
dir_enable = true;
|
||||||
|
} else if (st.st_gid == getegid()) {
|
||||||
|
if ((st.st_mode & S_IXGRP) != 0)
|
||||||
|
dir_enable = true;
|
||||||
|
} else if ((st.st_mode & S_IXOTH) != 0) {
|
||||||
|
dir_enable = true;
|
||||||
|
}
|
||||||
|
if (!dir_enable) {
|
||||||
|
rtld_printf("No execute permission for binary %s\n",
|
||||||
|
argv0);
|
||||||
|
rtld_die();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For direct exec mode, argv[0] is the interpreter
|
* For direct exec mode, argv[0] is the interpreter
|
||||||
|
Loading…
Reference in New Issue
Block a user