Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 2 May 2013 22:15:58 -0500
From:      Stacey Son <sson@FreeBSD.org>
To:        John Baldwin <jhb@freebsd.org>
Cc:        freebsd-arch@freebsd.org
Subject:   Re: A General or Miscellaneous Binary Image Activator
Message-ID:  <136ADFC2-D68F-4AE3-8186-4DF680C55E3E@FreeBSD.org>
In-Reply-To: <201305021138.36554.jhb@freebsd.org>
References:  <71BF89C0-13F9-41CA-9F7E-A3FDE11C2346@FreeBSD.org> <201305021138.36554.jhb@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

On May 2, 2013, at 10:38 AM, John Baldwin wrote:

> On Wednesday, May 01, 2013 7:02:49 pm Stacey Son wrote:
>> Of course, comments, questions, concerns, etc. are welcome.
>=20
> Certainly the ability to cross-build ports in this way is a huge win.  =
I just=20
> have a few comments on the kern.binmisc sysctl:
>=20
> It seems to be a bit overloaded and not used like a typical sysctl.  A =
better=20
> match would seem to be a /dev/binmisc that you perform ioctl's on.  A =
sysctl=20
> might still make better sense for enumerating the interperter entries, =
but the=20
> more typical way to do that would either be to have kern.binmisc.<n> =
be a=20
> sysctl that returns item <n> in the list, or to have the kern.binmisc =
sysctl=20
> that just returns an array of xbe entries (rather than having separate=20=

> list/lookup operations) similar to how the kern.proc sysctls work.  If =
you=20
> were to do this, I would probably prefer the second approach (one =
sysctl that=20
> returns a consistent snapshot).


I changed the code so userland gets a snapshot of the interpreter table =
much like kern.proc.  See:

	http://people.freebsd.org/~sson/imgact_binmisc/imgact_binmisc.c
	http://people.freebsd.org/~sson/imgact_binmisc/imgact_binmisc.h

Now the sysctl() interface as follows:

#include <sys/imgact_binmisc.h>

#define LLVM_MAGIC  "BC\xc0\xde"

#define MIPS64_ELF_MAGIC  \
=
"\x7f\x45\x4c\x46\x02\x02\x01\x00\x00\x00"\x00\x00\x00\x00\x00\x00\x00\x02=
\x00\x08"
#define MIPS64_ELF_MASK   \
=
"\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\=
xff\xff"

ximgact_binmisc_entry_t xbe, *xbep;
size_t size =3D 0, osize;
int error, i;

// Add image activator for LLVM byte code=20
bzero(&xbe, sizeof(xbe));
xbe.xbe_version =3D IBE_VERSION;
xbe.xbe_flags =3D IBF_ENABLED;
strlcpy(xbe.xbe_name, "llvm_bc", IBE_NAME_MAX);
strlcpy(xbe.xbe_interpreter, "/usr/bin/lli", MAXPATHLEN);
xbe.xbe_moffset =3D 0;
xbe.xbe_msize =3D sizeof(LLVM_MAGIC) - 1;
memcpy(xbe.xbe_magic, LLVM_MAGIC, xbe.xbe_msize);
error =3D sysctlbyname("kern.binmisc.add", NULL, NULL, &xbe, =
sizeof(xbe));

// Add image activator for mips64 ELF binaries to use qemu user mode
bzero(&xbe, sizeof(xbe));
xbe.xbe_version =3D IBE_VERSION;
xbe.xbe_flags =3D IBF_ENABLED | IBF_USE_MASK;
strlcpy(xbe.xbe_name, "mips64elf", IBE_NAME_MAX);
strlcpy(xbe.xbe_interpreter, "/usr/local/bin/qemu-mips64", MAXPATHLEN);
xbe.xbe_moffset =3D 0;
xbe.xbe_msize =3D sizeof(MIPS64_ELF_MAGIC) - 1;
memcpy(xbe.xbe_magic, MIPS64_ELF_MAGIC, xbe.xbe_msize);
memcpy(xbe.xbe_mask, MIPS64_ELF_MASK, xbe.xbe_msize);
sysctlbyname("kern.binmisc.add", NULL, NULL, &xbe, sizeof(xbe));

// Disable (OR Enable OR Delete) image activator for LLVM byte code
bzero(&xbe, sizeof(xbe));
xbe.xbe_version =3D IBE_VERSION;
strlcpy(xbe.xbe_name, "llvm_bc", IBE_NAME_MAX);
error =3D sysctlbyname("kern.binmisc.disable", NULL, NULL, &xbe, =
sizeof(xbe));
// OR sysctlbyname("kern.binmisc.enable", NULL, NULL, &xbe, =
sizeof(xbe));
// OR sysctlbyname("kern.binmisc.delete", NULL, NULL, &xbe, =
sizeof(xbe));

// Get all the currently configured image activators and report
error =3D sysctlbyname("kern.binmisc.getall", 0, &size, NULL, 0);
if (0 =3D=3D error && size > 0) {
	xbep =3D malloc(size);
	while(1) {
	    osize =3D size;
	    error =3D sysctlbyname("kern.binmisc.getall", xbep, &size, =
NULL, 0);
	    if (-1 =3D=3D error && ENOMEM =3D=3D errno && size =3D=3D =
osize) {
		// The buffer too small and needs to grow
		size +=3D sizeof(xbe);=20
		xbep =3D realloc(xbep, size);
	    } else
		break;
	}
}
for(i =3D 0; i < (size / sizeof(xbe)); i++, xbep++)
	printf("name: %s interpreter: %s flags: %s%s\n", xbep->xbe_name,
	    xbep->xbe_interpreter, (xbep->xbe_flags & IBF_ENABLED) ?=20
	    "ENABLED" : "", (xbep->xbe_flags & IBF_ENABLED) ? " =
USE_MASK" : "");

The sysctlbyname() calls above may return the following errors:

[EINVAL]     Invalid argment in the input ximgact_binmisc_entry_t =
structure.
[EEXIST]     Interpreter entry for given name already exist in kernel =
list.=20
[ENOMEM]  Allocating memory in the kernel failed or, in the case of
                 kern.binmisc.getall, the user buffer is too small.
[ENOENT]   Interpreter entry for given name is not found.
[ENOSPC]   Attempted to exceed maximum number of entries =
(IBE_MAX_ENTRIES).

On May 1, 2013, at 6:02 PM, Stacey Son wrote:

> Of course, image activators have been a source for security issues.  =
If this or something like this is include in the kernel then I would =
recommend it be optional.

Or, better yet, just simply build as a kernel module like I have done in =
the following diff:  =20

	=
http://people.freebsd.org/~sson/imgact_binmisc/imgact_binmisc.diff

-stacey.
sson@





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?136ADFC2-D68F-4AE3-8186-4DF680C55E3E>