From nobody Tue Dec 16 16:20:48 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1695666562; cv=none; d=zohomail.com; s=zohoarc; b=nGSSDAmnCIxJGKJfCfzuZp5w96VK9PPm1wKH8b6Fx7C7wgeHN2GWPjJ563DPwCM5zV16eGSCxtrEfFSYwteBIsn/OKb1bCjgAO4dHHqRkYwRSl0rkLYKHW6IwIDHgZBmu5DQwLHTnQ6EqN55VGJ8urG8jTdGlRiYh1WWxc1ejIw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1695666562; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=uxI2BautFYuM9X/6LgOM/mAy2btm9htJw+uHfz45eMY=; b=M/G1aeEFWJjLqsNmaY/G7xP1y3s22Cw52P0syh2Tmix2R3/Vtd8VAk3iMVv3SuXF2x3J9ngbls5NjOSKSSYF/Stbpi+e93fqMtN0tQDRUOFKoenIVo7Nz+7bpBpCRk4wIOw4uJ9V3MycRbL3touKftSAbIJecv2tNJ1yPClVKJc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1695666562386651.2618860166754; Mon, 25 Sep 2023 11:29:22 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qkqHp-0001Mu-N3; Mon, 25 Sep 2023 14:26:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qkqHn-0001M9-UV for qemu-devel@nongnu.org; Mon, 25 Sep 2023 14:26:23 -0400 Received: from mail-wm1-x331.google.com ([2a00:1450:4864:20::331]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qkqHj-0007R4-Rz for qemu-devel@nongnu.org; Mon, 25 Sep 2023 14:26:23 -0400 Received: by mail-wm1-x331.google.com with SMTP id 5b1f17b1804b1-40572aeb6d0so35488685e9.1 for ; Mon, 25 Sep 2023 11:26:19 -0700 (PDT) Received: from karim.my.domain ([197.39.209.18]) by smtp.gmail.com with ESMTPSA id 19-20020a05600c229300b00405953973c3sm2232858wmf.6.2023.09.25.11.26.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Sep 2023 11:26:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695666377; x=1696271177; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=uxI2BautFYuM9X/6LgOM/mAy2btm9htJw+uHfz45eMY=; b=jfStwEuRSRW6NYVsKYPouIDKH8JNNQQ56+4VZQncSN7+RZcuSAnox6YZVQn1yMN23/ L8lnxsccHrJAooScVmfkXM3odDhSrfpc1ns4FnSRnDCj/WgaJ+fNNppu3UC9X1guUGMf lRVw+Qw7PeKjk0L8zApNYn1eLwD+GvL0F+bvYgZT9dAFXGgI1Fj5hXUn+Rej9Vlv2YSr OKgz1tyVWMU6hOS+TaTfkTr1sZzArcV8Gkc4uOUL3gKKqvNqaS/OitpORqXUH8lBZFyc K+XdVj4jcijeYMPDwM4H29XwL1Q/YgjO00p/AT+YSS/9Q8fwhjqREYVe5ZfzUa/LhFaX 4Riw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695666377; x=1696271177; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uxI2BautFYuM9X/6LgOM/mAy2btm9htJw+uHfz45eMY=; b=ra1ubG/oWLftl/4kxKQJvlbMbc9Ol/76ZdsBeyRDfcO5CtrHM13xWllNdG4P/W/6PM D3ycC16fLAmlsVlNgasT8YlZ6E0c2Vty7df5PXJa4hqGRzwl2Jc8ddX6RO7VekRvG+6B xS3QeJPh5/pG5au2WuOhosNMXvOHHdiMJf8KW8bHXZwzA/KGUHU4BudvsZwgEnc91Kl2 QDPWrSpzt2VIolOTZ3Z1R56jXsAZghrNAPnHGAdlV7XYzn10MfY5+Kq/GAzYGuu+UeL3 voaqsPFm2U0Cv8BuDUPbWKS7h0llNyqBsSsHFzuA/xhFAe1MmfXeBfurnz4CnQY7U6xD sR3w== X-Gm-Message-State: AOJu0YwPFzW3p554UaVJnjnZO0lU1ualFywM1wQbQcXD1N4a2NsgqkbU 3sa6bLcJygwT5mfJvOQmNzcomC4H2Pk= X-Google-Smtp-Source: AGHT+IEGEAV47AR9MxKYtm4f0qWw8Jbr0wdFhMr+l5dUAw3OeVqNZ4Xlr6OR6LYjXStwKwgjogphOA== X-Received: by 2002:a05:600c:141:b0:400:ce4f:f184 with SMTP id w1-20020a05600c014100b00400ce4ff184mr6632576wmm.41.1695666377488; Mon, 25 Sep 2023 11:26:17 -0700 (PDT) From: Karim Taha To: qemu-devel@nongnu.org Cc: Warner Losh , Richard Henderson , Stacey Son , Karim Taha Subject: [PATCH v5 20/28] bsd-user: Implement freebsd_exec_common, used in implementing execve/fexecve. Date: Mon, 25 Sep 2023 21:24:17 +0300 Message-ID: <20230925182425.3163-21-kariem.taha2.7@gmail.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230925182425.3163-1-kariem.taha2.7@gmail.com> References: <20230925182425.3163-1-kariem.taha2.7@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::331; envelope-from=kariem.taha2.7@gmail.com; helo=mail-wm1-x331.google.com X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1695666564016100011 Content-Type: text/plain; charset="utf-8" From: Stacey Son Signed-off-by: Stacey Son Signed-off-by: Karim Taha Reviewed-by: Warner Losh --- bsd-user/freebsd/os-proc.c | 177 +++++++++++++++++++++++++++++++++++++ bsd-user/main.c | 2 +- bsd-user/qemu.h | 1 + 3 files changed, 179 insertions(+), 1 deletion(-) diff --git a/bsd-user/freebsd/os-proc.c b/bsd-user/freebsd/os-proc.c index cb35f29f10..12d78b7fc9 100644 --- a/bsd-user/freebsd/os-proc.c +++ b/bsd-user/freebsd/os-proc.c @@ -78,3 +78,180 @@ out: return ret; } =20 +/* + * execve/fexecve + */ +abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp, + abi_ulong guest_envp, int do_fexec) +{ + char **argp, **envp, **qargp, **qarg1, **qarg0, **qargend; + int argc, envc; + abi_ulong gp; + abi_ulong addr; + char **q; + int total_size =3D 0; + void *p; + abi_long ret; + + argc =3D 0; + for (gp =3D guest_argp; gp; gp +=3D sizeof(abi_ulong)) { + if (get_user_ual(addr, gp)) { + return -TARGET_EFAULT; + } + if (!addr) { + break; + } + argc++; + } + envc =3D 0; + for (gp =3D guest_envp; gp; gp +=3D sizeof(abi_ulong)) { + if (get_user_ual(addr, gp)) { + return -TARGET_EFAULT; + } + if (!addr) { + break; + } + envc++; + } + + qarg0 =3D argp =3D g_new0(char *, argc + 9); + /* save the first agrument for the emulator */ + *argp++ =3D (char *)getprogname(); + qargp =3D argp; + *argp++ =3D (char *)getprogname(); + qarg1 =3D argp; + envp =3D g_new0(char *, envc + 1); + for (gp =3D guest_argp, q =3D argp; gp; gp +=3D sizeof(abi_ulong), q++= ) { + if (get_user_ual(addr, gp)) { + ret =3D -TARGET_EFAULT; + goto execve_end; + } + if (!addr) { + break; + } + *q =3D lock_user_string(addr); + if (*q =3D=3D NULL) { + ret =3D -TARGET_EFAULT; + goto execve_end; + } + total_size +=3D strlen(*q) + 1; + } + *q++ =3D NULL; + qargend =3D q; + + for (gp =3D guest_envp, q =3D envp; gp; gp +=3D sizeof(abi_ulong), q++= ) { + if (get_user_ual(addr, gp)) { + ret =3D -TARGET_EFAULT; + goto execve_end; + } + if (!addr) { + break; + } + *q =3D lock_user_string(addr); + if (*q =3D=3D NULL) { + ret =3D -TARGET_EFAULT; + goto execve_end; + } + total_size +=3D strlen(*q) + 1; + } + *q =3D NULL; + + /* + * This case will not be caught by the host's execve() if its + * page size is bigger than the target's. + */ + if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) { + ret =3D -TARGET_E2BIG; + goto execve_end; + } + + if (do_fexec) { + if (((int)path_or_fd > 0 && + is_target_elf_binary((int)path_or_fd)) =3D=3D 1) { + char execpath[PATH_MAX]; + + /* + * The executable is an elf binary for the target + * arch. execve() it using the emulator if we can + * determine the filename path from the fd. + */ + if (get_filename_from_fd(getpid(), (int)path_or_fd, execpath, + sizeof(execpath)) !=3D NULL) { + memmove(qarg1 + 2, qarg1, (qargend - qarg1) * sizeof(*qarg= 1)); + qarg1[1] =3D qarg1[0]; + qarg1[0] =3D (char *)"-0"; + qarg1 +=3D 2; + qargend +=3D 2; + *qarg1 =3D execpath; +#ifndef DONT_INHERIT_INTERP_PREFIX + memmove(qarg1 + 2, qarg1, (qargend - qarg1) * sizeof(*qarg= 1)); + *qarg1++ =3D (char *)"-L"; + *qarg1++ =3D (char *)interp_prefix; +#endif + ret =3D get_errno(execve(qemu_proc_pathname, qargp, envp)); + } else { + /* Getting the filename path failed. */ + ret =3D -TARGET_EBADF; + goto execve_end; + } + } else { + ret =3D get_errno(fexecve((int)path_or_fd, argp, envp)); + } + } else { + int fd; + + p =3D lock_user_string(path_or_fd); + if (p =3D=3D NULL) { + ret =3D -TARGET_EFAULT; + goto execve_end; + } + + /* + * Check the header and see if it a target elf binary. If so + * then execute using qemu user mode emulator. + */ + fd =3D open(p, O_RDONLY | O_CLOEXEC); + if (fd > 0 && is_target_elf_binary(fd) =3D=3D 1) { + close(fd); + /* execve() as a target binary using emulator. */ + memmove(qarg1 + 2, qarg1, (qargend - qarg1) * sizeof(*qarg1)); + qarg1[1] =3D qarg1[0]; + qarg1[0] =3D (char *)"-0"; + qarg1 +=3D 2; + qargend +=3D 2; + *qarg1 =3D (char *)p; +#ifndef DONT_INHERIT_INTERP_PREFIX + memmove(qarg1 + 2, qarg1, (qargend - qarg1) * sizeof(*qarg1)); + *qarg1++ =3D (char *)"-L"; + *qarg1++ =3D (char *)interp_prefix; +#endif + ret =3D get_errno(execve(qemu_proc_pathname, qargp, envp)); + } else { + close(fd); + /* Execve() as a host native binary. */ + ret =3D get_errno(execve(p, argp, envp)); + } + unlock_user(p, path_or_fd, 0); + } + +execve_end: + for (gp =3D guest_argp, q =3D argp; *q; gp +=3D sizeof(abi_ulong), q++= ) { + if (get_user_ual(addr, gp) || !addr) { + break; + } + unlock_user(*q, addr, 0); + } + + for (gp =3D guest_envp, q =3D envp; *q; gp +=3D sizeof(abi_ulong), q++= ) { + if (get_user_ual(addr, gp) || !addr) { + break; + } + unlock_user(*q, addr, 0); + } + + g_free(qarg0); + g_free(envp); + + return ret; +} + diff --git a/bsd-user/main.c b/bsd-user/main.c index f913cb55a7..a12b4be80f 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -88,7 +88,7 @@ unsigned long reserved_va =3D MAX_RESERVED_VA; unsigned long reserved_va; #endif =20 -static const char *interp_prefix =3D CONFIG_QEMU_INTERP_PREFIX; +const char *interp_prefix =3D CONFIG_QEMU_INTERP_PREFIX; const char *qemu_uname_release; char qemu_proc_pathname[PATH_MAX]; /* full path to exeutable */ =20 diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index 41c7bd31d3..6047805ae3 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -111,6 +111,7 @@ typedef struct TaskState { } __attribute__((aligned(16))) TaskState; =20 void stop_all_tasks(void); +extern const char *interp_prefix; extern const char *qemu_uname_release; =20 /* --=20 2.42.0