summaryrefslogtreecommitdiff
path: root/sys/kern/exec_subr.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2015-02-06 23:58:13 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2015-02-06 23:58:13 +0000
commit10bf69cce0d92c5a9e6d252f99e02345c220f30f (patch)
tree130e4fe2b0d54ad814d081fc8fff9cba9e9342f1 /sys/kern/exec_subr.c
parent8a9300f5ce7c3a6e63c67274dc5cca83fc7efcaf (diff)
Raise ELF_RANDOMIZE_LIMIT to 64K, so that programs and libraries can
legitimately use random section variables without execve failures... Because this section is not demand faulted, yield() every page during the fill otherwise the costs are charged poorly. ok tedu matthew
Diffstat (limited to 'sys/kern/exec_subr.c')
-rw-r--r--sys/kern/exec_subr.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/sys/kern/exec_subr.c b/sys/kern/exec_subr.c
index 538e20ecb65..e51b6af910f 100644
--- a/sys/kern/exec_subr.c
+++ b/sys/kern/exec_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: exec_subr.c,v 1.46 2014/12/17 06:58:11 guenther Exp $ */
+/* $OpenBSD: exec_subr.c,v 1.47 2015/02/06 23:58:12 deraadt Exp $ */
/* $NetBSD: exec_subr.c,v 1.9 1994/12/04 03:10:42 mycroft Exp $ */
/*
@@ -289,16 +289,28 @@ vmcmd_randomize(struct proc *p, struct exec_vmcmd *cmd)
{
char *buf;
int error;
+ size_t off = 0, len;
if (cmd->ev_len == 0)
return (0);
- if (cmd->ev_len > 1024)
+ if (cmd->ev_len > ELF_RANDOMIZE_LIMIT)
return (EINVAL);
- buf = malloc(cmd->ev_len, M_TEMP, M_WAITOK);
- arc4random_buf(buf, cmd->ev_len);
- error = copyout(buf, (void *)cmd->ev_addr, cmd->ev_len);
- free(buf, M_TEMP, cmd->ev_len);
+ buf = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
+ len = cmd->ev_len;
+ do {
+ size_t sublen = MIN(len, PAGE_SIZE);
+
+ arc4random_buf(buf, sublen);
+ error = copyout(buf, (void *)cmd->ev_addr + off, sublen);
+ if (error)
+ break;
+ off += sublen;
+ len -= sublen;
+ if (len)
+ yield();
+ } while (len);
+ free(buf, M_TEMP, PAGE_SIZE);
return (error);
}