Messages in this thread Patch in this message | | | Date | Mon, 10 Jun 2013 21:52:44 +0800 (SGT) | From | Jeff Chua <> | Subject | binfmt_misc broken |
| |
According to Documentation/binfmt_misc.txt, the 'magic' and 'mask' can be set by echoing it to /proc/sys/fs/binfmt_misc/register.
Here's the problem I can across while working on ARM.
# echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm-static:' >/proc/sys/fs/binfmt_misc/register
# cat /proc/sys/fs/binfmt_misc/arm wrong ... magic 7f454c46010101 mask ffffffffffffff
right ... magic 7f454c4601010100000000000000000002002800 mask ffffffffffffff00fffffffffffffffffeffffff
binfmt_misc is truncating e->size, so once ARM's magic is loaded, 32-bit x86 can no longer run.
Here's a patch for it. It's looking for the delimiter ":" instead of \0. Now 32-bit x86 can run concurrent while qemu-arm is handling ARM's magic.
Thanks, Jeff
--- linux/fs/binfmt_misc.c 2013-05-01 12:59:39.000000000 +0800 +++ linux/fs/binfmt_misc.c 2013-06-10 21:29:45.000000000 +0800 @@ -276,6 +276,7 @@ int memsize, err; char *buf, *p; char del; + int esize = 0;
/* some sanity checks */ err = -EINVAL; @@ -323,6 +324,15 @@ e->offset = simple_strtoul(p, &p, 10); if (*p++) goto Einval; + + while(*(p + esize) != ':' && esize < BINPRM_BUF_SIZE) { + if(*(p + esize) == '\\' && *(p + esize + 1) == 'x') { + esize +=3; + } else + esize++; + } + e->size = esize; + e->magic = p; p = scanarg(p, del); if (!p) @@ -337,10 +347,6 @@ p[-1] = '\0'; if (!e->mask[0]) e->mask = NULL; - e->size = string_unescape_inplace(e->magic, UNESCAPE_HEX); - if (e->mask && - string_unescape_inplace(e->mask, UNESCAPE_HEX) != e->size) - goto Einval; if (e->size + e->offset > BINPRM_BUF_SIZE) goto Einval; } else {
| |