linux-user pull request 20210313

- fix elfload
 - fix executable page of /proc/self/maps
 - add preserve-arg[0] support for binfmt_misc
 -----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCAAwFiEEzS913cjjpNwuT1Fz8ww4vT8vvjwFAmBMiisSHGxhdXJlbnRA
 dml2aWVyLmV1AAoJEPMMOL0/L748840P/ArGjM4+D+mBttCtzH0vPlL7+4gfapGN
 m2oIn5WmU67nP3z/GgECFk9ZKeMj3oKhs2zvUkdlhG+6SYR3loXvtkYyy4Rv9ZaQ
 pCIqDOAUKigzGD69lTtjBHVb5FxO3TmEjz3dYaLTjFR9HljAa42isnPWUPkTkEyw
 GVAX8aD6ABfRDFjwU1YwB2zKPCVRIOqaXpFBU9Q4kgBJxgR2HqGdcWNyfE1qqQsw
 E/6+MMFWuhlyrIbcbheRXA925JQIFxu6ii8sh/1Zdote04mu9Gx91r6Edm3Wy1IO
 xSJzMrvdirPXEXJDdGdjfndu6vhBLnFIvkm6mXjpzlIZzYKyGkZ8MoL0NS0n2Rqu
 fT4S6NL56dYg8DetmWAw03+l6M7etwue8xvGy0RhK8qIrkSyZWbmXkWMoJPks1iU
 uDV3A9fGMwfTKf7kjUNcl7Uv92BBDZ36iFQ8XZVFr8nyGTy1RXtaGE69ow8NULlC
 SwslZ5cV6HwrviVLbSkQ8VQIIvn0iAMnTfKw+8ko7U4ymZ35L7feThA3wX978Z3U
 ZGAQMtuD6h06PzpENlLsOMCmMJzwHK1nGClQMyMqsVMG2jULTg52uIoAcHGBrcgs
 TkdNG/w2C92oazrIzHTkMqPW/pWgFh96zwJ1lWbfDg0PCmk2o7okoXsgmbkknfdn
 4ptwKHXN9IXc
 =oPYn
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-6.0-pull-request' into staging

linux-user pull request 20210313

- fix elfload
- fix executable page of /proc/self/maps
- add preserve-arg[0] support for binfmt_misc

# gpg: Signature made Sat 13 Mar 2021 09:47:23 GMT
# gpg:                using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C
# gpg:                issuer "laurent@vivier.eu"
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full]
# gpg:                 aka "Laurent Vivier <laurent@vivier.eu>" [full]
# gpg:                 aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full]
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F  5173 F30C 38BD 3F2F BE3C

* remotes/vivier2/tags/linux-user-for-6.0-pull-request:
  linux-user/elfload: fix address calculation in fallback scenario
  linux-user/elfload: do not assume MAP_FIXED_NOREPLACE kernel support
  linux-user/elfload: munmap proper address in pgd_find_hole_fallback
  linux-user: manage binfmt-misc preserve-arg[0] flag
  linux-user: Fix executable page of /proc/self/maps

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2021-03-14 17:47:49 +00:00
commit 6157b0e197
4 changed files with 58 additions and 24 deletions

View File

@ -2209,9 +2209,8 @@ static uintptr_t pgd_find_hole_fallback(uintptr_t guest_size, uintptr_t brk,
void * mmap_start = mmap((void *) align_start, guest_size, void * mmap_start = mmap((void *) align_start, guest_size,
PROT_NONE, flags, -1, 0); PROT_NONE, flags, -1, 0);
if (mmap_start != MAP_FAILED) { if (mmap_start != MAP_FAILED) {
munmap((void *) align_start, guest_size); munmap(mmap_start, guest_size);
if (MAP_FIXED_NOREPLACE != 0 || if (mmap_start == (void *) align_start) {
mmap_start == (void *) align_start) {
return (uintptr_t) mmap_start + offset; return (uintptr_t) mmap_start + offset;
} }
} }
@ -2236,7 +2235,8 @@ static uintptr_t pgb_find_hole(uintptr_t guest_loaddr, uintptr_t guest_size,
brk = (uintptr_t)sbrk(0); brk = (uintptr_t)sbrk(0);
if (!maps) { if (!maps) {
return pgd_find_hole_fallback(guest_size, brk, align, offset); ret = pgd_find_hole_fallback(guest_size, brk, align, offset);
return ret == -1 ? -1 : ret - guest_loaddr;
} }
/* The first hole is before the first map entry. */ /* The first hole is before the first map entry. */

View File

@ -26,6 +26,7 @@
#include <sys/syscall.h> #include <sys/syscall.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/shm.h> #include <sys/shm.h>
#include <linux/binfmts.h>
#include "qapi/error.h" #include "qapi/error.h"
#include "qemu.h" #include "qemu.h"
@ -49,6 +50,11 @@
#include "cpu_loop-common.h" #include "cpu_loop-common.h"
#include "crypto/init.h" #include "crypto/init.h"
#ifndef AT_FLAGS_PRESERVE_ARGV0
#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
#endif
char *exec_path; char *exec_path;
int singlestep; int singlestep;
@ -632,6 +638,7 @@ int main(int argc, char **argv, char **envp)
int execfd; int execfd;
int log_mask; int log_mask;
unsigned long max_reserved_va; unsigned long max_reserved_va;
bool preserve_argv0;
error_init(argv[0]); error_init(argv[0]);
module_call_init(MODULE_INIT_TRACE); module_call_init(MODULE_INIT_TRACE);
@ -688,6 +695,9 @@ int main(int argc, char **argv, char **envp)
init_qemu_uname_release(); init_qemu_uname_release();
/*
* Manage binfmt-misc open-binary flag
*/
execfd = qemu_getauxval(AT_EXECFD); execfd = qemu_getauxval(AT_EXECFD);
if (execfd == 0) { if (execfd == 0) {
execfd = open(exec_path, O_RDONLY); execfd = open(exec_path, O_RDONLY);
@ -697,6 +707,20 @@ int main(int argc, char **argv, char **envp)
} }
} }
/*
* get binfmt_misc flags
*/
preserve_argv0 = !!(qemu_getauxval(AT_FLAGS) & AT_FLAGS_PRESERVE_ARGV0);
/*
* Manage binfmt-misc preserve-arg[0] flag
* argv[optind] full path to the binary
* argv[optind + 1] original argv[0]
*/
if (optind + 1 < argc && preserve_argv0) {
optind++;
}
if (cpu_model == NULL) { if (cpu_model == NULL) {
cpu_model = cpu_get_model(get_elf_eflags(execfd)); cpu_model = cpu_get_model(get_elf_eflags(execfd));
} }

View File

@ -7890,9 +7890,9 @@ static int open_self_maps(void *cpu_env, int fd)
count = dprintf(fd, TARGET_ABI_FMT_ptr "-" TARGET_ABI_FMT_ptr count = dprintf(fd, TARGET_ABI_FMT_ptr "-" TARGET_ABI_FMT_ptr
" %c%c%c%c %08" PRIx64 " %s %"PRId64, " %c%c%c%c %08" PRIx64 " %s %"PRId64,
h2g(min), h2g(max - 1) + 1, h2g(min), h2g(max - 1) + 1,
e->is_read ? 'r' : '-', (flags & PAGE_READ) ? 'r' : '-',
e->is_write ? 'w' : '-', (flags & PAGE_WRITE_ORG) ? 'w' : '-',
e->is_exec ? 'x' : '-', (flags & PAGE_EXEC) ? 'x' : '-',
e->is_priv ? 'p' : '-', e->is_priv ? 'p' : '-',
(uint64_t) e->offset, e->dev, e->inode); (uint64_t) e->offset, e->dev, e->inode);
if (path) { if (path) {

View File

@ -178,25 +178,27 @@ usage() {
Usage: qemu-binfmt-conf.sh [--qemu-path PATH][--debian][--systemd CPU] Usage: qemu-binfmt-conf.sh [--qemu-path PATH][--debian][--systemd CPU]
[--help][--credential yes|no][--exportdir PATH] [--help][--credential yes|no][--exportdir PATH]
[--persistent yes|no][--qemu-suffix SUFFIX] [--persistent yes|no][--qemu-suffix SUFFIX]
[--preserve-argv0 yes|no]
Configure binfmt_misc to use qemu interpreter Configure binfmt_misc to use qemu interpreter
--help: display this usage --help: display this usage
--qemu-path: set path to qemu interpreter ($QEMU_PATH) --qemu-path: set path to qemu interpreter ($QEMU_PATH)
--qemu-suffix: add a suffix to the default interpreter name --qemu-suffix: add a suffix to the default interpreter name
--debian: don't write into /proc, --debian: don't write into /proc,
instead generate update-binfmts templates instead generate update-binfmts templates
--systemd: don't write into /proc, --systemd: don't write into /proc,
instead generate file for systemd-binfmt.service instead generate file for systemd-binfmt.service
for the given CPU. If CPU is "ALL", generate a for the given CPU. If CPU is "ALL", generate a
file for all known cpus file for all known cpus
--exportdir: define where to write configuration files --exportdir: define where to write configuration files
(default: $SYSTEMDDIR or $DEBIANDIR) (default: $SYSTEMDDIR or $DEBIANDIR)
--credential: if yes, credential and security tokens are --credential: if yes, credential and security tokens are
calculated according to the binary to interpret calculated according to the binary to interpret
--persistent: if yes, the interpreter is loaded when binfmt is --persistent: if yes, the interpreter is loaded when binfmt is
configured and remains in memory. All future uses configured and remains in memory. All future uses
are cloned from the open file. are cloned from the open file.
--preserve-argv0 preserve argv[0]
To import templates with update-binfmts, use : To import templates with update-binfmts, use :
@ -269,6 +271,9 @@ qemu_generate_register() {
if [ "$PERSISTENT" = "yes" ] ; then if [ "$PERSISTENT" = "yes" ] ; then
flags="${flags}F" flags="${flags}F"
fi fi
if [ "$PRESERVE_ARG0" = "yes" ] ; then
flags="${flags}P"
fi
echo ":qemu-$cpu:M::$magic:$mask:$qemu:$flags" echo ":qemu-$cpu:M::$magic:$mask:$qemu:$flags"
} }
@ -330,9 +335,10 @@ DEBIANDIR="/usr/share/binfmts"
QEMU_PATH=/usr/local/bin QEMU_PATH=/usr/local/bin
CREDENTIAL=no CREDENTIAL=no
PERSISTENT=no PERSISTENT=no
PRESERVE_ARG0=no
QEMU_SUFFIX="" QEMU_SUFFIX=""
options=$(getopt -o ds:Q:S:e:hc:p: -l debian,systemd:,qemu-path:,qemu-suffix:,exportdir:,help,credential:,persistent: -- "$@") options=$(getopt -o ds:Q:S:e:hc:p:g: -l debian,systemd:,qemu-path:,qemu-suffix:,exportdir:,help,credential:,persistent:,preserve-argv0: -- "$@")
eval set -- "$options" eval set -- "$options"
while true ; do while true ; do
@ -388,6 +394,10 @@ while true ; do
shift shift
PERSISTENT="$1" PERSISTENT="$1"
;; ;;
-g|--preserve-argv0)
shift
PRESERVE_ARG0="$1"
;;
*) *)
break break
;; ;;