diff options
author | dchagin <dchagin@FreeBSD.org> | 2016-01-09 16:24:30 +0000 |
---|---|---|
committer | dchagin <dchagin@FreeBSD.org> | 2016-01-09 16:24:30 +0000 |
commit | 68ddeae1b4dafbdcc753ae60d8495aecc6dde4cc (patch) | |
tree | d878568d4b02bdcee1d86e32899092b7cbb2ac72 /sys/amd64 | |
parent | 6a7051941493d24f6ceac5c4560fdc0a0465393d (diff) | |
download | FreeBSD-src-68ddeae1b4dafbdcc753ae60d8495aecc6dde4cc.zip FreeBSD-src-68ddeae1b4dafbdcc753ae60d8495aecc6dde4cc.tar.gz |
MFC r283431:
Add AT_RANDOM and AT_EXECFN auxiliary vector entries which are used by
glibc. At list since glibc version 2.16 using AT_RANDOM is mandatory.
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/linux/linux.h | 2 | ||||
-rw-r--r-- | sys/amd64/linux/linux_sysvec.c | 26 | ||||
-rw-r--r-- | sys/amd64/linux32/linux.h | 2 | ||||
-rw-r--r-- | sys/amd64/linux32/linux32_sysvec.c | 26 |
4 files changed, 54 insertions, 2 deletions
diff --git a/sys/amd64/linux/linux.h b/sys/amd64/linux/linux.h index c16d294..fee2b8d 100644 --- a/sys/amd64/linux/linux.h +++ b/sys/amd64/linux/linux.h @@ -100,7 +100,7 @@ typedef struct { #define LINUX_NAME_MAX 255 #define LINUX_CTL_MAXNAME 10 -#define LINUX_AT_COUNT 17 /* Count of used aux entry types. */ +#define LINUX_AT_COUNT 19 /* Count of used aux entry types. */ struct l___sysctl_args { diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c index 6c11a40..1d4c710 100644 --- a/sys/amd64/linux/linux_sysvec.c +++ b/sys/amd64/linux/linux_sysvec.c @@ -319,6 +319,9 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp) AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); AUXARGS_ENTRY(pos, LINUX_AT_SECURE, 0); AUXARGS_ENTRY(pos, LINUX_AT_PLATFORM, PTROUT(linux_platform)); + AUXARGS_ENTRY(pos, LINUX_AT_RANDOM, imgp->canary); + if (imgp->execpathp != 0) + AUXARGS_ENTRY(pos, LINUX_AT_EXECFN, imgp->execpathp); if (args->execfd != -1) AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); AUXARGS_ENTRY(pos, AT_NULL, 0); @@ -345,16 +348,39 @@ linux_copyout_strings(struct image_params *imgp) char *stringp, *destp; register_t *stack_base; struct ps_strings *arginfo; + char canary[LINUX_AT_RANDOM_LEN]; + size_t execpath_len; struct proc *p; /* * Calculate string base and vector table pointers. */ + if (imgp->execpath != NULL && imgp->auxargs != NULL) + execpath_len = strlen(imgp->execpath) + 1; + else + execpath_len = 0; + p = imgp->proc; arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings; destp = (caddr_t)arginfo - SPARE_USRSPACE - + roundup(sizeof(canary), sizeof(char *)) - + roundup(execpath_len, sizeof(char *)) - roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *)); + if (execpath_len != 0) { + imgp->execpathp = (uintptr_t)arginfo - execpath_len; + copyout(imgp->execpath, (void *)imgp->execpathp, execpath_len); + } + + /* + * Prepare the canary for SSP. + */ + arc4rand(canary, sizeof(canary), 0); + imgp->canary = (uintptr_t)arginfo - + roundup(execpath_len, sizeof(char *)) - + roundup(sizeof(canary), sizeof(char *)); + copyout(canary, (void *)imgp->canary, sizeof(canary)); + /* * If we have a valid auxargs ptr, prepare some room * on the stack. diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h index aec74a3..67c1750 100644 --- a/sys/amd64/linux32/linux.h +++ b/sys/amd64/linux32/linux.h @@ -110,7 +110,7 @@ typedef struct { /* * Miscellaneous */ -#define LINUX_AT_COUNT 18 /* Count of used aux entry types. +#define LINUX_AT_COUNT 20 /* Count of used aux entry types. * Keep this synchronized with * elf_linux_fixup() code. */ diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index f07f56e..448563b 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -289,6 +289,9 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp) AUXARGS_ENTRY_32(pos, AT_GID, imgp->proc->p_ucred->cr_rgid); AUXARGS_ENTRY_32(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); AUXARGS_ENTRY_32(pos, LINUX_AT_PLATFORM, PTROUT(linux_platform)); + AUXARGS_ENTRY(pos, LINUX_AT_RANDOM, PTROUT(imgp->canary)); + if (imgp->execpathp != 0) + AUXARGS_ENTRY(pos, LINUX_AT_EXECFN, PTROUT(imgp->execpathp)); if (args->execfd != -1) AUXARGS_ENTRY_32(pos, AT_EXECFD, args->execfd); AUXARGS_ENTRY_32(pos, AT_NULL, 0); @@ -869,14 +872,37 @@ linux_copyout_strings(struct image_params *imgp) char *stringp, *destp; u_int32_t *stack_base; struct linux32_ps_strings *arginfo; + char canary[LINUX_AT_RANDOM_LEN]; + size_t execpath_len; /* * Calculate string base and vector table pointers. */ + if (imgp->execpath != NULL && imgp->auxargs != NULL) + execpath_len = strlen(imgp->execpath) + 1; + else + execpath_len = 0; + arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS; destp = (caddr_t)arginfo - SPARE_USRSPACE - + roundup(sizeof(canary), sizeof(char *)) - + roundup(execpath_len, sizeof(char *)) - roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *)); + if (execpath_len != 0) { + imgp->execpathp = (uintptr_t)arginfo - execpath_len; + copyout(imgp->execpath, (void *)imgp->execpathp, execpath_len); + } + + /* + * Prepare the canary for SSP. + */ + arc4rand(canary, sizeof(canary), 0); + imgp->canary = (uintptr_t)arginfo - + roundup(execpath_len, sizeof(char *)) - + roundup(sizeof(canary), sizeof(char *)); + copyout(canary, (void *)imgp->canary, sizeof(canary)); + /* * If we have a valid auxargs ptr, prepare some room * on the stack. |