diff options
author | emaste <emaste@FreeBSD.org> | 2015-06-08 16:07:07 +0000 |
---|---|---|
committer | emaste <emaste@FreeBSD.org> | 2015-06-08 16:07:07 +0000 |
commit | 41e1b133ab1d8173f5b19f67a7df2823d5c84aa2 (patch) | |
tree | ca1dff4275ea796df75bb85abcd3e8aa72d04363 | |
parent | 1c5eb55915374777acda11ca6bc13e6918752620 (diff) | |
download | FreeBSD-src-41e1b133ab1d8173f5b19f67a7df2823d5c84aa2.zip FreeBSD-src-41e1b133ab1d8173f5b19f67a7df2823d5c84aa2.tar.gz |
Add user facing errors for exceeding process memory limits
Previously the process terminating with SIGABRT at startup was the
only notification.
PR: 200617
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D2731
-rw-r--r-- | sys/kern/imgact_elf.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index a98a15d..c3953fe 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -732,7 +732,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) u_long addr, baddr, et_dyn_addr, entry = 0, proghdr = 0; int32_t osrel = 0; int error = 0, i, n, interp_name_len = 0; - const char *interp = NULL, *newinterp = NULL; + const char *err_str = NULL, *interp = NULL, *newinterp = NULL; Elf_Brandinfo *brand_info; char *path; struct sysentvec *sv; @@ -755,11 +755,14 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) if ((hdr->e_phoff > PAGE_SIZE) || (u_int)hdr->e_phentsize * hdr->e_phnum > PAGE_SIZE - hdr->e_phoff) { /* Only support headers in first page for now */ + uprintf("Program headers not in the first page\n"); return (ENOEXEC); } - phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff); - if (!aligned(phdr, Elf_Addr)) + phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff); + if (!aligned(phdr, Elf_Addr)) { + uprintf("Unaligned program headers\n"); return (ENOEXEC); + } n = 0; baddr = 0; for (i = 0; i < hdr->e_phnum; i++) { @@ -773,8 +776,10 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) /* Path to interpreter */ if (phdr[i].p_filesz > MAXPATHLEN || phdr[i].p_offset > PAGE_SIZE || - phdr[i].p_filesz > PAGE_SIZE - phdr[i].p_offset) + phdr[i].p_filesz > PAGE_SIZE - phdr[i].p_offset) { + uprintf("Invalid PT_INTERP\n"); return (ENOEXEC); + } interp = imgp->image_header + phdr[i].p_offset; interp_name_len = phdr[i].p_filesz; break; @@ -795,8 +800,10 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) return (ENOEXEC); } if (hdr->e_type == ET_DYN) { - if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0) + if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0) { + uprintf("Cannot execute shared object\n"); return (ENOEXEC); + } /* * Honour the base load address from the dso if it is * non-zero for some reason. @@ -901,12 +908,19 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) * not actually fault in all the segments pages. */ PROC_LOCK(imgp->proc); - if (data_size > lim_cur(imgp->proc, RLIMIT_DATA) || - text_size > maxtsiz || - total_size > lim_cur(imgp->proc, RLIMIT_VMEM) || - racct_set(imgp->proc, RACCT_DATA, data_size) != 0 || - racct_set(imgp->proc, RACCT_VMEM, total_size) != 0) { + if (data_size > lim_cur(imgp->proc, RLIMIT_DATA)) + err_str = "Data segment size exceeds process limit"; + else if (text_size > maxtsiz) + err_str = "Text segment size exceeds system limit"; + else if (total_size > lim_cur(imgp->proc, RLIMIT_VMEM)) + err_str = "Total segment size exceeds process limit"; + else if (racct_set(imgp->proc, RACCT_DATA, data_size) != 0) + err_str = "Data segment size exceeds resource limit"; + else if (racct_set(imgp->proc, RACCT_VMEM, total_size) != 0) + err_str = "Total segment size exceeds resource limit"; + if (err_str != NULL) { PROC_UNLOCK(imgp->proc); + uprintf("%s\n", err_str); return (ENOMEM); } |