summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordchagin <dchagin@FreeBSD.org>2016-01-09 16:24:30 +0000
committerdchagin <dchagin@FreeBSD.org>2016-01-09 16:24:30 +0000
commit68ddeae1b4dafbdcc753ae60d8495aecc6dde4cc (patch)
treed878568d4b02bdcee1d86e32899092b7cbb2ac72
parent6a7051941493d24f6ceac5c4560fdc0a0465393d (diff)
downloadFreeBSD-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.
-rw-r--r--sys/amd64/linux/linux.h2
-rw-r--r--sys/amd64/linux/linux_sysvec.c26
-rw-r--r--sys/amd64/linux32/linux.h2
-rw-r--r--sys/amd64/linux32/linux32_sysvec.c26
-rw-r--r--sys/compat/linux/linux_misc.h3
-rw-r--r--sys/i386/linux/linux.h2
-rw-r--r--sys/i386/linux/linux_sysvec.c26
7 files changed, 84 insertions, 3 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.
diff --git a/sys/compat/linux/linux_misc.h b/sys/compat/linux/linux_misc.h
index ca8d7b6..62c76da 100644
--- a/sys/compat/linux/linux_misc.h
+++ b/sys/compat/linux/linux_misc.h
@@ -70,10 +70,13 @@ extern const char *linux_kplatform;
#define LINUX_AT_BASE_PLATFORM 24 /* string identifying real platform, may
* differ from AT_PLATFORM.
*/
+#define LINUX_AT_RANDOM 25 /* address of random bytes */
#define LINUX_AT_EXECFN 31 /* filename of program */
#define LINUX_AT_SYSINFO 32 /* vsyscall */
#define LINUX_AT_SYSINFO_EHDR 33 /* vdso header */
+#define LINUX_AT_RANDOM_LEN 16 /* size of random bytes */
+
/* Linux sets the i387 to extended precision. */
#if defined(__i386__) || defined(__amd64__)
#define __LINUX_NPXCW__ 0x37f
diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h
index aad9509..5e23d07 100644
--- a/sys/i386/linux/linux.h
+++ b/sys/i386/linux/linux.h
@@ -104,7 +104,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/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 6bda0aa..c1dca1d 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -298,6 +298,9 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
AUXARGS_ENTRY(pos, LINUX_AT_PLATFORM, PTROUT(uplatform));
+ 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);
@@ -321,14 +324,22 @@ 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.
*/
p = imgp->proc;
+ if (imgp->execpath != NULL && imgp->auxargs != NULL)
+ execpath_len = strlen(imgp->execpath) + 1;
+ else
+ execpath_len = 0;
arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
destp = (caddr_t)arginfo - SPARE_USRSPACE - linux_szplatform -
+ roundup(sizeof(canary), sizeof(char *)) -
+ roundup(execpath_len, sizeof(char *)) -
roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
/*
@@ -337,6 +348,21 @@ linux_copyout_strings(struct image_params *imgp)
copyout(linux_kplatform, ((caddr_t)arginfo - linux_szplatform),
linux_szplatform);
+ if (execpath_len != 0) {
+ imgp->execpathp = (uintptr_t)arginfo -
+ linux_szplatform - 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 - linux_szplatform -
+ 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.
OpenPOWER on IntegriCloud