From patchwork Thu May 31 22:49:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 137444 Delivered-To: patch@linaro.org Received: by 2002:a2e:9706:0:0:0:0:0 with SMTP id r6-v6csp207829lji; Thu, 31 May 2018 15:49:43 -0700 (PDT) X-Google-Smtp-Source: ADUXVKIiWO3o8ZWV7pk9Gesi4bzVY02+Ne47GwavG2ynQOCVm7X26D4HCOqse9TOzfnl8pfempqm X-Received: by 2002:a37:4e8c:: with SMTP id c134-v6mr146033qkb.207.1527806983650; Thu, 31 May 2018 15:49:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527806983; cv=none; d=google.com; s=arc-20160816; b=czLHdCxVMoG5JL32DUyubdm1IeOh7/8fQ3UMV+RGP5Rfx0dxNyZNlLWbprE3rC5pbF J+egFug6LTbpTPnBOmjk8uLBRxZ2Z6NkUVjatXuGmKagAAF2daircN9rkhpCaUBxI+C/ 4KMym/ShwAVNvLsmEQ3/d7f7NShLa4gMEzy43WvFMqRwYEzn3uFEHBBSG42bCxNEn3XC P85i7Y8M+J3bWUSGTKITZL/TAocAnztitSocHrSj8KRIzn9zJxhGxElneyYucWPuSxk8 hmG6ylitHVYWhj9YUe+YB0H6j2qXygj9VhH5h6/RoNXv3K5yp42GkZ8PjIXaS+mZTQeY r4ug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=dc9nmEC4EhhoiijrUSkV24PteoW8Hb15c4lSKrNTdhc=; b=0YYJG7/TiYx7R1ysu4JZD1RnPnH4BOq+0LsjO7h1HyCadikdemWIAu0BfZjleHco0/ 0E8W+/UoDbcB92MKlgB30Op07fSFT1Tksx1DGn4xMSuwWAklANFT5gftKmhABkLU2hcT c+/WwqjnAafS3Weywmf49vTTtaWK7pN+1hW7qoq+v7X+S81WYlsL+2o3TGXAlHJRBACE LfppDRTtO9atTk4nEQbOfI8iMB0k9Y0+jrRQrKPeE0rpAyqHD6aiUiMYK8t3pvtTjFvm iizfhz50/xRdv1YjI+dmyLQvWe0hK0FA6CXk0R7dAKgvCLNg8m3oq1cf/Fa0xVPZGXSZ /l9A== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=b6KsWPso; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id w17-v6si519451qvd.275.2018.05.31.15.49.43 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 31 May 2018 15:49:43 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=b6KsWPso; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:46493 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fOWO7-000584-3L for patch@linaro.org; Thu, 31 May 2018 18:49:43 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38488) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fOWNi-00056J-EY for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fOWNg-0000k1-9P for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:18 -0400 Received: from mail-pg0-x22a.google.com ([2607:f8b0:400e:c05::22a]:38598) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fOWNg-0000jV-3I for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:16 -0400 Received: by mail-pg0-x22a.google.com with SMTP id c9-v6so7528196pgf.5 for ; Thu, 31 May 2018 15:49:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=dc9nmEC4EhhoiijrUSkV24PteoW8Hb15c4lSKrNTdhc=; b=b6KsWPsowirLWGQeC0h95k+bgZWIOQEvTdR8u+xI0abJeRV/CfMZ+Ld1NHMqfvNBAE WFvnsKO6pl3dnH5EffsboswTLoUPMBFGSU4TUZaGg1senGtg4W86DluiSCHgMdiPbxxB N7AVODxaUGxalSjlm1/l5B5hiPdxkAojB3mHc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=dc9nmEC4EhhoiijrUSkV24PteoW8Hb15c4lSKrNTdhc=; b=AHAaZpE6NRo0TUSDCMKqNodNaTW/9xv2JT1iBZMvS7njHXBph5VUqUDkhlepInnrr7 V7lKbcC8EsyebDS+JxV1xMIzFZV4oPUOj1CT+QYMZAcf5PCUIy6qnHKv5kGIsJz8MTcy A1viHgycLUBXQNaie4gewRdfODSPMjOwV4HOymIQJ2eoMg2E17nSP8TWEM5hF326kseO onNYwKE/T+WYfqhPBgx4LFS72JOE0l6PUSGaux0lKlbHD/dz5kSYorit+W9gBwUyoKkm 8x3ZHrD05OghWHbAGe5lhinxA3cP9EBR/YBPshEZjfezXWuYlcU/qmQ5/vt1kAl4W9eK NCJQ== X-Gm-Message-State: ALKqPweIUiQ1Ym3qV8SSb+q5kewjAsh9wPYzufPR+P+9N7H5zWZGLpWT mTGiFqy8o1v2G1eTjahctmOmZGHvKb4= X-Received: by 2002:a62:ed12:: with SMTP id u18-v6mr8488604pfh.127.1527806954743; Thu, 31 May 2018 15:49:14 -0700 (PDT) Received: from cloudburst.twiddle.net (97-126-112-211.tukw.qwest.net. [97.126.112.211]) by smtp.gmail.com with ESMTPSA id t3-v6sm33385584pgs.91.2018.05.31.15.49.13 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 31 May 2018 15:49:13 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 31 May 2018 15:49:06 -0700 Message-Id: <20180531224911.23725-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180531224911.23725-1-richard.henderson@linaro.org> References: <20180531224911.23725-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c05::22a Subject: [Qemu-devel] [PATCH 1/6] gdbstub: Return the fd from gdbserver_start X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, laurent@vivier.eu, evgreen@chromium.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" This will allow us to protect gdbserver_fd from the guest. Signed-off-by: Richard Henderson --- gdbstub.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) -- 2.17.0 Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier diff --git a/gdbstub.c b/gdbstub.c index 6081e719c5..057d0d65c5 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1890,15 +1890,16 @@ static int gdbserver_open(int port) int gdbserver_start(int port) { gdbserver_fd = gdbserver_open(port); - if (gdbserver_fd < 0) + if (gdbserver_fd < 0) { return -1; + } /* accept connections */ if (!gdb_accept()) { close(gdbserver_fd); gdbserver_fd = -1; return -1; } - return 0; + return gdbserver_fd; } /* Disable gdb stub for child processes. */ From patchwork Thu May 31 22:49:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 137446 Delivered-To: patch@linaro.org Received: by 2002:a2e:9706:0:0:0:0:0 with SMTP id r6-v6csp209397lji; Thu, 31 May 2018 15:51:57 -0700 (PDT) X-Google-Smtp-Source: ADUXVKJSeD6IM3/z68yf6zFfMiR7mVeZYqKpq3H2YawyDQu0+zUHZIW2GLQ+cf5AaBIQMOhWIz2G X-Received: by 2002:ac8:65c6:: with SMTP id t6-v6mr8884075qto.347.1527807117076; Thu, 31 May 2018 15:51:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527807117; cv=none; d=google.com; s=arc-20160816; b=m/FAiYlJJBtFabHcl5NqYZsbTiOPTFy4NZYPcZ6/m4WudPbouFEJ8TYPethYoc5kPO XFzZsBXE9sTHzCk0Z2+BgYrEpMPl+h/sNsJGGfY+GOOQ5YSoWRh2Yuw1hGlqVF7x29x+ MmEorcuVgYN2s9T0G8RYueWjNCmfwRf4VCf32xrK0s1CNPgm4HOOITxJGZtfP4LRX3ci NBeFwp2Jd9+7ZxrpXWnOYr8HCzxoRQlJaN57/g5Gj/5+yAglYYDt6VF+A3kGmEDW3ln8 bsqEmhoiaWzfMzTYUY0rX+s9+jIlGASrc9UavTRmE15rE3C7DOFoUAB1qKkYOS73H3lX dlbw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=4kx9iWqrZaAigsaP3mi/Tl0rT4kzKW4FmGtRPBRUajU=; b=U/rmskKO74jd7zanND/6+PJ4XtDOMuKJ/pvmKdX2MDHrYRGLYLkPzkntDdMBObImY8 8jA4EfLQOA8AjI48IJeBG18qQ164byJV5E/AokVu2NKb2uz9M7HRAyGf6oPodwOjL/8c mf7u9s2JJX1dNd7AEMumCDEe7lKh9NwVOsAsBaAfj9QUkieHvwLG/iUdXvJau7gKoorq BCnM7se04hTq/A5waYZAqLtrpxjNIVXgHmPTeixNc8vTpm4M2tckRyK70tEGOp6NWPHb V+c/dyXLW5y8odJ43Z2E9MjReECoDrChxhuy+n4GX3S2jZeIWXqQtntmtmeq4eTMYMfh 3bwg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=IHPHY/Pn; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id e10-v6si5919676qvm.131.2018.05.31.15.51.56 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 31 May 2018 15:51:57 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=IHPHY/Pn; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:46508 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fOWQG-0007Tp-He for patch@linaro.org; Thu, 31 May 2018 18:51:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38492) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fOWNi-00056K-O0 for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fOWNh-0000lA-O2 for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:18 -0400 Received: from mail-pf0-x243.google.com ([2607:f8b0:400e:c00::243]:37862) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fOWNh-0000ke-Hp for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:17 -0400 Received: by mail-pf0-x243.google.com with SMTP id e9-v6so11490070pfi.4 for ; Thu, 31 May 2018 15:49:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4kx9iWqrZaAigsaP3mi/Tl0rT4kzKW4FmGtRPBRUajU=; b=IHPHY/PnNxiLGBmD/SOzbwnkkztdegq25rSlB7OPUunzCK6SbcTfqBBM66R4+/3pdY q2202u4GyvLsds4bLhwObFfgA0cHNBP8/xPjjp5fA+MsIfY6UlJfMhMHQqUSeDDaIN2b XkK/t3gK72wOX8Q72u3+o7CQoKNmBhZPvVPrk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=4kx9iWqrZaAigsaP3mi/Tl0rT4kzKW4FmGtRPBRUajU=; b=nui0YBdu4vQKIfJ4EYvRMqAV3S1DBIKEntiW9RRjzYoBGKTZG/SAZBmmDHhFCNfCUf jR4n/D9AW50yiFhg9MVRLJYyHKwTDS3m/rRmQARLYo9f3+t396Rf4ZdmaptyhpflYCy3 4eQC2Vi+qMTY6fHUHo7Acrecc14pGSfAYSn1yEsp7OwnTw56X1A5JFnKYuoZ1UXfz5Yj AhUnv0uJ7J3MAU49dHeGH+jE7FoaDyCOFSOLxPjABTfy7cP8lpEktCiCv5NQ+CNaJM+R t+Xn04VJ/01KOCwte3aes2SHrB+vFqNkOXRK6VPGQbfTlHPCtsWmo37AyIUEiJ7a8H9H Jnog== X-Gm-Message-State: ALKqPwfqq35wazyVInARj3bei/QR4W6GuwCLOTEvjLDRvNkkKUArVwpO zsXdIDm1ouMY0N882hhEgsPvWy4kM5c= X-Received: by 2002:a62:1411:: with SMTP id 17-v6mr8512872pfu.3.1527806956101; Thu, 31 May 2018 15:49:16 -0700 (PDT) Received: from cloudburst.twiddle.net (97-126-112-211.tukw.qwest.net. [97.126.112.211]) by smtp.gmail.com with ESMTPSA id t3-v6sm33385584pgs.91.2018.05.31.15.49.14 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 31 May 2018 15:49:15 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 31 May 2018 15:49:07 -0700 Message-Id: <20180531224911.23725-3-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180531224911.23725-1-richard.henderson@linaro.org> References: <20180531224911.23725-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::243 Subject: [Qemu-devel] [PATCH 2/6] linux-user: Add host_fds and manipulators X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, laurent@vivier.eu, evgreen@chromium.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" This allows emulation of guest syscalls to reject manipulations to fds used by the host. Signed-off-by: Richard Henderson --- linux-user/qemu.h | 30 ++++++++++++++++++++++++++++++ linux-user/main.c | 27 ++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) -- 2.17.0 Reviewed-by: Laurent Vivier diff --git a/linux-user/qemu.h b/linux-user/qemu.h index c55c8e294b..33dafbe0e4 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -155,6 +155,36 @@ void task_settid(TaskState *); void stop_all_tasks(void); extern const char *qemu_uname_release; extern unsigned long mmap_min_addr; +extern fd_set host_fds; + +/** + * is_hostfd: + * @fd: file descriptor to check + * + * Return true if @fd is being used by the host and therefore any + * guest system call referencing @fd should return EBADF. + */ +static inline bool is_hostfd(int fd) +{ + return fd >= 0 && fd < FD_SETSIZE && FD_ISSET(fd, &host_fds); +} + +/** + * contains_hostfd: + * @fds: fd_set of descriptors to check + * + * Return true if any descriptor in @fds are being used by the host + * and therefore the guest system call should return EBADF. + */ +bool contains_hostfd(const fd_set *fds); + +/** + * add_hostfd: + * @fd: file descriptor to reserve + * + * Add @fd to the set of file descriptors to reserve for the host. + */ +void add_hostfd(int fd); /* ??? See if we can avoid exposing so much of the loader internals. */ diff --git a/linux-user/main.c b/linux-user/main.c index 78d6d3e7eb..ee3f323c08 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -49,6 +49,7 @@ static const char *cpu_type; unsigned long mmap_min_addr; unsigned long guest_base; int have_guest_base; +fd_set host_fds; /* * When running 32-on-64 we should make sure we can fit all of the possible @@ -112,6 +113,23 @@ int cpu_get_pic_interrupt(CPUX86State *env) } #endif +bool contains_hostfd(const fd_set *fds) +{ + int i; + for (i = 0; i < ARRAY_SIZE(__FDS_BITS(fds)); ++i) { + if (__FDS_BITS(fds)[i] & __FDS_BITS(&host_fds)[i]) { + return true; + } + } + return true; +} + +void add_hostfd(int fd) +{ + g_assert(fd >= 0 && fd < FD_SETSIZE); + FD_SET(fd, &host_fds); +} + /***********************************************************/ /* Helper routines for implementing atomic operations. */ @@ -805,12 +823,19 @@ int main(int argc, char **argv, char **envp) target_cpu_copy_regs(env, regs); + /* Prevent the guest from closing the log file. */ + if (qemu_logfile && qemu_logfile != stderr) { + add_hostfd(fileno(qemu_logfile)); + } + if (gdbstub_port) { - if (gdbserver_start(gdbstub_port) < 0) { + int fd = gdbserver_start(gdbstub_port); + if (fd < 0) { fprintf(stderr, "qemu: could not open gdbserver on port %d\n", gdbstub_port); exit(EXIT_FAILURE); } + add_hostfd(fd); gdb_handlesig(cpu, 0); } cpu_loop(env); From patchwork Thu May 31 22:49:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 137450 Delivered-To: patch@linaro.org Received: by 2002:a2e:9706:0:0:0:0:0 with SMTP id r6-v6csp212143lji; Thu, 31 May 2018 15:56:17 -0700 (PDT) X-Google-Smtp-Source: ADUXVKJmsF0Atu/VnP1CHAvk7tzPfy9bbBYN+qJZzSUk8c9BSyU0uyqSO4V/dg7dtx+BainCRXFj X-Received: by 2002:a0c:f845:: with SMTP id g5-v6mr8350417qvo.150.1527807377331; Thu, 31 May 2018 15:56:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527807377; cv=none; d=google.com; s=arc-20160816; b=g4R2g1ELuWwhYmofFtplK5/dP+z1uXbwrYME8Cpygt6t5WNacWNCru7psK/YQlhNUy 47gFWueGpb29xJlOANnuY7Pyee5i4JL0m7hKTHxx/vg/5kUj42GI8uQrEtPi1Cgf8k+D kSVcy6QzRbe/C7nIMEoceay+a/bZlQkdIdVYEJw+U3SVbecfFUh8uP6/x14Bhsbt5Sv+ gIYdMfAOIr2cIS53bV7w62MNg/hXETAG5QhidapdRAY+sXBJSna1LA6lpoCrxhMAzgkc HOgqqmaBIR0rhBq/Dx5124ydgaaWOhIogoXaEbIfZ5b26OSSu2W6FzPnYBrE6yQHqRjc 65NA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=gmDyDf7PgQJa87IpvETmA8ipIStbcbJNh9qw/rzUD1s=; b=1Ly8/BQzpLawh47sMagrb7Y5YlH8e5x9hDmcpF10Vqnm3Zo2CgqjJ2YbwImneGSG7z yZQZldkvLuf2VvqFjrr6nhJPNypd7WFh0qhRv5JQg92np0CMzLVKpqK0a2GzaEAzyPsq TXyGpPK0ifcKX4KwC8Z7bLutqb9sXi8hHCmClPLD3TRuky1oWrx0z9glVs9TaeSupwhU ryycEahKf8sYSiAJrAXBxD0jLUChIO0rkWyYX4dYM8Wt5r8JhEuc084r6+XcH2tK5C4r +Ar9eUzU22BBayA1vqAdT+IYmPI8TVwxMVJ59hWa0MKPxaL169wDoE7iN593inmWeyyv 9xAQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=j3xhvY59; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id f203-v6si3850422qkb.43.2018.05.31.15.56.17 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 31 May 2018 15:56:17 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=j3xhvY59; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:46548 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fOWUS-0002At-Q9 for patch@linaro.org; Thu, 31 May 2018 18:56:16 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38519) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fOWNm-00059y-Kz for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fOWNj-0000nN-Ml for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:22 -0400 Received: from mail-pf0-x243.google.com ([2607:f8b0:400e:c00::243]:35356) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fOWNj-0000mY-BU for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:19 -0400 Received: by mail-pf0-x243.google.com with SMTP id x9-v6so11494872pfm.2 for ; Thu, 31 May 2018 15:49:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=gmDyDf7PgQJa87IpvETmA8ipIStbcbJNh9qw/rzUD1s=; b=j3xhvY59XR9eALmO+eWoeFbq0DTBBO/R9cNIa55JBnfndx+7oY6/GW/P6v1MSLvcYG odS4KVgMDOyO/3U98hAmlgYgMMZ2IQiBkU9yignjsQYLvyJhoLh9IT198iFfqh5roeQ3 PcvxoHNLwsXPVyMrkpOxSD+cxYTzasnl4kF08= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=gmDyDf7PgQJa87IpvETmA8ipIStbcbJNh9qw/rzUD1s=; b=n7hrSeO+O/TKWtY3463nZSbsDxW4UYVzXkH9m7eRuHsNibyqo5mWnNg5uFX4gj0VuJ 6O0S/ny2i7L//2Orjoc8cKYlqg9anUxymN+aya9jOxlDipga4m4IAfU/FGkA+p9yyHPT ahh2aznCcC2Ec0aaPUsbnHOT3lSKBn0Jsq5MtFXUgizjQLuKEBI6hNtLIEw0ps5qSvfs krJNyS5Gfe98STXWJjoKbfuRVHRKzdgQDIcvr6ALgAMtBctoBadE+g4/sQKYeUZjApfD EWS8hKNBp/94rq1Fcp6ION3s4ViMbAqF/+mY8ZURgVrUEXNyzVUcSQw4S88/DpwGRRzm lCGA== X-Gm-Message-State: ALKqPwfSESppAXYbXXNX7Vc78M2GEATjC1CkvYHzKJ8NEHsfq9MHRVuT kR2ZrOPZs14pUYz1LSRuUR9Legd4ink= X-Received: by 2002:a62:cd45:: with SMTP id o66-v6mr8464919pfg.250.1527806957628; Thu, 31 May 2018 15:49:17 -0700 (PDT) Received: from cloudburst.twiddle.net (97-126-112-211.tukw.qwest.net. [97.126.112.211]) by smtp.gmail.com with ESMTPSA id t3-v6sm33385584pgs.91.2018.05.31.15.49.16 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 31 May 2018 15:49:16 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 31 May 2018 15:49:08 -0700 Message-Id: <20180531224911.23725-4-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180531224911.23725-1-richard.henderson@linaro.org> References: <20180531224911.23725-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::243 Subject: [Qemu-devel] [PATCH 3/6] linux-user: Check is_hostfd in do_syscall X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, laurent@vivier.eu, evgreen@chromium.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" This is the vast majority of all fd inputs, but not all. Signed-off-by: Richard Henderson --- linux-user/syscall.c | 303 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 280 insertions(+), 23 deletions(-) -- 2.17.0 Reviewed-by: Laurent Vivier diff --git a/linux-user/syscall.c b/linux-user/syscall.c index d02c16bbc6..5339f0bc1c 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8034,6 +8034,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, if (arg3 == 0) ret = 0; else { + if (is_hostfd(arg1)) { + goto ebadf; + } if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) goto efault; ret = get_errno(safe_read(arg1, p, arg3)); @@ -8045,6 +8048,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } break; case TARGET_NR_write: + if (is_hostfd(arg1)) { + goto ebadf; + } if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) goto efault; if (fd_trans_target_to_host_data(arg1)) { @@ -8072,6 +8078,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; #endif case TARGET_NR_openat: + if (is_hostfd(arg1)) { + goto ebadf; + } if (!(p = lock_user_string(arg2))) goto efault; ret = get_errno(do_openat(cpu_env, arg1, p, @@ -8082,16 +8091,25 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; #if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE) case TARGET_NR_name_to_handle_at: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_name_to_handle_at(arg1, arg2, arg3, arg4, arg5); break; #endif #if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE) case TARGET_NR_open_by_handle_at: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_open_by_handle_at(arg1, arg2, arg3); fd_trans_unregister(ret); break; #endif case TARGET_NR_close: + if (is_hostfd(arg1)) { + goto ebadf; + } fd_trans_unregister(arg1); ret = get_errno(close(arg1)); break; @@ -8155,7 +8173,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #if defined(TARGET_NR_linkat) case TARGET_NR_linkat: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { void * p2 = NULL; if (!arg2 || !arg4) goto efault; @@ -8180,6 +8200,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #if defined(TARGET_NR_unlinkat) case TARGET_NR_unlinkat: + if (is_hostfd(arg1)) { + goto ebadf; + } if (!(p = lock_user_string(arg2))) goto efault; ret = get_errno(unlinkat(arg1, p, arg3)); @@ -8311,6 +8334,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #if defined(TARGET_NR_mknodat) case TARGET_NR_mknodat: + if (is_hostfd(arg1)) { + goto ebadf; + } if (!(p = lock_user_string(arg2))) goto efault; ret = get_errno(mknodat(arg1, p, arg3, arg4)); @@ -8334,6 +8360,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, goto unimplemented; #endif case TARGET_NR_lseek: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = get_errno(lseek(arg1, arg2, arg3)); break; #if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA) @@ -8484,7 +8513,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #if defined(TARGET_NR_futimesat) case TARGET_NR_futimesat: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { struct timeval *tvp, tv[2]; if (arg3) { if (copy_from_user_timeval(&tv[0], arg3) @@ -8520,6 +8551,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat) case TARGET_NR_faccessat: + if (is_hostfd(arg1)) { + goto ebadf; + } if (!(p = lock_user_string(arg2))) goto efault; ret = get_errno(faccessat(arg1, p, arg3, 0)); @@ -8564,7 +8598,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #if defined(TARGET_NR_renameat) case TARGET_NR_renameat: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { void *p2; p = lock_user_string(arg2); p2 = lock_user_string(arg4); @@ -8579,7 +8615,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #if defined(TARGET_NR_renameat2) case TARGET_NR_renameat2: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { void *p2; p = lock_user_string(arg2); p2 = lock_user_string(arg4); @@ -8603,6 +8641,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #if defined(TARGET_NR_mkdirat) case TARGET_NR_mkdirat: + if (is_hostfd(arg1)) { + goto ebadf; + } if (!(p = lock_user_string(arg2))) goto efault; ret = get_errno(mkdirat(arg1, p, arg3)); @@ -8618,6 +8659,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; #endif case TARGET_NR_dup: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = get_errno(dup(arg1)); if (ret >= 0) { fd_trans_dup(arg1, ret); @@ -8720,6 +8764,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_dup2 case TARGET_NR_dup2: + if (is_hostfd(arg1) || is_hostfd(arg2)) { + goto ebadf; + } ret = get_errno(dup2(arg1, arg2)); if (ret >= 0) { fd_trans_dup(arg1, arg2); @@ -8731,6 +8778,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, { int host_flags; + if (is_hostfd(arg1) || is_hostfd(arg2)) { + goto ebadf; + } if ((arg3 & ~TARGET_O_CLOEXEC) != 0) { return -EINVAL; } @@ -9424,7 +9474,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #if defined(TARGET_NR_symlinkat) case TARGET_NR_symlinkat: - { + if (is_hostfd(arg2)) { + goto ebadf; + } else { void *p2; p = lock_user_string(arg1); p2 = lock_user_string(arg3); @@ -9475,7 +9527,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #if defined(TARGET_NR_readlinkat) case TARGET_NR_readlinkat: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { void *p2; p = lock_user_string(arg2); p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0); @@ -9619,13 +9673,22 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, unlock_user(p, arg1, 0); break; case TARGET_NR_ftruncate: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = get_errno(ftruncate(arg1, arg2)); break; case TARGET_NR_fchmod: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = get_errno(fchmod(arg1, arg2)); break; #if defined(TARGET_NR_fchmodat) case TARGET_NR_fchmodat: + if (is_hostfd(arg1)) { + goto ebadf; + } if (!(p = lock_user_string(arg2))) goto efault; ret = get_errno(fchmodat(arg1, p, arg3, 0)); @@ -9688,6 +9751,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } break; case TARGET_NR_fstatfs: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = get_errno(fstatfs(arg1, &stfs)); goto convert_statfs; #ifdef TARGET_NR_statfs64 @@ -9718,6 +9784,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } break; case TARGET_NR_fstatfs64: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = get_errno(fstatfs(arg1, &stfs)); goto convert_statfs64; #endif @@ -9732,84 +9801,135 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_accept case TARGET_NR_accept: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_accept4(arg1, arg2, arg3, 0); break; #endif #ifdef TARGET_NR_accept4 case TARGET_NR_accept4: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_accept4(arg1, arg2, arg3, arg4); break; #endif #ifdef TARGET_NR_bind case TARGET_NR_bind: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_bind(arg1, arg2, arg3); break; #endif #ifdef TARGET_NR_connect case TARGET_NR_connect: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_connect(arg1, arg2, arg3); break; #endif #ifdef TARGET_NR_getpeername case TARGET_NR_getpeername: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_getpeername(arg1, arg2, arg3); break; #endif #ifdef TARGET_NR_getsockname case TARGET_NR_getsockname: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_getsockname(arg1, arg2, arg3); break; #endif #ifdef TARGET_NR_getsockopt case TARGET_NR_getsockopt: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5); break; #endif #ifdef TARGET_NR_listen case TARGET_NR_listen: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = get_errno(listen(arg1, arg2)); break; #endif #ifdef TARGET_NR_recv case TARGET_NR_recv: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0); break; #endif #ifdef TARGET_NR_recvfrom case TARGET_NR_recvfrom: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6); break; #endif #ifdef TARGET_NR_recvmsg case TARGET_NR_recvmsg: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_sendrecvmsg(arg1, arg2, arg3, 0); break; #endif #ifdef TARGET_NR_send case TARGET_NR_send: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0); break; #endif #ifdef TARGET_NR_sendmsg case TARGET_NR_sendmsg: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_sendrecvmsg(arg1, arg2, arg3, 1); break; #endif #ifdef TARGET_NR_sendmmsg case TARGET_NR_sendmmsg: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 1); break; case TARGET_NR_recvmmsg: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0); break; #endif #ifdef TARGET_NR_sendto case TARGET_NR_sendto: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6); break; #endif #ifdef TARGET_NR_shutdown case TARGET_NR_shutdown: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = get_errno(shutdown(arg1, arg2)); break; #endif @@ -9835,6 +9955,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_setsockopt case TARGET_NR_setsockopt: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5); break; #endif @@ -9938,7 +10061,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, goto do_stat; #endif case TARGET_NR_fstat: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { ret = get_errno(fstat(arg1, &st)); #if defined(TARGET_NR_stat) || defined(TARGET_NR_lstat) do_stat: @@ -10110,6 +10235,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; #endif case TARGET_NR_fsync: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = get_errno(fsync(arg1)); break; case TARGET_NR_clone: @@ -10225,6 +10353,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = get_errno(getpgid(arg1)); break; case TARGET_NR_fchdir: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = get_errno(fchdir(arg1)); break; #ifdef TARGET_NR_bdflush /* not on x86_64 */ @@ -10244,7 +10375,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR__llseek /* Not on alpha */ case TARGET_NR__llseek: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { int64_t res; #if !defined(__NR_llseek) res = lseek(arg1, ((uint64_t)arg2 << 32) | (abi_ulong)arg3, arg5); @@ -10264,6 +10397,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_getdents case TARGET_NR_getdents: + if (is_hostfd(arg1)) { + goto ebadf; + } #ifdef EMULATE_GETDENTS_WITH_GETDENTS #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 { @@ -10396,7 +10532,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif /* TARGET_NR_getdents */ #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64) case TARGET_NR_getdents64: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { struct linux_dirent64 *dirp; abi_long count = arg3; if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0))) @@ -10454,10 +10592,19 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, goto efault; } + ret = 0; pfd = alloca(sizeof(struct pollfd) * nfds); for (i = 0; i < nfds; i++) { pfd[i].fd = tswap32(target_pfd[i].fd); pfd[i].events = tswap16(target_pfd[i].events); + if (is_hostfd(pfd[i].fd)) { + ret = -TARGET_EBADF; + } + } + if (ret < 0) { + unlock_user(target_pfd, arg1, + sizeof(struct target_pollfd) * nfds); + goto fail; } } @@ -10541,10 +10688,15 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_flock: /* NOTE: the flock constant seems to be the same for every Linux platform */ + if (is_hostfd(arg1)) { + goto ebadf; + } ret = get_errno(safe_flock(arg1, arg2)); break; case TARGET_NR_readv: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0); if (vec != NULL) { ret = get_errno(safe_readv(arg1, vec, arg3)); @@ -10555,7 +10707,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } break; case TARGET_NR_writev: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1); if (vec != NULL) { ret = get_errno(safe_writev(arg1, vec, arg3)); @@ -10567,7 +10721,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; #if defined(TARGET_NR_preadv) case TARGET_NR_preadv: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0); if (vec != NULL) { unsigned long low, high; @@ -10583,7 +10739,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #if defined(TARGET_NR_pwritev) case TARGET_NR_pwritev: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1); if (vec != NULL) { unsigned long low, high; @@ -10602,6 +10760,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */ case TARGET_NR_fdatasync: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = get_errno(fdatasync(arg1)); break; #endif @@ -10866,6 +11027,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_pread64 case TARGET_NR_pread64: + if (is_hostfd(arg1)) { + goto ebadf; + } if (regpairs_aligned(cpu_env, num)) { arg4 = arg5; arg5 = arg6; @@ -10876,6 +11040,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, unlock_user(p, arg2, ret); break; case TARGET_NR_pwrite64: + if (is_hostfd(arg1)) { + goto ebadf; + } if (regpairs_aligned(cpu_env, num)) { arg4 = arg5; arg5 = arg6; @@ -10971,6 +11138,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, { off_t *offp = NULL; off_t off; + + if (is_hostfd(arg1) || is_hostfd(arg2)) { + goto ebadf; + } if (arg3) { ret = get_user_sal(off, arg3); if (is_error(ret)) { @@ -10992,6 +11163,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, { off_t *offp = NULL; off_t off; + + if (is_hostfd(arg1) || is_hostfd(arg2)) { + goto ebadf; + } if (arg3) { ret = get_user_s64(off, arg3); if (is_error(ret)) { @@ -11059,6 +11234,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_ftruncate64 case TARGET_NR_ftruncate64: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4); break; #endif @@ -11084,6 +11262,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_fstat64 case TARGET_NR_fstat64: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = get_errno(fstat(arg1, &st)); if (!is_error(ret)) ret = host_to_target_stat64(cpu_env, arg2, &st); @@ -11096,6 +11277,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #ifdef TARGET_NR_newfstatat case TARGET_NR_newfstatat: #endif + if (is_hostfd(arg1)) { + goto ebadf; + } if (!(p = lock_user_string(arg2))) goto efault; ret = get_errno(fstatat(arg1, path(p), &st, arg4)); @@ -11184,6 +11368,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; #if defined(TARGET_NR_fchownat) case TARGET_NR_fchownat: + if (is_hostfd(arg1)) { + goto ebadf; + } if (!(p = lock_user_string(arg2))) goto efault; ret = get_errno(fchownat(arg1, p, low2highuid(arg3), @@ -11525,6 +11712,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_fchown32 case TARGET_NR_fchown32: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = get_errno(fchown(arg1, arg2, arg3)); break; #endif @@ -11626,6 +11816,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, * Note that offset and len are both 64-bit so appear as * pairs of 32-bit registers. */ + if (is_hostfd(arg1)) { + goto ebadf; + } ret = posix_fadvise(arg1, target_offset64(arg3, arg4), target_offset64(arg5, arg6), arg2); ret = -host_to_target_errno(ret); @@ -11636,6 +11829,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #ifdef TARGET_NR_fadvise64_64 case TARGET_NR_fadvise64_64: + if (is_hostfd(arg1)) { + goto ebadf; + } #if defined(TARGET_PPC) || defined(TARGET_XTENSA) /* 6 args: fd, advice, offset (high, low), len (high, low) */ ret = arg2; @@ -11664,6 +11860,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #ifdef TARGET_NR_fadvise64 case TARGET_NR_fadvise64: + if (is_hostfd(arg1)) { + goto ebadf; + } /* 5 args: fd, offset (high, low), len, advice */ if (regpairs_aligned(cpu_env, num)) { /* offset is in (3,4), len in 5 and advice in 6 */ @@ -11686,6 +11885,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #ifdef TARGET_NR_fadvise64 case TARGET_NR_fadvise64: #endif + if (is_hostfd(arg1)) { + goto ebadf; + } #ifdef TARGET_S390X switch (arg4) { case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */ @@ -11711,6 +11913,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #if TARGET_ABI_BITS == 32 case TARGET_NR_fcntl64: + if (is_hostfd(arg1)) { + goto ebadf; + } { int cmd; struct flock64 fl; @@ -11858,7 +12063,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } break; case TARGET_NR_fsetxattr: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { void *n, *v = 0; if (arg3) { v = lock_user(VERIFY_READ, arg3, arg4, 1); @@ -11905,7 +12112,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } break; case TARGET_NR_fgetxattr: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { void *n, *v = 0; if (arg3) { v = lock_user(VERIFY_WRITE, arg3, arg4, 0); @@ -11944,7 +12153,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } break; case TARGET_NR_fremovexattr: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { void *n; n = lock_user_string(arg2); if (n) { @@ -12095,7 +12306,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #if defined(TARGET_NR_utimensat) case TARGET_NR_utimensat: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { struct timespec *tsp, ts[2]; if (!arg3) { tsp = NULL; @@ -12141,6 +12354,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch) case TARGET_NR_inotify_add_watch: + if (is_hostfd(arg1)) { + goto ebadf; + } p = lock_user_string(arg2); ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3)); unlock_user(p, arg2, 0); @@ -12148,6 +12364,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch) case TARGET_NR_inotify_rm_watch: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = get_errno(sys_inotify_rm_watch(arg1, arg2)); break; #endif @@ -12248,14 +12467,18 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #ifdef CONFIG_SPLICE #ifdef TARGET_NR_tee case TARGET_NR_tee: - { + if (is_hostfd(arg1) || is_hostfd(arg2)) { + goto ebadf; + } else { ret = get_errno(tee(arg1,arg2,arg3,arg4)); } break; #endif #ifdef TARGET_NR_splice case TARGET_NR_splice: - { + if (is_hostfd(arg1) || is_hostfd(arg3)) { + goto ebadf; + } else { loff_t loff_in, loff_out; loff_t *ploff_in = NULL, *ploff_out = NULL; if (arg2) { @@ -12285,8 +12508,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; #endif #ifdef TARGET_NR_vmsplice - case TARGET_NR_vmsplice: - { + case TARGET_NR_vmsplice: + if (is_hostfd(arg1)) { + goto ebadf; + } else { struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1); if (vec != NULL) { ret = get_errno(vmsplice(arg1, vec, arg3, arg4)); @@ -12327,6 +12552,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif /* CONFIG_EVENTFD */ #if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate) case TARGET_NR_fallocate: + if (is_hostfd(arg1)) { + goto ebadf; + } #if TARGET_ABI_BITS == 32 ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4), target_offset64(arg5, arg6))); @@ -12338,6 +12566,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #if defined(CONFIG_SYNC_FILE_RANGE) #if defined(TARGET_NR_sync_file_range) case TARGET_NR_sync_file_range: + if (is_hostfd(arg1)) { + goto ebadf; + } #if TARGET_ABI_BITS == 32 #if defined(TARGET_MIPS) ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4), @@ -12354,6 +12585,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #if defined(TARGET_NR_sync_file_range2) case TARGET_NR_sync_file_range2: /* This is like sync_file_range but the arguments are reordered */ + if (is_hostfd(arg1)) { + goto ebadf; + } #if TARGET_ABI_BITS == 32 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4), target_offset64(arg5, arg6), arg2)); @@ -12365,11 +12599,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #if defined(TARGET_NR_signalfd4) case TARGET_NR_signalfd4: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_signalfd4(arg1, arg2, arg4); break; #endif #if defined(TARGET_NR_signalfd) case TARGET_NR_signalfd: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = do_signalfd4(arg1, arg2, 0); break; #endif @@ -12389,6 +12629,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, { struct epoll_event ep; struct epoll_event *epp = 0; + + if (is_hostfd(arg1) || is_hostfd(arg3)) { + goto ebadf; + } if (arg4) { struct target_epoll_event *target_ep; if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) { @@ -12422,6 +12666,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, int maxevents = arg3; int timeout = arg4; + if (is_hostfd(arg1)) { + goto ebadf; + } if (maxevents <= 0 || maxevents > TARGET_EP_MAX_EVENTS) { ret = -TARGET_EINVAL; break; @@ -12698,7 +12945,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #if defined(TARGET_NR_timerfd_gettime) && defined(CONFIG_TIMERFD) case TARGET_NR_timerfd_gettime: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { struct itimerspec its_curr; ret = get_errno(timerfd_gettime(arg1, &its_curr)); @@ -12712,7 +12961,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #if defined(TARGET_NR_timerfd_settime) && defined(CONFIG_TIMERFD) case TARGET_NR_timerfd_settime: - { + if (is_hostfd(arg1)) { + goto ebadf; + } else { struct itimerspec its_new, its_old, *p_new; if (arg3) { @@ -12747,6 +12998,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #if defined(TARGET_NR_setns) && defined(CONFIG_SETNS) case TARGET_NR_setns: + if (is_hostfd(arg1)) { + goto ebadf; + } ret = get_errno(setns(arg1, arg2)); break; #endif @@ -12781,4 +13035,7 @@ fail: efault: ret = -TARGET_EFAULT; goto fail; +ebadf: + ret = -TARGET_EBADF; + goto fail; } From patchwork Thu May 31 22:49:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 137448 Delivered-To: patch@linaro.org Received: by 2002:a2e:9706:0:0:0:0:0 with SMTP id r6-v6csp211025lji; Thu, 31 May 2018 15:54:33 -0700 (PDT) X-Google-Smtp-Source: ADUXVKI6fUUu5jYaA7DWvA9Xh1/FUpHRoKWLvgfaklivIxRRj2fUP0o4q5u0M/E8e4lb3AtnTNGY X-Received: by 2002:a0c:a3c3:: with SMTP id v61-v6mr2930529qvv.99.1527807273725; Thu, 31 May 2018 15:54:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527807273; cv=none; d=google.com; s=arc-20160816; b=x/aaJJXhuA8XIqcGQ759pT751yE0N3Shr0yDwIHrur69upJ7IvIyp0Zpn/VDqLdO2x BTReu7ni1CcrJMG25Y4RMsPCqeteUBX8mBwGA5U4K1TYf0cS8zzHwNRCggp8jK6mUhPr I1VFKTJtuX4lUTzzuctHpiFIZhxyaM21wrqhAmzpm+57AxtHZRvU9fCZ3cR4RWqxd3ne M8lQ2jljKi7nuzyTUT/IFyJ0CLE9G/RqytamiYk2imrWMiBiIQbewvrcd5LFqMJYg1SC Ad151i7KKfFf07/wEOndcJj1Bzhlk012V7E4UvvyPgRlFXRxnXROm8YrRGr9ZbvgS0pF qHyw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=vgByVcF4sTG4UIGoDfjdQmMRjmxXVfAO4cyzhWgy1pQ=; b=MKRhnOb3zWePxEeg5ydxZOWt89ebOUiB/4JI+TmhL8H8z/a6j1IdIjhaGru7/7sjur cpYK2Xkllv5ZnQGNIm/6GNFRLyRJraMhP5l8WZzZGQuqdGUQa/rWMbdD7QgOm0GPMmmN lRLJ/ARhNwsvsI+FJVRw6zt/8XiaOC7J72lqybYw1SbWsDFufShtNtcZmnPFCRo3SG2Z WxvZsvBZhZ32ZonwJq/piRdg+RIXhpWe5vLgp2cTOZpaJlBMpGRkMSvW5N5qgSUEMpcv O56NpmG1M6J+J4y4xybHjYJDaqtJpKCCvtWSgsZBUmkBr5HeC9oUe8TJ8/ZW0Btn1sg0 bj4w== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=jXBJAyoQ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id h18-v6si2914063qvc.186.2018.05.31.15.54.33 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 31 May 2018 15:54:33 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=jXBJAyoQ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:46524 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fOWSm-0001Hm-VI for patch@linaro.org; Thu, 31 May 2018 18:54:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38529) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fOWNn-0005AX-7a for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fOWNm-0000pQ-I9 for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:23 -0400 Received: from mail-pl0-x230.google.com ([2607:f8b0:400e:c01::230]:47027) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fOWNm-0000p0-CQ for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:22 -0400 Received: by mail-pl0-x230.google.com with SMTP id 30-v6so14074562pld.13 for ; Thu, 31 May 2018 15:49:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=vgByVcF4sTG4UIGoDfjdQmMRjmxXVfAO4cyzhWgy1pQ=; b=jXBJAyoQ5oIb2p6Nf95rL+iLe45Ui5dtDFJzssYth2sQVfoQ16lFJK2OYXEiKO4pyT c4b/U6jOD3xenRbibE15kfrhTmzP1i/irQjmuPN0EuDxW5kYydWGnpOLgN4n0jnDlpUm 4rZFwhllXSMWxyhPkHcY7UBReii4c5Y879IA4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=vgByVcF4sTG4UIGoDfjdQmMRjmxXVfAO4cyzhWgy1pQ=; b=eNVhdPkhQpJxlZu+li3Le76tDLMYIMGbPBkxYXYonIw+heyJCRNG9MPYnr8hILD/TS 3kIO2EQkNJ4o44PXzkKMNYHHZ1n2slKSiMKcwbjixPnBpodtLHBL+K88OJMoSHziYWg5 RtsAxaM1UxrqF4wCy046oruYIsz5XUqTGXUc3jqCjryjx8waK34Phz8OAxD7vCqajBna 97YUvOMJdwv518j55zCOjwnkvwbXXdCKi92q75jGWEA1YAKBkU2qzrvaT4T19xHPGMaA 7HI80Vrd7Ih18Y0rAjnSqFqBTpqTMGcnsFtuRaA0Az28uTz6iGCQfKqbhYbz7NIdadR6 vuvA== X-Gm-Message-State: ALKqPwfAif36pSMH98phD+alvRGheoeHlpt8NG6Ueb0tlsZHcCb6BRR3 1NRkMmEFpKKGExQaOCTgJ568dZlXKoQ= X-Received: by 2002:a17:902:7e42:: with SMTP id a2-v6mr8654068pln.151.1527806959735; Thu, 31 May 2018 15:49:19 -0700 (PDT) Received: from cloudburst.twiddle.net (97-126-112-211.tukw.qwest.net. [97.126.112.211]) by smtp.gmail.com with ESMTPSA id t3-v6sm33385584pgs.91.2018.05.31.15.49.18 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 31 May 2018 15:49:18 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 31 May 2018 15:49:09 -0700 Message-Id: <20180531224911.23725-5-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180531224911.23725-1-richard.henderson@linaro.org> References: <20180531224911.23725-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c01::230 Subject: [Qemu-devel] [PATCH 4/6] linux-user: Check contains_hostfd in select syscalls X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, laurent@vivier.eu, evgreen@chromium.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall.c | 10 ++++++++++ 1 file changed, 10 insertions(+) -- 2.17.0 Reviewed-by: Laurent Vivier diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 5339f0bc1c..b98125829b 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1506,6 +1506,11 @@ static abi_long do_select(int n, if (ret) { return ret; } + if (contains_hostfd(&rfds) || + contains_hostfd(&wfds) || + contains_hostfd(&efds)) { + return -TARGET_EBADF; + } if (target_tv_addr) { if (copy_from_user_timeval(&tv, target_tv_addr)) @@ -9392,6 +9397,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, if (ret) { goto fail; } + if (contains_hostfd(&rfds) || + contains_hostfd(&wfds) || + contains_hostfd(&efds)) { + goto ebadf; + } /* * This takes a timespec, and not a timeval, so we cannot From patchwork Thu May 31 22:49:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 137445 Delivered-To: patch@linaro.org Received: by 2002:a2e:9706:0:0:0:0:0 with SMTP id r6-v6csp207900lji; Thu, 31 May 2018 15:49:50 -0700 (PDT) X-Google-Smtp-Source: ADUXVKJ/ZdCh4FmVdTdRiQlyVjsJNCeFxmpPN2K/8NuZa6wNRU38PM+PO6ptEBFnVq5Z8d8Qzm2O X-Received: by 2002:a37:7742:: with SMTP id s63-v6mr7796012qkc.97.1527806990465; Thu, 31 May 2018 15:49:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527806990; cv=none; d=google.com; s=arc-20160816; b=tEMChNh+UbYKZ0E8smkeZb1siI8reIdAws5yutfSXrGJOaJtDTEN9mR0wkFmDd5hPt ZFzST/dlb82kJ7LbZNI0ld/oOuHN4rBRDtyXu3TiWKJecOA7YOlEZPB+TONEbvNQ+sj1 NardmIYNHlJKgUSY4ijVF+4SKneOjkJ4RCgHruBi2h9MefMbXGI1Ncts07WtQsuH+LKz XUnB3+3EGpkeGagQnoRYVpfJYq5ohL3g5O4GYOUC4ZxRL1rTDNFUlbmh44t7HcLxSuIL 966uDkeIZpOQ+lv6tTHIFZKj35lyPInKeG47iw0jPMc7T6c6p8q8/QxXsTWz68bY0XMg u1yQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=Q1iNbE7b2UYUJKQIqBMPbPcIDxffIQfiNgT2DyF9Ne0=; b=RrMhZSMBSCDf0e484ca9cx1AL8FE0JWQh92jXQsOakG3BtTS4Hlhymg7xPs4qEq3fC fMw3Qx0j8VJzXMooRp3r8LRr7Wq6AKgmmJco0SaPie8ARAMmCjaC379y17jy9kBfEtl6 0/5EcTjSo2Dtn4JE1lsQVh1Bh6EN6c1WSYUTUi8SSv0JbwgMA71cis+B7N7YIeCGp9wK bTghvob6yTNyxFnghNMxoXLJsjLd3gi3bNk/3ubUZq/7uXjgjBxT0J780Xu8S+fcOvS6 4OMXcWSwLTlZdPrAxgl1AeQkKYSdnr5kCdBGeY7nH2xB8JqyMKiZeHem5D7ORqplNa27 D9/g== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=ILKiSk7K; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id d64-v6si5964272qkf.220.2018.05.31.15.49.50 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 31 May 2018 15:49:50 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=ILKiSk7K; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:46496 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fOWOD-0005F5-TN for patch@linaro.org; Thu, 31 May 2018 18:49:49 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38531) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fOWNn-0005Aj-Ev for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fOWNm-0000pe-MG for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:23 -0400 Received: from mail-pf0-x231.google.com ([2607:f8b0:400e:c00::231]:36718) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fOWNm-0000p5-Gv for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:22 -0400 Received: by mail-pf0-x231.google.com with SMTP id w129-v6so11499025pfd.3 for ; Thu, 31 May 2018 15:49:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Q1iNbE7b2UYUJKQIqBMPbPcIDxffIQfiNgT2DyF9Ne0=; b=ILKiSk7K5205eB5+ztRNKyiGmk3yhvOqgSnhlUOQQUzcEqe9PzD1Mx2ssOdYfbyYJT Zfkr8O3B3QChado6oJ7aYVsD7MKY2pPv2fBeZjEBYZc24RG7PYg7pXZrpOufuEQ380Pn 7keXPQ3Xr54Vga4E5rvj30X9Irnr5vz3qhN4s= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Q1iNbE7b2UYUJKQIqBMPbPcIDxffIQfiNgT2DyF9Ne0=; b=aWUPwQ8SSiq8RDcNQXfpSkc9IKdR3ckXswckr4svBKl6FWTF9Ykcs92zHfCAhyQZM+ lX5kHEItvn+MptCwYXToXe4aO2ZQiDE5Y57NCe3InHQhhow5QdgkXCJXX82e1/qJ/LZ7 yJ15MAu2i1KFzUYNJCsfictoqimpEahBh4Z8zmvJAlxPH78kP1sFHN3FwESMShGZ7k98 +qZShCe8mcVNPmllPRxZ8iaQKIrP2ft0y1hE93VluvpPfgi6rPtFRnMN7B7KiCkU4YcG aU8uXuFvd5+1BtuBFV2Rh3wlWrdmzt5Tso1lkJe2DuSQ35n4yLZHCk4nWl4G+msyX747 /ZZA== X-Gm-Message-State: ALKqPweLFAvlhOPQnbSI/d5MevdGHil4RaaG/PKpBUUszX82d3wTdO6P QLQzmoMhprhUq9IcFE6sMMqPWRirU3I= X-Received: by 2002:a62:6c87:: with SMTP id h129-v6mr8371181pfc.179.1527806961171; Thu, 31 May 2018 15:49:21 -0700 (PDT) Received: from cloudburst.twiddle.net (97-126-112-211.tukw.qwest.net. [97.126.112.211]) by smtp.gmail.com with ESMTPSA id t3-v6sm33385584pgs.91.2018.05.31.15.49.19 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 31 May 2018 15:49:20 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 31 May 2018 15:49:10 -0700 Message-Id: <20180531224911.23725-6-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180531224911.23725-1-richard.henderson@linaro.org> References: <20180531224911.23725-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::231 Subject: [Qemu-devel] [PATCH 5/6] linux-user: Check is_hostfd in mmap syscalls X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, laurent@vivier.eu, evgreen@chromium.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall.c | 9 +++++++++ 1 file changed, 9 insertions(+) -- 2.17.0 Reviewed-by: Laurent Vivier diff --git a/linux-user/syscall.c b/linux-user/syscall.c index b98125829b..d7513d5dac 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -9605,11 +9605,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, v5 = tswapal(v[4]); v6 = tswapal(v[5]); unlock_user(v, arg1, 0); + if (is_hostfd(v5)) { + goto ebadf; + } ret = get_errno(target_mmap(v1, v2, v3, target_to_host_bitmask(v4, mmap_flags_tbl), v5, v6)); } #else + if (is_hostfd(arg5)) { + goto ebadf; + } ret = get_errno(target_mmap(arg1, arg2, arg3, target_to_host_bitmask(arg4, mmap_flags_tbl), arg5, @@ -9622,6 +9628,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #ifndef MMAP_SHIFT #define MMAP_SHIFT 12 #endif + if (is_hostfd(arg5)) { + goto ebadf; + } ret = get_errno(target_mmap(arg1, arg2, arg3, target_to_host_bitmask(arg4, mmap_flags_tbl), arg5, From patchwork Thu May 31 22:49:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 137449 Delivered-To: patch@linaro.org Received: by 2002:a2e:9706:0:0:0:0:0 with SMTP id r6-v6csp211053lji; Thu, 31 May 2018 15:54:37 -0700 (PDT) X-Google-Smtp-Source: ADUXVKKO6mYenSF5l87JPvuKlhDuw8FRZpXm69rskR+c1s8YvbxCtEATv/6fKP0oxg2ZLdyKUc9l X-Received: by 2002:a37:a4c2:: with SMTP id n185-v6mr7874802qke.230.1527807277087; Thu, 31 May 2018 15:54:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527807277; cv=none; d=google.com; s=arc-20160816; b=nPCOzmMUWfTgVJlCZnfJ3NnM3bKVRYvMvxy+7fJomuy9QaCsciSaXEWSBNIp0A90Rh j1DbhgJSyNCbyLVotUayT+hgt6JBKfTtqDb6gMTvBO1xX8DtLZAe8M/MZPzI3iZdHXVw 0NxQl3fufv0OWIU9OHfgINcYDKRMbJ75NbPBimtZY2Wg5KmS2nYqjNKcOy6F3bqWk9od 1bfqh3EzSVO7rlN2X4JozIMgxZQ4z1N/zw8pK71RNLbm285ltAXSGVgIuzMdVDqoMr4/ +lw/b4Apqd/Ql+dFxMWsdwv5AzYvCaEGg9jfxBs4NldIaoB0zoCf1UNy/P2rLNyB0Mrw IPig== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=7OSmq4hqL21PytEiWwZ62wkBZ8Vmh8b24upJeUdJdBg=; b=ecvZ1dIIj2sg0SezMk7FYwSo34jad2vSGLD0r78DdjnJuRX64vUk8GUcWeuBws867d DsN3435FbGqUfx31HF3wQjLoItJmpPt33dfK9G+dME1d7IRPKEeilfX30q9+tA05MCOA +L16R7dys1gcuFjCpPMZMIe0UoV7E7HnefHvRVGFGXZeCv91ZVN1WBymfMvZjyeNLUTJ MajW4JFZGGnpc1e1SJuDstIiLfdMnvZvg+jHWRRlZqHKTaC5BEouGrju3P5zqf0UnWnE Uf/mD8vqdTZ/nmRp9zYGf9RiSVfoMMBVTNd5tQ3U55WbAGRUWODVN8aUW/sF1LDI6Bol 0XSw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=kFcSyzrF; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id i64-v6si1907893qkf.377.2018.05.31.15.54.36 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 31 May 2018 15:54:37 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=kFcSyzrF; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:46525 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fOWSq-0001KY-Eu for patch@linaro.org; Thu, 31 May 2018 18:54:36 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38559) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fOWNr-0005Gw-Uj for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fOWNo-0000rO-LU for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:27 -0400 Received: from mail-pg0-x244.google.com ([2607:f8b0:400e:c05::244]:44340) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fOWNo-0000qf-B4 for qemu-devel@nongnu.org; Thu, 31 May 2018 18:49:24 -0400 Received: by mail-pg0-x244.google.com with SMTP id p21-v6so10350839pgd.11 for ; Thu, 31 May 2018 15:49:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7OSmq4hqL21PytEiWwZ62wkBZ8Vmh8b24upJeUdJdBg=; b=kFcSyzrF7C6LBF7LlbRzF78myjrbbahwkKM1+4VP1v24M+W2Fw6iOmEY5nsO/amv8m fIza4QHYBU1qKFX5tEOZmQj3auBXOtuH5aF68PRZhBOkrxfPvrAWBRhJ6IfynOEu80Fz xMT5d5+fWJoKFHetzVdNGV/y1n4d2a2v5xBSE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7OSmq4hqL21PytEiWwZ62wkBZ8Vmh8b24upJeUdJdBg=; b=Uy5ye6xpYPyKvoScUtMblN/d00wFL9YiEIgZMNRVAs8ldIalSqUAAc4mBA4HHfxPj8 HtrVUunksnvVoWYm+1/sU/FzEcgRh+0QyRQ7Bb+Z4A3wCsLTfrH7HP64BFYB+RHt3Tlz r6vmqcJlwW8AvT1If/3MOcazG3YHsTQ5XmZqDvNz5RZlymamUPE6GNMtenTf9J/KI/Eb ZiNaihZ56L4f/Rvdq64AX7wdgDgIog7PXHZfBfDXky31366tUypb8EO8qBfQvsP7V2KZ k3c9JYDXtnz7JYc4368BzWSa1TU1i8cYUI3ymQymqqQqFHy9/xCizuxo/rhIFLT+7RGN /qTw== X-Gm-Message-State: ALKqPwevhDMV6NvBn7EUrE+DH8G/DpGXpUBrMulhjajIcBcWlmH4Bzkp 2O0SMmd7E5sBpcE8fbaMlyTa7uUgJsg= X-Received: by 2002:a65:4b49:: with SMTP id k9-v6mr6772862pgt.369.1527806962785; Thu, 31 May 2018 15:49:22 -0700 (PDT) Received: from cloudburst.twiddle.net (97-126-112-211.tukw.qwest.net. [97.126.112.211]) by smtp.gmail.com with ESMTPSA id t3-v6sm33385584pgs.91.2018.05.31.15.49.21 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 31 May 2018 15:49:21 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 31 May 2018 15:49:11 -0700 Message-Id: <20180531224911.23725-7-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180531224911.23725-1-richard.henderson@linaro.org> References: <20180531224911.23725-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c05::244 Subject: [Qemu-devel] [PATCH 6/6] linux-user: Use *at functions to implement interp_prefix X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, laurent@vivier.eu, evgreen@chromium.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" If the interp_prefix is a complete chroot, it may have a *lot* of files. Setting up the cache for this is quite expensive. For the most part, we can use the *at versions of various syscalls to attempt the operation in the prefix. For the few cases that remain, attempt the operation in the prefix via concatenation and then retry if that fails. Signed-off-by: Richard Henderson --- linux-user/qemu.h | 37 ++++++++++ linux-user/elfload.c | 5 +- linux-user/main.c | 26 ++++++- linux-user/syscall.c | 163 +++++++++++++++++++++++++++++-------------- 4 files changed, 174 insertions(+), 57 deletions(-) -- 2.17.0 diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 33dafbe0e4..05a82a3628 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -471,7 +471,44 @@ void mmap_fork_start(void); void mmap_fork_end(int child); /* main.c */ +extern int interp_dirfd; extern unsigned long guest_stack_size; +char *interp_prefix_path(const char *path); + +/* If PATH is absolute, attempt an operation first within interp_dirfd, + * using OPENAT_EXPR. If that fails with ENOENT, or if PATH is not + * absolute, only use NORMAL_EXPR. + */ +#define TRY_INTERP_FD(RET, PATH, OPENAT_EXPR, NORMAL_EXPR) \ + do { \ + if (interp_dirfd >= 0 && (PATH)[0] == '/') { \ + RET = OPENAT_EXPR; \ + if (RET != -1 || errno != ENOENT) { \ + break; \ + } \ + } \ + RET = NORMAL_EXPR; \ + } while (0) + +/* If PATH is absolute, attempt an operation first with interp_prefix + * prefixed. If that fails with ENOENT, or if PATH is not absolute, + * only attempt with PATH. + */ +#define TRY_INTERP_PATH(RET, PATH, EXPR) \ + do { \ + char *new_##PATH = interp_prefix_path(PATH); \ + if (new_##PATH) { \ + __typeof(PATH) save_##PATH = PATH; \ + PATH = new_##PATH; \ + RET = EXPR; \ + free(new_##PATH); \ + PATH = save_##PATH; \ + if (RET != -1 || errno != ENOENT) { \ + break; \ + } \ + } \ + RET = EXPR; \ + } while (0) /* user access */ diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 13bc78d0c8..abdf5bbf01 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -6,7 +6,6 @@ #include "qemu.h" #include "disas/disas.h" -#include "qemu/path.h" #ifdef _ARCH_PPC64 #undef ARCH_DLINFO @@ -2375,7 +2374,9 @@ static void load_elf_interp(const char *filename, struct image_info *info, { int fd, retval; - fd = open(path(filename), O_RDONLY); + TRY_INTERP_FD(fd, filename, + openat(interp_dirfd, filename + 1, O_RDONLY), + open(filename, O_RDONLY)); if (fd < 0) { goto exit_perror; } diff --git a/linux-user/main.c b/linux-user/main.c index ee3f323c08..4e956fc00c 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -23,7 +23,6 @@ #include "qapi/error.h" #include "qemu.h" -#include "qemu/path.h" #include "qemu/config-file.h" #include "qemu/cutils.h" #include "qemu/help_option.h" @@ -89,9 +88,27 @@ unsigned long reserved_va; static void usage(int exitcode); +int interp_dirfd; static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX; const char *qemu_uname_release; +char *interp_prefix_path(const char *path) +{ + size_t i_len, p_len; + char *ret; + + if (interp_prefix == NULL || path[0] != '/') { + return NULL; + } + i_len = strlen(interp_prefix); + p_len = strlen(path) + 1; + ret = g_malloc(i_len + p_len); + + memcpy(ret, interp_prefix, i_len); + memcpy(ret + i_len, path, p_len); + return ret; +} + /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so we allocate a bigger stack. Need a better solution, for example by remapping the process stack directly at the right place */ @@ -671,7 +688,12 @@ int main(int argc, char **argv, char **envp) memset(&bprm, 0, sizeof (bprm)); /* Scan interp_prefix dir for replacement files. */ - init_paths(interp_prefix); + interp_dirfd = open(interp_prefix, O_CLOEXEC | O_DIRECTORY | O_PATH); + if (interp_dirfd >= 0) { + add_hostfd(interp_dirfd); + } else { + interp_prefix = NULL; + } init_qemu_uname_release(); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index d7513d5dac..b75dd9a5bc 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -19,7 +19,6 @@ #define _ATFILE_SOURCE #include "qemu/osdep.h" #include "qemu/cutils.h" -#include "qemu/path.h" #include #include #include @@ -7401,7 +7400,10 @@ static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname, fh = g_malloc0(total_size); fh->handle_bytes = size; - ret = get_errno(name_to_handle_at(dirfd, path(name), fh, &mid, flags)); + TRY_INTERP_FD(ret, name, + name_to_handle_at(interp_dirfd, name + 1, fh, &mid, flags), + name_to_handle_at(dirfd, name, fh, &mid, flags)); + ret = get_errno(ret); unlock_user(name, pathname, 0); /* man name_to_handle_at(2): @@ -7777,6 +7779,7 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags, #endif { NULL, NULL, NULL } }; + int ret; if (is_proc_myself(pathname, "exe")) { int execfd = qemu_getauxval(AT_EXECFD); @@ -7816,7 +7819,10 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags, return fd; } - return safe_openat(dirfd, path(pathname), flags, mode); + TRY_INTERP_FD(ret, pathname, + safe_openat(interp_dirfd, pathname + 1, flags, mode), + safe_openat(dirfd, pathname, flags, mode)); + return ret; } #define TIMER_MAGIC 0x0caf0000 @@ -7969,6 +7975,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, struct stat st; struct statfs stfs; void *p; + char *fn; #if defined(DEBUG_ERESTARTSYS) /* Debug-only code for exercising the syscall-restart code paths @@ -8531,10 +8538,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } else { tvp = NULL; } - if (!(p = lock_user_string(arg2))) + if (!(fn = lock_user_string(arg2))) { goto efault; - ret = get_errno(futimesat(arg1, path(p), tvp)); - unlock_user(p, arg2, 0); + } + TRY_INTERP_FD(ret, fn, + futimesat(interp_dirfd, fn + 1, tvp), + futimesat(arg1, fn, tvp)); + ret = get_errno(ret); + unlock_user(fn, arg2, 0); } break; #endif @@ -8548,10 +8559,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_access case TARGET_NR_access: - if (!(p = lock_user_string(arg1))) + if (!(fn = lock_user_string(arg1))) { goto efault; - ret = get_errno(access(path(p), arg2)); - unlock_user(p, arg1, 0); + } + TRY_INTERP_FD(ret, fn, + faccessat(interp_dirfd, fn + 1, arg2, 0), + access(fn, arg2)); + ret = get_errno(ret); + unlock_user(fn, arg1, 0); break; #endif #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat) @@ -8559,10 +8574,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, if (is_hostfd(arg1)) { goto ebadf; } - if (!(p = lock_user_string(arg2))) + if (!(fn = lock_user_string(arg2))) { goto efault; - ret = get_errno(faccessat(arg1, p, arg3, 0)); - unlock_user(p, arg2, 0); + } + TRY_INTERP_FD(ret, fn, + faccessat(interp_dirfd, fn + 1, arg3, 0), + faccessat(arg1, fn, arg3, 0)); + ret = get_errno(ret); + unlock_user(fn, arg2, 0); break; #endif #ifdef TARGET_NR_nice /* not on alpha */ @@ -8713,10 +8732,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, if (arg1 == 0) { ret = get_errno(acct(NULL)); } else { - if (!(p = lock_user_string(arg1))) + if (!(fn = lock_user_string(arg1))) { goto efault; - ret = get_errno(acct(path(p))); - unlock_user(p, arg1, 0); + } + TRY_INTERP_PATH(ret, fn, acct(fn)); + ret = get_errno(ret); + unlock_user(fn, arg1, 0); } break; #ifdef TARGET_NR_umount2 @@ -9507,14 +9528,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_readlink: { void *p2; - p = lock_user_string(arg1); + fn = lock_user_string(arg1); p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0); - if (!p || !p2) { + if (!fn || !p2) { ret = -TARGET_EFAULT; } else if (!arg3) { /* Short circuit this for the magic exe check. */ ret = -TARGET_EINVAL; - } else if (is_proc_myself((const char *)p, "exe")) { + } else if (is_proc_myself(fn, "exe")) { char real[PATH_MAX], *temp; temp = realpath(exec_path, real); /* Return value is # of bytes that we wrote to the buffer. */ @@ -9528,10 +9549,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, memcpy(p2, real, ret); } } else { - ret = get_errno(readlink(path(p), p2, arg3)); + TRY_INTERP_FD(ret, fn, + readlinkat(interp_dirfd, fn + 1, p2, arg3), + readlink(fn, p2, arg3)); + ret = get_errno(ret); } unlock_user(p2, arg2, ret); - unlock_user(p, arg1, 0); + unlock_user(fn, arg1, 0); } break; #endif @@ -9541,20 +9565,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, goto ebadf; } else { void *p2; - p = lock_user_string(arg2); + fn = lock_user_string(arg2); p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0); - if (!p || !p2) { + if (!fn || !p2) { ret = -TARGET_EFAULT; - } else if (is_proc_myself((const char *)p, "exe")) { + } else if (is_proc_myself(fn, "exe")) { char real[PATH_MAX], *temp; temp = realpath(exec_path, real); ret = temp == NULL ? get_errno(-1) : strlen(real) ; snprintf((char *)p2, arg4, "%s", real); } else { - ret = get_errno(readlinkat(arg1, path(p), p2, arg4)); + TRY_INTERP_FD(ret, fn, + readlinkat(interp_dirfd, fn + 1, p2, arg4), + readlinkat(arg1, fn, p2, arg4)); + ret = get_errno(ret); } unlock_user(p2, arg3, ret); - unlock_user(p, arg2, 0); + unlock_user(fn, arg2, 0); } break; #endif @@ -9739,10 +9766,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, goto unimplemented; #endif case TARGET_NR_statfs: - if (!(p = lock_user_string(arg1))) + if (!(fn = lock_user_string(arg1))) { goto efault; - ret = get_errno(statfs(path(p), &stfs)); - unlock_user(p, arg1, 0); + } + TRY_INTERP_PATH(ret, fn, statfs(fn, &stfs)); + ret = get_errno(ret); + unlock_user(fn, arg1, 0); convert_statfs: if (!is_error(ret)) { struct target_statfs *target_stfs; @@ -9777,10 +9806,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, goto convert_statfs; #ifdef TARGET_NR_statfs64 case TARGET_NR_statfs64: - if (!(p = lock_user_string(arg1))) + if (!(fn = lock_user_string(arg1))) { goto efault; - ret = get_errno(statfs(path(p), &stfs)); - unlock_user(p, arg1, 0); + } + TRY_INTERP_PATH(ret, fn, statfs(fn, &stfs)); + ret = get_errno(ret); + unlock_user(fn, arg1, 0); convert_statfs64: if (!is_error(ret)) { struct target_statfs64 *target_stfs; @@ -10065,18 +10096,26 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; #ifdef TARGET_NR_stat case TARGET_NR_stat: - if (!(p = lock_user_string(arg1))) + if (!(fn = lock_user_string(arg1))) { goto efault; - ret = get_errno(stat(path(p), &st)); - unlock_user(p, arg1, 0); + } + TRY_INTERP_FD(ret, fn, + fstatat(interp_dirfd, fn + 1, &st, 0), + stat(fn, &st)); + ret = get_errno(ret); + unlock_user(fn, arg1, 0); goto do_stat; #endif #ifdef TARGET_NR_lstat case TARGET_NR_lstat: - if (!(p = lock_user_string(arg1))) + if (!(fn = lock_user_string(arg1))) { goto efault; - ret = get_errno(lstat(path(p), &st)); - unlock_user(p, arg1, 0); + } + TRY_INTERP_FD(ret, fn, + fstatat(interp_dirfd, fn + 1, &st, AT_SYMLINK_NOFOLLOW), + lstat(fn, &st)); + ret = get_errno(ret); + unlock_user(fn, arg1, 0); goto do_stat; #endif case TARGET_NR_fstat: @@ -11261,20 +11300,28 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_stat64 case TARGET_NR_stat64: - if (!(p = lock_user_string(arg1))) + if (!(fn = lock_user_string(arg1))) { goto efault; - ret = get_errno(stat(path(p), &st)); - unlock_user(p, arg1, 0); + } + TRY_INTERP_FD(ret, fn, + fstatat(interp_dirfd, fn + 1, &st, 0), + stat(fn, &st)); + ret = get_errno(ret); + unlock_user(fn, arg1, 0); if (!is_error(ret)) ret = host_to_target_stat64(cpu_env, arg2, &st); break; #endif #ifdef TARGET_NR_lstat64 case TARGET_NR_lstat64: - if (!(p = lock_user_string(arg1))) + if (!(fn = lock_user_string(arg1))) { goto efault; - ret = get_errno(lstat(path(p), &st)); - unlock_user(p, arg1, 0); + } + TRY_INTERP_FD(ret, fn, + fstatat(interp_dirfd, fn + 1, &st, AT_SYMLINK_NOFOLLOW), + lstat(fn, &st)); + ret = get_errno(ret); + unlock_user(fn, arg1, 0); if (!is_error(ret)) ret = host_to_target_stat64(cpu_env, arg2, &st); break; @@ -11299,9 +11346,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, if (is_hostfd(arg1)) { goto ebadf; } - if (!(p = lock_user_string(arg2))) + if (!(fn = lock_user_string(arg2))) { goto efault; - ret = get_errno(fstatat(arg1, path(p), &st, arg4)); + } + TRY_INTERP_FD(ret, fn, + fstatat(interp_dirfd, fn + 1, &st, arg4), + fstatat(arg1, fn, &st, arg4)); + ret = get_errno(ret); + unlock_user(fn, arg2, 0); if (!is_error(ret)) ret = host_to_target_stat64(cpu_env, arg3, &st); break; @@ -12339,12 +12391,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, if (!arg2) ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4)); else { - if (!(p = lock_user_string(arg2))) { - ret = -TARGET_EFAULT; - goto fail; + if (!(fn = lock_user_string(arg2))) { + goto efault; } - ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4)); - unlock_user(p, arg2, 0); + TRY_INTERP_FD(ret, fn, + sys_utimensat(interp_dirfd, fn + 1, tsp, arg4), + sys_utimensat(arg1, fn, tsp, arg4)); + ret = get_errno(ret); + unlock_user(fn, arg2, 0); } } break; @@ -12376,9 +12430,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, if (is_hostfd(arg1)) { goto ebadf; } - p = lock_user_string(arg2); - ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3)); - unlock_user(p, arg2, 0); + if (!(fn = lock_user_string(arg2))) { + goto efault; + } + TRY_INTERP_PATH(ret, fn, sys_inotify_add_watch(arg1, fn, arg3)); + ret = get_errno(ret); + unlock_user(fn, arg2, 0); break; #endif #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)