summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2015-10-28 11:22:30 +0000
committerkib <kib@FreeBSD.org>2015-10-28 11:22:30 +0000
commitfbbf115be010f7a6fc4eb8ce79f4df4069510673 (patch)
treee5241fc7e85ae96e1b0df02ed9e45218add0ee42 /sys/kern
parent0cbc4b1b34411b4e62099fc56e6d75824acac40e (diff)
downloadFreeBSD-src-fbbf115be010f7a6fc4eb8ce79f4df4069510673.zip
FreeBSD-src-fbbf115be010f7a6fc4eb8ce79f4df4069510673.tar.gz
MFC r284157 (by emaste):
Add user facing errors for exceeding process memory limits.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/imgact_elf.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index e66d679..053099a 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -726,7 +726,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;
@@ -749,11 +749,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++) {
@@ -767,8 +770,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;
@@ -789,8 +794,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.
@@ -895,12 +902,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);
}
OpenPOWER on IntegriCloud