From patchwork Sun Sep 25 16:15:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 12988030 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2A568C54EE9 for ; Sun, 25 Sep 2022 16:20:48 +0000 (UTC) Received: from localhost ([::1]:45660 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ocUN5-0003wi-27 for qemu-devel@archiver.kernel.org; Sun, 25 Sep 2022 12:20:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38150) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ocUI5-0008KG-2w for qemu-devel@nongnu.org; Sun, 25 Sep 2022 12:15:37 -0400 Received: from mout.kundenserver.de ([217.72.192.75]:35615) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ocUI3-0005Yq-DD for qemu-devel@nongnu.org; Sun, 25 Sep 2022 12:15:36 -0400 Received: from quad ([82.142.8.70]) by mrelayeu.kundenserver.de (mreue109 [212.227.15.183]) with ESMTPSA (Nemesis) id 1MHG4c-1oPEk048sS-00DINQ; Sun, 25 Sep 2022 18:15:33 +0200 From: Laurent Vivier To: qemu-devel@nongnu.org Cc: Laurent Vivier Subject: [PATCH 1/2] linux-user: handle /proc/self/exe with execve() syscall Date: Sun, 25 Sep 2022 18:15:26 +0200 Message-Id: <20220925161527.374593-2-laurent@vivier.eu> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220925161527.374593-1-laurent@vivier.eu> References: <20220925161527.374593-1-laurent@vivier.eu> MIME-Version: 1.0 X-Provags-ID: V03:K1:r10wQjcsMwnRBGXgrEWmNOITrQypMreVTVzIzf1rAfE0Jum2K74 +ZmzcOekypPPsE7fgJpTg4lznblKUIOZ2ohrAT+1qO/o0g9odqVSnJK9AwgmKCTG55zXzz4 qB0rGNO8xXZyBAdcVgULiJGCoxpoebEgyH09qFTpyCMvPqm5gde1wiHx+g5OZCmjZ90CqYm itnAF92ONj5GaaTe7QgeQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:VwkIOfZ5FsY=:8wIhXCI1eTAEDpPvudyqAu ap+bHgHJDF105B5tG2vuE96PFvuCE5rheySSOWAa0yAsHoeo9m6iFMMDle8aVfGCadN6GFubS lh8QYGC+/476Pf0/Rhc58QLMVhlIuWho8vc+039eaIZbFY8405wQ26mssVXMspdr2CyMcRvrx drGk+VVTsj9wMZwsAnySgaslxcyw+YAWFhEJGJnN4tqe3c3UsznlTUX5v50DjgplSGxqzRZKM 0MlibdxID2vQ3bs3/3Sue2nLq6D8hGWa8z/1qRBESEgpwguJbJiR8lbXTd7yGGlbcp9zbnorW PNJySgApUQ4C8hbWp6JBkLPPYd2g8hXm/ioBFyJR1oApDY5ig5rf1LgjxPbR/DS+oRzPis1ox vd1R+iVDNXtOKr6xn8msUdLWFrUgWjwRfiR24LXeQ6Ohpn+7Nc7WTmrKpAJXLxwX/+0VJ9hmT qE5gPfPfDWl3om7gIjnOUBIVMUBumvtpcTFsSDTGNwUmRbg0j1H+pScIQGehCt0rHGbLEtJ1A qsfbl5ntLLDxR+iIjdzUUXRyP/1qD2xEPJdmaazIUFoT6N6ivK5IlGhfxM+ydztxy2iHi5JdJ xfRYf1pT0p77MIxf3WYtL4aFgXnRap1EoRdfQJZE6g0qeY0xw8g7bEIafFje5jxwEufQasrlT d5FVMphBaE3n6zmQnXIYsfAB+ECyolhrQmyxqGvKcTZEX9N5znrD5BFcnsVBfjRZu3YuEzI4h kYi9PP4yE5fefONI/mXQ2D29AIzLrzWLWHOMm+HlRjzBDyL3I14VRPqeOqslw3pJUIzS8o56i N9o519V Received-SPF: none client-ip=217.72.192.75; envelope-from=laurent@vivier.eu; helo=mout.kundenserver.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_NONE=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+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" If path is /proc/self/exe, use the executable file descriptor provided by binfmt_misc (or opened by main()) with execveat(). Signed-off-by: Laurent Vivier --- linux-user/main.c | 9 +++++++-- linux-user/syscall.c | 9 ++++++++- linux-user/user-internals.h | 1 + 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index e44bdb17b853..f915bdd7cef7 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -64,6 +64,7 @@ #endif char *exec_path; +int execfd; int singlestep; static const char *argv0; @@ -646,7 +647,6 @@ int main(int argc, char **argv, char **envp) int target_argc; int i; int ret; - int execfd; unsigned long max_reserved_va; bool preserve_argv0; @@ -845,7 +845,12 @@ int main(int argc, char **argv, char **envp) fd_trans_init(); - ret = loader_exec(execfd, exec_path, target_argv, target_environ, regs, + /* + * loader_exec() closes the file descriptor provided by the caller. + * As we need to keep it available for execve("/proc/self/exe") + * we provide a copy to loader_exec(). + */ + ret = loader_exec(dup(execfd), exec_path, target_argv, target_environ, regs, info, &bprm); if (ret != 0) { printf("Error while loading %s: %s\n", exec_path, strerror(-ret)); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index f4091212027c..6642652b7644 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -649,6 +649,8 @@ safe_syscall4(pid_t, wait4, pid_t, pid, int *, status, int, options, \ safe_syscall5(int, waitid, idtype_t, idtype, id_t, id, siginfo_t *, infop, \ int, options, struct rusage *, rusage) safe_syscall3(int, execve, const char *, filename, char **, argv, char **, envp) +safe_syscall5(int, execveat, int, dirfd, const char *, pathname, char **, \ + argv, char **, envp, int, flags) #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \ defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64) safe_syscall6(int, pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, \ @@ -8843,7 +8845,12 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, * before the execve completes and makes it the other * program's problem. */ - ret = get_errno(safe_execve(p, argp, envp)); + if (is_proc_myself(p, "exe")) { + ret = get_errno(safe_execveat(execfd, "", argp, envp, + AT_EMPTY_PATH)); + } else { + ret = get_errno(safe_execve(p, argp, envp)); + } unlock_user(p, arg1, 0); goto execve_end; diff --git a/linux-user/user-internals.h b/linux-user/user-internals.h index 0280e76addda..84f29a1e2990 100644 --- a/linux-user/user-internals.h +++ b/linux-user/user-internals.h @@ -23,6 +23,7 @@ #include "qemu/log.h" extern char *exec_path; +extern int execfd; void init_task_state(TaskState *ts); void task_settid(TaskState *); void stop_all_tasks(void); From patchwork Sun Sep 25 16:15:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 12988029 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DE556C6FA82 for ; Sun, 25 Sep 2022 16:18:05 +0000 (UTC) Received: from localhost ([::1]:58836 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ocUKS-0001Ms-Rj for qemu-devel@archiver.kernel.org; Sun, 25 Sep 2022 12:18:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38152) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ocUI5-0008KN-DS for qemu-devel@nongnu.org; Sun, 25 Sep 2022 12:15:37 -0400 Received: from mout.kundenserver.de ([212.227.17.13]:39761) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ocUI3-0005Yt-Qc for qemu-devel@nongnu.org; Sun, 25 Sep 2022 12:15:37 -0400 Received: from quad ([82.142.8.70]) by mrelayeu.kundenserver.de (mreue109 [212.227.15.183]) with ESMTPSA (Nemesis) id 1MmDAc-1p2zKv2GpM-00iDHg; Sun, 25 Sep 2022 18:15:33 +0200 From: Laurent Vivier To: qemu-devel@nongnu.org Cc: Laurent Vivier Subject: [PATCH 2/2] linux-user: don't use AT_EXECFD in do_openat() Date: Sun, 25 Sep 2022 18:15:27 +0200 Message-Id: <20220925161527.374593-3-laurent@vivier.eu> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220925161527.374593-1-laurent@vivier.eu> References: <20220925161527.374593-1-laurent@vivier.eu> MIME-Version: 1.0 X-Provags-ID: V03:K1:heDivYGpA7kVL/ZoD8ZNwfk2WHmNl+61vu8j9Z8m/bB8PZCkqE4 QiLB+yeFadOInI/ZKjxVctIdr8k9caBYbrrjpfkegMBOhqs6OHXOwOCmihuorUTYWkegU3d BzHDJu8q5C972aO2+VKxKf60rU196jb/72CHLtIYNVOj13ad/qvx/iXm872I7LB9Qq0ci1Q BEKycMHhq4t7Nyup1/7xg== X-UI-Out-Filterresults: notjunk:1;V03:K0:XpHW6CjWTmY=:yqsAqAEDxyMgYhiiRQVXc1 FMoIiTq4jXnTvl/BwNQInMk7MIBI4O9SMzLgnBYO6qGh3guRfj4d1/PJmEWSZH8bPyvrE88Hz 9EhrnyoCbf5j3DKp0Br7EP0lfljW2TspRMqRFMxYmRLHvx4KhghrxhiijeM6SM1w/ujTQW4l8 2YLbT3k8D0sxR1O3JeJ4uXpwe6R+19K/zOHtSQ9KJPfjU9evg6ompalWNe36uBV9ahVASiEa+ Odt/9pO32zWAzcKUa+wj0W4g2VKVg0G16lEGGh4UlrpWniaEmUMrKEwlpQhfc3wwZqD4Q3NMi +GE3kRI1fFlqjIHtCMxKaCWesRUKIV3GXVB5pWJnEiys0/gxYhqVtQNt0vI/HDdoxdQVYd7z2 HWBo59WZWU6uFj1pcyVOrKY/DWeWI5zotZOIe4q0zpMKQurxjtO3xtnIp5wrKXoeIVydpwppA OvQ3PorITeRTBEv/g8MHAV2r89++P3Ope1Ux5Z9SoBcSuNl4nfaiXjA2Fd29rH1d+LmvEOZNH fjOllbB74AdlPE4dwCjYBueq9wn5buds1OYVRVS69N1mNJpzVfd8tb/FbGbvqO5z/bPJ+RJKH dYu4cfQeebUS5mVmOulMQe4LpiX1MwISB/D96VQlCcGwWxGPNriNyK7/GaQVGV1ebyILl4SSe Kwfvh32vN3mYVkTS9o7Sglg/ufaglCI5Ukd5UZKP1vnpYOFTmmaeH60SkTKq+rsN04EWsPMwF ozqsMxClg7LB2bYBjoPLDrGotq/a0bFkg6vh/hoDSi0B5OIWy5eaBmWJS+0z4CVYEQCk+V+3g 3yMet2J Received-SPF: none client-ip=212.227.17.13; envelope-from=laurent@vivier.eu; helo=mout.kundenserver.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_NONE=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+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" AT_EXECFD gives access to the binary file even if it is not readable (only executable). Moreover it can be opened with flags and mode that are not the ones provided by do_openat() caller. And finally the caller can close the file descriptor whereas we can need it with execveat(). To avoid that, use only safe_openat() with the exec_path. Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 6642652b7644..01f03535fe64 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8265,8 +8265,7 @@ static int do_openat(CPUArchState *cpu_env, int dirfd, const char *pathname, int }; if (is_proc_myself(pathname, "exe")) { - int execfd = qemu_getauxval(AT_EXECFD); - return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode); + return safe_openat(dirfd, exec_path, flags, mode); } for (fake_open = fakes; fake_open->filename; fake_open++) {