Date: Mon, 28 Jun 2010 17:48:59 +0300 From: Kostik Belousov <kostikbel@gmail.com> To: Jeremie Le Hen <jeremie@le-hen.org> Cc: FreeBSD Hackers <freebsd-hackers@freebsd.org>, marius@freebsd.org, nwhitehorn@freebsd.org Subject: Re: Avoiding sysctl at program startup using ELF aux vector (was: concurrent sysctl implementation) Message-ID: <20100628144858.GA13238@deviant.kiev.zoral.com.ua> In-Reply-To: <20100623210959.GA21260@felucia.tataz.chchile.org> References: <20090509113459.GD56667@e.0x20.net> <20090509121313.GA58540@hoeg.nl> <20090724073451.GH54986@felucia.tataz.chchile.org> <20090724081842.GF55190@deviant.kiev.zoral.com.ua> <20090724115404.GI54986@felucia.tataz.chchile.org> <20090724115649.GV68469@hoeg.nl> <20090724130928.GJ54986@felucia.tataz.chchile.org> <20090724134953.GW68469@hoeg.nl> <20090724212916.GQ55190@deviant.kiev.zoral.com.ua> <20100623210959.GA21260@felucia.tataz.chchile.org>
next in thread | previous in thread | raw e-mail | index | archive | help
--Cu2X4S6QpqS+1MBM
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
On Wed, Jun 23, 2010 at 11:09:59PM +0200, Jeremie Le Hen wrote:
> Hi Kostik,
>=20
> This patch seems to have faded out from memory. Is it possible to go
> forward and commit it?
I refreshed the patch. Hopefully, nobody will object, and I commit it
shortly.
>=20
> Thanks,
> Regards.
>=20
> On Sat, Jul 25, 2009 at 12:29:16AM +0300, Kostik Belousov wrote:
> > Below is the prototype that seems to work for me both with patched and
> > old rtld on i386. Patch also contains bits for amd64 that I did not
> > tested yet. All other arches are not buildable for now.
> >=20
> > Patch completely eliminates sysctl syscalls from the rtld and libc
> > startup. Without the patch, a single run of /bin/ls did 6 sysctls,
> > with the patch, no sysctls is queried at all.
> >=20
Comparing with the originally posted patch, I added support for all
architectures, tested amd64 and ia32 on amd64, and converted getpagesizes(3)
that added two more startup sysctls.
Would be nice to get a testing for at least some !x86 architectures
before the commit, I added some people who helped me in past, to the Cc:.
diff --git a/lib/libc/gen/__getosreldate.c b/lib/libc/gen/__getosreldate.c
index 7e26845..1bed6d0 100644
--- a/lib/libc/gen/__getosreldate.c
+++ b/lib/libc/gen/__getosreldate.c
@@ -29,6 +29,8 @@ __FBSDID("$FreeBSD$");
=20
#include <sys/param.h>
#include <sys/sysctl.h>
+#include <errno.h>
+#include <link.h>
=20
int __getosreldate(void);
=20
@@ -51,7 +53,15 @@ __getosreldate(void)
=20
if (osreldate !=3D 0)
return (osreldate);
-=09
+
+ if (_rtld_aux_info !=3D NULL)
+ error =3D _rtld_aux_info(AT_OSRELDATE, &osreldate,
+ sizeof(osreldate));
+ else
+ error =3D ENOSYS;
+ if (error =3D=3D 0 && osreldate !=3D 0)
+ return (osreldate);
+
oid[0] =3D CTL_KERN;
oid[1] =3D KERN_OSRELDATE;
osrel =3D 0;
diff --git a/lib/libc/gen/getpagesize.c b/lib/libc/gen/getpagesize.c
index d796b9d..b8f0ec1 100644
--- a/lib/libc/gen/getpagesize.c
+++ b/lib/libc/gen/getpagesize.c
@@ -36,6 +36,8 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/sysctl.h>
=20
+#include <errno.h>
+#include <link.h>
#include <unistd.h>
=20
/*
@@ -52,13 +54,23 @@ getpagesize()
int mib[2];=20
static int value;
size_t size;
+ int error;
+
+ if (value !=3D 0)
+ return (value);
+
+ if (_rtld_aux_info !=3D NULL)
+ error =3D _rtld_aux_info(AT_PAGESZ, &value, sizeof(value));
+ else
+ error =3D ENOSYS;
+ if (error =3D=3D 0 && value !=3D 0)
+ return (value);
+
+ mib[0] =3D CTL_HW;
+ mib[1] =3D HW_PAGESIZE;
+ size =3D sizeof value;
+ if (sysctl(mib, 2, &value, &size, NULL, 0) =3D=3D -1)
+ return (-1);
=20
- if (!value) {
- mib[0] =3D CTL_HW;
- mib[1] =3D HW_PAGESIZE;
- size =3D sizeof value;
- if (sysctl(mib, 2, &value, &size, NULL, 0) =3D=3D -1)
- return (-1);
- }
return (value);
}
diff --git a/lib/libc/gen/getpagesizes.c b/lib/libc/gen/getpagesizes.c
index b0de939..bfeeef8 100644
--- a/lib/libc/gen/getpagesizes.c
+++ b/lib/libc/gen/getpagesizes.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
=20
#include <errno.h>
+#include <link.h>
=20
/*
* Retrieves page size information from the system. Specifically, returns=
the
@@ -51,7 +52,7 @@ getpagesizes(size_t pagesize[], int nelem)
static u_long ps[MAXPAGESIZES];
static int nops;
size_t size;
- int i;=20
+ int error, i;
=20
if (nelem < 0 || (nelem > 0 && pagesize =3D=3D NULL)) {
errno =3D EINVAL;
@@ -59,9 +60,16 @@ getpagesizes(size_t pagesize[], int nelem)
}
/* Cache the result of the sysctl(2). */
if (nops =3D=3D 0) {
- size =3D sizeof(ps);
- if (sysctlbyname("hw.pagesizes", ps, &size, NULL, 0) =3D=3D -1)
- return (-1);
+ if (_rtld_aux_info !=3D NULL)
+ error =3D _rtld_aux_info(AT_PAGESIZES, ps, sizeof(ps));
+ else
+ error =3D ENOSYS;
+ if (error !=3D 0 || ps[0] =3D=3D 0) {
+ size =3D sizeof(ps);
+ if (sysctlbyname("hw.pagesizes", ps, &size, NULL, 0)
+ =3D=3D -1)
+ return (-1);
+ }
/* Count the number of page sizes that are supported. */
nops =3D size / sizeof(ps[0]);
while (nops > 0 && ps[nops - 1] =3D=3D 0)
diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c
index 295a168..41be6d8 100644
--- a/lib/libc/stdlib/malloc.c
+++ b/lib/libc/stdlib/malloc.c
@@ -180,6 +180,7 @@ __FBSDID("$FreeBSD$");
=20
#include <errno.h>
#include <limits.h>
+#include <link.h>
#include <pthread.h>
#include <sched.h>
#include <stdarg.h>
@@ -5348,14 +5349,23 @@ small_size2bin_init_hard(void)
static unsigned
malloc_ncpus(void)
{
+ int mib[2];
unsigned ret;
- size_t retlen =3D sizeof(ret);
- int mib[] =3D {CTL_HW, HW_NCPU};
+ int error;
+ size_t len;
=20
- if (sysctl(mib, sizeof(mib) / sizeof(int), &ret, &retlen,
- (void *)0, 0) =3D=3D -1) {
- /* Error. */
- ret =3D 1;
+ if (_rtld_aux_info !=3D NULL)
+ error =3D _rtld_aux_info(AT_NCPUS, &ret, sizeof(ret));
+ else
+ error =3D ENOSYS;
+ if (error !=3D 0 || ret =3D=3D 0) {
+ mib[0] =3D CTL_HW;
+ mib[1] =3D HW_NCPU;
+ len =3D sizeof(ret);
+ if (sysctl(mib, 2, &ret, &len, (void *)NULL, 0) =3D=3D -1) {
+ /* Error. */
+ ret =3D 1;
+ }
}
=20
return (ret);
diff --git a/lib/libc/sys/stack_protector.c b/lib/libc/sys/stack_protector.c
index 14c20eb..e868d3b 100644
--- a/lib/libc/sys/stack_protector.c
+++ b/lib/libc/sys/stack_protector.c
@@ -34,6 +34,8 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/types.h>
+#include <errno.h>
+#include <link.h>
#include <signal.h>
#include <string.h>
#include <syslog.h>
@@ -54,9 +56,17 @@ __guard_setup(void)
{
int mib[2];
size_t len;
+ int error;
=20
if (__stack_chk_guard[0] !=3D 0)
return;
+ if (_rtld_aux_info !=3D NULL)
+ error =3D _rtld_aux_info(AT_CANARY, __stack_chk_guard,
+ sizeof(__stack_chk_guard));
+ else
+ error =3D ENOSYS;
+ if (error =3D=3D 0 && __stack_chk_guard[0] !=3D 0)
+ return;
=20
mib[0] =3D CTL_KERN;
mib[1] =3D KERN_ARND;
diff --git a/libexec/rtld-elf/Symbol.map b/libexec/rtld-elf/Symbol.map
index ce1e3e5..f45f955 100644
--- a/libexec/rtld-elf/Symbol.map
+++ b/libexec/rtld-elf/Symbol.map
@@ -24,4 +24,5 @@ FBSDprivate_1.0 {
_rtld_free_tls;
_rtld_atfork_pre;
_rtld_atfork_post;
+ _rtld_aux_info;
};
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 8082656..6c5914c 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -40,6 +40,7 @@
#include <sys/mount.h>
#include <sys/mman.h>
#include <sys/stat.h>
+#include <sys/sysctl.h>
#include <sys/uio.h>
#include <sys/utsname.h>
#include <sys/ktrace.h>
@@ -84,6 +85,9 @@ typedef struct Struct_DoneList {
*/
static const char *basename(const char *);
static void die(void) __dead2;
+static void digest_dynamic1(Obj_Entry *, int, const Elf_Dyn **,
+ const Elf_Dyn **);
+static void digest_dynamic2(Obj_Entry *, const Elf_Dyn *, const Elf_Dyn *);
static void digest_dynamic(Obj_Entry *, int);
static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *=
);
static Obj_Entry *dlcheck(void *);
@@ -97,7 +101,7 @@ static char *find_library(const char *, const Obj_Entry =
*);
static const char *gethints(void);
static void init_dag(Obj_Entry *);
static void init_dag1(Obj_Entry *, Obj_Entry *, DoneList *);
-static void init_rtld(caddr_t);
+static void init_rtld(caddr_t, Elf_Auxinfo **);
static void initlist_add_neededs(Needed_Entry *, Objlist *);
static void initlist_add_objects(Obj_Entry *, Obj_Entry **, Objlist *);
static bool is_exported(const Elf_Sym *);
@@ -188,6 +192,9 @@ extern Elf_Dyn _DYNAMIC;
#define RTLD_IS_DYNAMIC() (&_DYNAMIC !=3D NULL)
#endif
=20
+static int pagesize, osreldate, canary_len, ncpus, pagesizes_len;
+static char *canary, *pagesizes;
+
/*
* These are the functions the dynamic linker exports to application
* programs. They are the only symbols the dynamic linker is willing
@@ -214,6 +221,7 @@ static func_ptr_type exports[] =3D {
(func_ptr_type) &dl_iterate_phdr,
(func_ptr_type) &_rtld_atfork_pre,
(func_ptr_type) &_rtld_atfork_post,
+ (func_ptr_type) &_rtld_aux_info,
NULL
};
=20
@@ -350,7 +358,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry=
**objp)
=20
/* Initialize and relocate ourselves. */
assert(aux_info[AT_BASE] !=3D NULL);
- init_rtld((caddr_t) aux_info[AT_BASE]->a_un.a_ptr);
+ init_rtld((caddr_t) aux_info[AT_BASE]->a_un.a_ptr, aux_info);
=20
__progname =3D obj_rtld.path;
argv0 =3D argv[0] !=3D NULL ? argv[0] : "(null)";
@@ -737,14 +745,16 @@ die(void)
* information in its Obj_Entry structure.
*/
static void
-digest_dynamic(Obj_Entry *obj, int early)
+digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
+ const Elf_Dyn **dyn_soname)
{
const Elf_Dyn *dynp;
Needed_Entry **needed_tail =3D &obj->needed;
- const Elf_Dyn *dyn_rpath =3D NULL;
- const Elf_Dyn *dyn_soname =3D NULL;
int plttype =3D DT_REL;
=20
+ *dyn_rpath =3D NULL;
+ *dyn_soname =3D NULL;
+
obj->bind_now =3D false;
for (dynp =3D obj->dynamic; dynp->d_tag !=3D DT_NULL; dynp++) {
switch (dynp->d_tag) {
@@ -868,11 +878,11 @@ digest_dynamic(Obj_Entry *obj, int early)
* We have to wait until later to process this, because we
* might not have gotten the address of the string table yet.
*/
- dyn_rpath =3D dynp;
+ *dyn_rpath =3D dynp;
break;
=20
case DT_SONAME:
- dyn_soname =3D dynp;
+ *dyn_soname =3D dynp;
break;
=20
case DT_INIT:
@@ -961,6 +971,12 @@ digest_dynamic(Obj_Entry *obj, int early)
obj->pltrelasize =3D obj->pltrelsize;
obj->pltrelsize =3D 0;
}
+}
+
+static void
+digest_dynamic2(Obj_Entry *obj, const Elf_Dyn *dyn_rpath,
+ const Elf_Dyn *dyn_soname)
+{
=20
if (obj->z_origin && obj->origin_path =3D=3D NULL) {
obj->origin_path =3D xmalloc(PATH_MAX);
@@ -978,6 +994,16 @@ digest_dynamic(Obj_Entry *obj, int early)
object_add_name(obj, obj->strtab + dyn_soname->d_un.d_val);
}
=20
+static void
+digest_dynamic(Obj_Entry *obj, int early)
+{
+ const Elf_Dyn *dyn_rpath;
+ const Elf_Dyn *dyn_soname;
+
+ digest_dynamic1(obj, early, &dyn_rpath, &dyn_soname);
+ digest_dynamic2(obj, dyn_rpath, dyn_soname);
+}
+
/*
* Process a shared object's program header. This is used only for the
* main program, when the kernel has already loaded the main program
@@ -1304,9 +1330,11 @@ init_dag1(Obj_Entry *root, Obj_Entry *obj, DoneList =
*dlp)
* this function is to relocate the dynamic linker.
*/
static void
-init_rtld(caddr_t mapbase)
+init_rtld(caddr_t mapbase, Elf_Auxinfo **aux_info)
{
Obj_Entry objtmp; /* Temporary rtld object */
+ const Elf_Dyn *dyn_rpath;
+ const Elf_Dyn *dyn_soname;
=20
/*
* Conjure up an Obj_Entry structure for the dynamic linker.
@@ -1323,7 +1351,7 @@ init_rtld(caddr_t mapbase)
#endif
if (RTLD_IS_DYNAMIC()) {
objtmp.dynamic =3D rtld_dynamic(&objtmp);
- digest_dynamic(&objtmp, 1);
+ digest_dynamic1(&objtmp, 1, &dyn_rpath, &dyn_soname);
assert(objtmp.needed =3D=3D NULL);
#if !defined(__mips__)
/* MIPS and SH{3,5} have a bogus DT_TEXTREL. */
@@ -1344,6 +1372,23 @@ init_rtld(caddr_t mapbase)
/* Now that non-local variables can be accesses, copy out obj_rtld. */
memcpy(&obj_rtld, &objtmp, sizeof(obj_rtld));
=20
+ if (aux_info[AT_PAGESZ] !=3D NULL)
+ pagesize =3D aux_info[AT_PAGESZ]->a_un.a_val;
+ if (aux_info[AT_OSRELDATE] !=3D NULL)
+ osreldate =3D aux_info[AT_OSRELDATE]->a_un.a_val;
+ if (aux_info[AT_CANARY] !=3D NULL && aux_info[AT_CANARYLEN] !=3D NULL)=
{
+ canary =3D aux_info[AT_CANARY]->a_un.a_ptr;
+ canary_len =3D aux_info[AT_CANARYLEN]->a_un.a_val;
+ }
+ if (aux_info[AT_PAGESIZES] !=3D NULL && aux_info[AT_PAGESIZESLEN] !=3D=
NULL) {
+ pagesizes =3D aux_info[AT_PAGESIZES]->a_un.a_ptr;
+ pagesizes_len =3D aux_info[AT_PAGESIZESLEN]->a_un.a_val;
+ }
+ if (aux_info[AT_NCPUS] !=3D NULL)
+ ncpus =3D aux_info[AT_NCPUS]->a_un.a_val;
+
+ digest_dynamic2(&obj_rtld, dyn_rpath, dyn_soname);
+
/* Replace the path with a dynamically allocated copy. */
obj_rtld.path =3D xstrdup(PATH_RTLD);
=20
@@ -3630,3 +3675,118 @@ fetch_ventry(const Obj_Entry *obj, unsigned long sy=
mnum)
}
return NULL;
}
+
+static int
+__getosreldate(void)
+{
+ static int osreldate;
+ size_t len;
+ int oid[2];
+ int error, osrel;
+
+ oid[0] =3D CTL_KERN;
+ oid[1] =3D KERN_OSRELDATE;
+ osrel =3D 0;
+ len =3D sizeof(osrel);
+ error =3D sysctl(oid, 2, &osrel, &len, NULL, 0);
+ if (error =3D=3D 0 && osrel > 0 && len =3D=3D sizeof(osrel))
+ osreldate =3D osrel;
+ return (osreldate);
+}
+
+static int
+__getpagesize(void)
+{
+ int mib[2];
+ static int value;
+ size_t size;
+
+ mib[0] =3D CTL_HW;
+ mib[1] =3D HW_PAGESIZE;
+ size =3D sizeof value;
+ if (sysctl(mib, 2, &value, &size, NULL, 0) =3D=3D -1)
+ return (-1);
+
+ return (value);
+}
+
+static int
+__getncpus(void)
+{
+ int mib[2];
+ size_t len;
+ int n;
+
+ mib[0] =3D CTL_HW;
+ mib[1] =3D HW_NCPU;
+ len =3D sizeof(ncpus);
+ if (sysctl(mib, 2, &n, &len, (void *) 0, 0) =3D=3D -1)
+ n =3D 1;
+ return (n);
+}
+
+int
+_rtld_aux_info(int aux, void *buf, int buflen)
+{
+ int res;
+
+ switch (aux) {
+ case AT_CANARY:
+ if (canary !=3D NULL && canary_len >=3D buflen) {
+ memcpy(buf, canary, buflen);
+ memset(canary, 0, canary_len);
+ canary =3D NULL;
+ res =3D 0;
+ } else
+ res =3D ENOENT;
+ break;
+ case AT_PAGESIZES:
+ if (pagesizes !=3D NULL && pagesizes_len >=3D buflen) {
+ memcpy(buf, pagesizes, buflen);
+ res =3D 0;
+ } else
+ res =3D ENOENT;
+ break;
+
+ case AT_PAGESZ:
+ if (buflen =3D=3D sizeof(int)) {
+ if (pagesize =3D=3D 0)
+ pagesize =3D __getpagesize();
+ if (pagesize !=3D 0) {
+ *(int *)buf =3D pagesize;
+ res =3D 0;
+ } else
+ res =3D ENOENT;
+ } else
+ res =3D EINVAL;
+ break;
+ case AT_OSRELDATE:
+ if (buflen =3D=3D sizeof(int)) {
+ if (osreldate =3D=3D 0)
+ osreldate =3D __getosreldate();
+ if (osreldate !=3D 0) {
+ *(int *)buf =3D osreldate;
+ res =3D 0;
+ } else
+ res =3D ENOENT;
+ } else
+ res =3D EINVAL;
+ break;
+ case AT_NCPUS:
+ if (buflen =3D=3D sizeof(int)) {
+ if (ncpus =3D=3D 0)
+ ncpus =3D __getncpus();
+ if (ncpus !=3D 0) {
+ *(int *)buf =3D ncpus;
+ res =3D 0;
+ } else
+ res =3D ENOENT;
+ } else
+ res =3D EINVAL;
+ break;
+ default:
+ res =3D ENOENT;
+ break;
+ }
+ return (res);
+}
diff --git a/sys/amd64/include/elf.h b/sys/amd64/include/elf.h
index 678f5d3..1f5c754 100644
--- a/sys/amd64/include/elf.h
+++ b/sys/amd64/include/elf.h
@@ -88,8 +88,14 @@ __ElfType(Auxinfo);
#define AT_GID 13 /* Real gid. */
#define AT_EGID 14 /* Effective gid. */
#define AT_EXECPATH 15 /* Path to the executable. */
-
-#define AT_COUNT 16 /* Count of defined aux entry types. */
+#define AT_CANARY 16 /* Canary for SSP */
+#define AT_CANARYLEN 17 /* Length of the canary. */
+#define AT_OSRELDATE 18 /* OSRELDATE. */
+#define AT_NCPUS 19 /* Number of CPUs. */
+#define AT_PAGESIZES 20 /* Pagesizes. */
+#define AT_PAGESIZESLEN 21 /* Number of pagesizes. */
+
+#define AT_COUNT 22 /* Count of defined aux entry types. */
=20
/*
* Relocation types.
diff --git a/sys/arm/include/elf.h b/sys/arm/include/elf.h
index 0660ba6..4cb2ae3 100644
--- a/sys/arm/include/elf.h
+++ b/sys/arm/include/elf.h
@@ -76,8 +76,14 @@ __ElfType(Auxinfo);
#define AT_GID 13 /* Real gid. */
#define AT_EGID 14 /* Effective gid. */
#define AT_EXECPATH 15 /* Path to the executable. */
-
-#define AT_COUNT 16 /* Count of defined aux entry types. */
+#define AT_CANARY 16 /* Canary for SSP */
+#define AT_CANARYLEN 17 /* Length of the canary. */
+#define AT_OSRELDATE 18 /* OSRELDATE. */
+#define AT_NCPUS 19 /* Number of CPUs. */
+#define AT_PAGESIZES 20 /* Pagesizes. */
+#define AT_PAGESIZESLEN 21 /* Number of pagesizes. */
+
+#define AT_COUNT 22 /* Count of defined aux entry types. */
=20
#define R_ARM_COUNT 33 /* Count of defined relocation types. */
=20
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/f=
reebsd32_misc.c
index f0fde2b..cc4172c 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -2524,11 +2524,13 @@ syscall32_helper_unregister(struct syscall_helper_d=
ata *sd)
register_t *
freebsd32_copyout_strings(struct image_params *imgp)
{
- int argc, envc;
+ int argc, envc, i;
u_int32_t *vectp;
char *stringp, *destp;
u_int32_t *stack_base;
struct freebsd32_ps_strings *arginfo;
+ char canary[sizeof(long) * 8];
+ int32_t pagesizes32[MAXPAGESIZES];
size_t execpath_len;
int szsigcode;
=20
@@ -2543,8 +2545,10 @@ freebsd32_copyout_strings(struct image_params *imgp)
arginfo =3D (struct freebsd32_ps_strings *)FREEBSD32_PS_STRINGS;
szsigcode =3D *(imgp->proc->p_sysent->sv_szsigcode);
destp =3D (caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
- roundup(execpath_len, sizeof(char *)) -
- roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
+ roundup(execpath_len, sizeof(char *)) -
+ roundup(sizeof(canary), sizeof(char *)) -
+ roundup(sizeof(pagesizes32), sizeof(char *)) -
+ roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
=20
/*
* install sigcode
@@ -2563,6 +2567,25 @@ freebsd32_copyout_strings(struct image_params *imgp)
}
=20
/*
+ * Prepare the canary for SSP.
+ */
+ arc4rand(canary, sizeof(canary), 0);
+ imgp->canary =3D (uintptr_t)arginfo - szsigcode - execpath_len -
+ sizeof(canary);
+ copyout(canary, (void *)imgp->canary, sizeof(canary));
+ imgp->canarylen =3D sizeof(canary);
+
+ /*
+ * Prepare the pagesizes array.
+ */
+ for (i =3D 0; i < MAXPAGESIZES; i++)
+ pagesizes32[i] =3D (uint32_t)pagesizes[i];
+ imgp->pagesizes =3D (uintptr_t)arginfo - szsigcode - execpath_len -
+ roundup(sizeof(canary), sizeof(char *)) - sizeof(pagesizes32);
+ copyout(pagesizes32, (void *)imgp->pagesizes, sizeof(pagesizes32));
+ imgp->pagesizeslen =3D sizeof(pagesizes32);
+
+ /*
* If we have a valid auxargs ptr, prepare some room
* on the stack.
*/
diff --git a/sys/i386/include/elf.h b/sys/i386/include/elf.h
index 37ee279..6490f2a 100644
--- a/sys/i386/include/elf.h
+++ b/sys/i386/include/elf.h
@@ -90,8 +90,14 @@ __ElfType(Auxinfo);
#define AT_GID 13 /* Real gid. */
#define AT_EGID 14 /* Effective gid. */
#define AT_EXECPATH 15 /* Path to the executable. */
-
-#define AT_COUNT 16 /* Count of defined aux entry types. */
+#define AT_CANARY 16 /* Canary for SSP. */
+#define AT_CANARYLEN 17 /* Length of the canary. */
+#define AT_OSRELDATE 18 /* OSRELDATE. */
+#define AT_NCPUS 19 /* Number of CPUs. */
+#define AT_PAGESIZES 20 /* Pagesizes. */
+#define AT_PAGESIZESLEN 21 /* Number of pagesizes. */
+
+#define AT_COUNT 22 /* Count of defined aux entry types. */
=20
/*
* Relocation types.
diff --git a/sys/ia64/include/elf.h b/sys/ia64/include/elf.h
index 27182db..ab7706b 100644
--- a/sys/ia64/include/elf.h
+++ b/sys/ia64/include/elf.h
@@ -89,8 +89,14 @@ __ElfType(Auxinfo);
#define AT_GID 13 /* Real gid. */
#define AT_EGID 14 /* Effective gid. */
#define AT_EXECPATH 15 /* Path to the executable. */
-
-#define AT_COUNT 16 /* Count of defined aux entry types. */
+#define AT_CANARY 16 /* Canary for SSP */
+#define AT_CANARYLEN 17 /* Length of the canary. */
+#define AT_OSRELDATE 18 /* OSRELDATE. */
+#define AT_NCPUS 19 /* Number of CPUs. */
+#define AT_PAGESIZES 20 /* Pagesizes. */
+#define AT_PAGESIZESLEN 21 /* Number of pagesizes. */
+
+#define AT_COUNT 22 /* Count of defined aux entry types. */
=20
/*
* Values for e_flags.
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index c48e0f5..88c64e9 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <sys/procfs.h>
#include <sys/resourcevar.h>
#include <sys/sf_buf.h>
+#include <sys/smp.h>
#include <sys/systm.h>
#include <sys/signalvar.h>
#include <sys/stat.h>
@@ -972,6 +973,16 @@ __elfN(freebsd_fixup)(register_t **stack_base, struct =
image_params *imgp)
AUXARGS_ENTRY(pos, AT_BASE, args->base);
if (imgp->execpathp !=3D 0)
AUXARGS_ENTRY(pos, AT_EXECPATH, imgp->execpathp);
+ AUXARGS_ENTRY(pos, AT_OSRELDATE, imgp->proc->p_osrel);
+ if (imgp->canary !=3D 0) {
+ AUXARGS_ENTRY(pos, AT_CANARY, imgp->canary);
+ AUXARGS_ENTRY(pos, AT_CANARYLEN, imgp->canarylen);
+ }
+ AUXARGS_ENTRY(pos, AT_NCPUS, mp_ncpus);
+ if (imgp->pagesizes !=3D 0) {
+ AUXARGS_ENTRY(pos, AT_PAGESIZES, imgp->pagesizes);
+ AUXARGS_ENTRY(pos, AT_PAGESIZESLEN, imgp->pagesizeslen);
+ }
AUXARGS_ENTRY(pos, AT_NULL, 0);
=20
free(imgp->auxargs, M_TEMP);
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 149e6df..1387529 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -386,6 +386,10 @@ do_execve(td, args, mac_p)
imgp->args =3D args;
imgp->execpath =3D imgp->freepath =3D NULL;
imgp->execpathp =3D 0;
+ imgp->canary =3D 0;
+ imgp->canarylen =3D 0;
+ imgp->pagesizes =3D 0;
+ imgp->pagesizeslen =3D 0;
=20
#ifdef MAC
error =3D mac_execve_enter(imgp, mac_p);
@@ -1183,8 +1187,10 @@ exec_copyout_strings(imgp)
struct ps_strings *arginfo;
struct proc *p;
size_t execpath_len;
- int szsigcode;
+ int szsigcode, szps;
+ char canary[sizeof(long) * 8];
=20
+ szps =3D sizeof(pagesizes[0]) * MAXPAGESIZES;
/*
* Calculate string base and vector table pointers.
* Also deal with signal trampoline code for this exec type.
@@ -1200,6 +1206,8 @@ exec_copyout_strings(imgp)
szsigcode =3D *(p->p_sysent->sv_szsigcode);
destp =3D (caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
roundup(execpath_len, sizeof(char *)) -
+ roundup(sizeof(canary), sizeof(char *)) -
+ roundup(szps, sizeof(char *)) -
roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
=20
/*
@@ -1219,6 +1227,23 @@ exec_copyout_strings(imgp)
}
=20
/*
+ * Prepare the canary for SSP.
+ */
+ arc4rand(canary, sizeof(canary), 0);
+ imgp->canary =3D (uintptr_t)arginfo - szsigcode - execpath_len -
+ sizeof(canary);
+ copyout(canary, (void *)imgp->canary, sizeof(canary));
+ imgp->canarylen =3D sizeof(canary);
+
+ /*
+ * Prepare the pagesizes array.
+ */
+ imgp->pagesizes =3D (uintptr_t)arginfo - szsigcode - execpath_len -
+ roundup(sizeof(canary), sizeof(char *)) - szps;
+ copyout(pagesizes, (void *)imgp->pagesizes, szps);
+ imgp->pagesizeslen =3D szps;
+
+ /*
* If we have a valid auxargs ptr, prepare some room
* on the stack.
*/
@@ -1235,8 +1260,8 @@ exec_copyout_strings(imgp)
* for argument of Runtime loader.
*/
vectp =3D (char **)(destp - (imgp->args->argc +
- imgp->args->envc + 2 + imgp->auxarg_size + execpath_len) *
- sizeof(char *));
+ imgp->args->envc + 2 + imgp->auxarg_size)
+ * sizeof(char *));
} else {
/*
* The '+ 2' is for the null pointers at the end of each of
diff --git a/sys/mips/include/elf.h b/sys/mips/include/elf.h
index 2d6ca3e..2646181 100644
--- a/sys/mips/include/elf.h
+++ b/sys/mips/include/elf.h
@@ -251,8 +251,14 @@ __ElfType(Auxinfo);
#define AT_GID 13 /* Real gid. */
#define AT_EGID 14 /* Effective gid. */
#define AT_EXECPATH 15 /* Path to the executable. */
+#define AT_CANARY 16 /* Canary for SSP */
+#define AT_CANARYLEN 17 /* Length of the canary. */
+#define AT_OSRELDATE 18 /* OSRELDATE. */
+#define AT_NCPUS 19 /* Number of CPUs. */
+#define AT_PAGESIZES 20 /* Pagesizes. */
+#define AT_PAGESIZESLEN 21 /* Number of pagesizes. */
=20
-#define AT_COUNT 16 /* Count of defined aux entry types. */
+#define AT_COUNT 22 /* Count of defined aux entry types. */
=20
#define ET_DYN_LOAD_ADDR 0x0120000
=20
diff --git a/sys/powerpc/include/elf.h b/sys/powerpc/include/elf.h
index e01488d..5ea3281 100644
--- a/sys/powerpc/include/elf.h
+++ b/sys/powerpc/include/elf.h
@@ -78,8 +78,14 @@ __ElfType(Auxinfo);
#define AT_ICACHEBSIZE 11 /* Instruction cache block size for the uP. */
#define AT_UCACHEBSIZE 12 /* Cache block size, or `0' if cache not unified=
. */
#define AT_EXECPATH 13 /* Path to the executable. */
-
-#define AT_COUNT 14 /* Count of defined aux entry types. */
+#define AT_CANARY 14 /* Canary for SSP */
+#define AT_CANARYLEN 15 /* Length of the canary. */
+#define AT_OSRELDATE 16 /* OSRELDATE. */
+#define AT_NCPUS 17 /* Number of CPUs. */
+#define AT_PAGESIZES 18 /* Pagesizes. */
+#define AT_PAGESIZESLEN 19 /* Number of pagesizes. */
+
+#define AT_COUNT 20 /* Count of defined aux entry types. */
=20
/*
* Relocation types.
diff --git a/sys/sparc64/include/elf.h b/sys/sparc64/include/elf.h
index 2a66670..0618434 100644
--- a/sys/sparc64/include/elf.h
+++ b/sys/sparc64/include/elf.h
@@ -84,8 +84,14 @@ __ElfType(Auxinfo);
#define AT_GID 13 /* Real gid. */
#define AT_EGID 14 /* Effective gid. */
#define AT_EXECPATH 15 /* Path to the executable. */
+#define AT_CANARY 16 /* Canary for SSP */
+#define AT_CANARYLEN 17 /* Length of the canary. */
+#define AT_OSRELDATE 18 /* OSRELDATE. */
+#define AT_NCPUS 19 /* Number of CPUs. */
+#define AT_PAGESIZES 20 /* Pagesizes. */
+#define AT_PAGESIZESLEN 21 /* Number of pagesizes. */
=20
-#define AT_COUNT 16 /* Count of defined aux entry types. */
+#define AT_COUNT 22 /* Count of defined aux entry types. */
=20
/* Define "machine" characteristics */
#if __ELF_WORD_SIZE =3D=3D 32
diff --git a/sys/sun4v/include/elf.h b/sys/sun4v/include/elf.h
index 2a66670..0618434 100644
--- a/sys/sun4v/include/elf.h
+++ b/sys/sun4v/include/elf.h
@@ -84,8 +84,14 @@ __ElfType(Auxinfo);
#define AT_GID 13 /* Real gid. */
#define AT_EGID 14 /* Effective gid. */
#define AT_EXECPATH 15 /* Path to the executable. */
+#define AT_CANARY 16 /* Canary for SSP */
+#define AT_CANARYLEN 17 /* Length of the canary. */
+#define AT_OSRELDATE 18 /* OSRELDATE. */
+#define AT_NCPUS 19 /* Number of CPUs. */
+#define AT_PAGESIZES 20 /* Pagesizes. */
+#define AT_PAGESIZESLEN 21 /* Number of pagesizes. */
=20
-#define AT_COUNT 16 /* Count of defined aux entry types. */
+#define AT_COUNT 22 /* Count of defined aux entry types. */
=20
/* Define "machine" characteristics */
#if __ELF_WORD_SIZE =3D=3D 32
diff --git a/sys/sys/imgact.h b/sys/sys/imgact.h
index 1d1e361..3d1a049 100644
--- a/sys/sys/imgact.h
+++ b/sys/sys/imgact.h
@@ -70,6 +70,10 @@ struct image_params {
char *execpath;
unsigned long execpathp;
char *freepath;
+ unsigned long canary;
+ int canarylen;
+ unsigned long pagesizes;
+ int pagesizeslen;
};
=20
#ifdef _KERNEL
diff --git a/sys/sys/link_elf.h b/sys/sys/link_elf.h
index 98840a5..30f3d75 100644
--- a/sys/sys/link_elf.h
+++ b/sys/sys/link_elf.h
@@ -92,6 +92,10 @@ __BEGIN_DECLS
=20
typedef int (*__dl_iterate_hdr_callback)(struct dl_phdr_info *, size_t, vo=
id *);
extern int dl_iterate_phdr(__dl_iterate_hdr_callback, void *);
+extern int _rtld_aux_info(int, void *, int);
+#ifndef IN_RTLD
+#pragma weak _rtld_aux_info
+#endif
=20
__END_DECLS
=20
diff --git a/tools/test/auxinfo/Makefile b/tools/test/auxinfo/Makefile
new file mode 100644
index 0000000..d0ba464
--- /dev/null
+++ b/tools/test/auxinfo/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD
+
+PROG=3D auxinfo
+NO_MAN=3D
+WARNS?=3D 6
+
+.include <bsd.prog.mk>
\ No newline at end of file
diff --git a/tools/test/auxinfo/auxinfo.c b/tools/test/auxinfo/auxinfo.c
new file mode 100644
index 0000000..374bed8
--- /dev/null
+++ b/tools/test/auxinfo/auxinfo.c
@@ -0,0 +1,58 @@
+/*
+ * This file is in public domain.
+ * Written by Konstantin Belousov <kib@freebsd.org>
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/mman.h>
+#include <err.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static void
+test_pagesizes(void)
+{
+ size_t *ps;
+ int i, nelem;
+
+ nelem =3D getpagesizes(NULL, 0);
+ if (nelem =3D=3D -1)
+ err(1, "getpagesizes(NULL, 0)");
+ ps =3D malloc(nelem * sizeof(size_t));
+ if (ps =3D=3D NULL)
+ err(1, "malloc");
+ nelem =3D getpagesizes(ps, nelem);
+ if (nelem =3D=3D -1)
+ err(1, "getpagesizes");
+ printf("Supported page sizes:");
+ for (i =3D 0; i < nelem; i++)
+ printf(" %jd", (intmax_t)ps[i]);
+ printf("\n");
+}
+
+static void
+test_pagesize(void)
+{
+
+ printf("Pagesize: %d\n", getpagesize());
+}
+
+static void
+test_osreldate(void)
+{
+
+ printf("OSRELDATE: %d\n", getosreldate());
+}
+
+int
+main(int argc __unused, char *argv[] __unused)
+{
+
+ test_pagesizes();
+ test_pagesize();
+ test_osreldate();
+ return (0);
+}
--Cu2X4S6QpqS+1MBM
Content-Type: application/pgp-signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (FreeBSD)
iEYEARECAAYFAkwotloACgkQC3+MBN1Mb4hJ6QCaAqBNJoWUXpzc4oXayue3iSMs
CL0AoKIdgVvQWeCpSmwIl0rzGCgweFzh
=hsGK
-----END PGP SIGNATURE-----
--Cu2X4S6QpqS+1MBM--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100628144858.GA13238>
