From nobody Sun Feb 8 20:28:23 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1527817324618177.8376016058172; Thu, 31 May 2018 18:42:04 -0700 (PDT) Received: from localhost ([::1]:46972 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fOZ4t-0005BF-PR for importer@patchew.org; Thu, 31 May 2018 21:42:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33481) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fOYrF-0003FI-Vd for qemu-devel@nongnu.org; Thu, 31 May 2018 21:27:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fOYrE-0003KZ-Es for qemu-devel@nongnu.org; Thu, 31 May 2018 21:27:57 -0400 Received: from mail-qt0-x22e.google.com ([2607:f8b0:400d:c0d::22e]:34666) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fOYrE-0003KB-9L for qemu-devel@nongnu.org; Thu, 31 May 2018 21:27:56 -0400 Received: by mail-qt0-x22e.google.com with SMTP id m5-v6so30317914qti.1 for ; Thu, 31 May 2018 18:27:56 -0700 (PDT) Received: from localhost.localdomain (96-86-104-61-static.hfc.comcastbusiness.net. [96.86.104.61]) by smtp.gmail.com with ESMTPSA id o68-v6sm2003842qkc.19.2018.05.31.18.27.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 31 May 2018 18:27:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=juliacomputing-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=i7MhZc+tIIRKA4U6ikcPVCRG0VkhFryqrjxztGNwlsI=; b=N+unzIdJcDdHRnkmrXU6iAhIirN2co+5AZ8FLR4c4jWPc6ZoKgeTD5vCHQaoXLBURV cQRV0eMQFoa+6hAZfnY91DsdBi2nTKog4BkbE43W4e1jSApTkbgm1ZJXC1HH5aq1+ksk FcByvbZ1giOvW5DgpmKiYxc0rz6ckcTqooq5u8+5mlwSH9E1ELonhIlkcf9g242Xpit9 NB5cYKWI/9P4fBsy0fWh4QaQWuQrVUD5Pdy4W9f15Gsd/Un7it+Nr+JhDGKJhukV6n3n FrbYVcNtLybtUOxKbktsArt9ZN0jC1DahWx4rrCTzmL9EexoItummqLumxZmdEMKr8UI KrAQ== 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:in-reply-to:references; bh=i7MhZc+tIIRKA4U6ikcPVCRG0VkhFryqrjxztGNwlsI=; b=Uqh/M8c7LHqni7lbimzH4PfVQdE24dmFIfaFxyIuob4vDOmdVubDMX1/Ub2Ci1ZcMI sN78+y79++MOGnsjNg2oi6FZwfg6rpDlKcPJBtuYJUYugHSTXNChHQt02aPeKTguGRi0 ASPv3WxGfaZage3qRtJSAKPp0XHp/n41VQ8Poyp0xqOp55x4WRQhOcr2AxltfJjtUHEN ff2uZbsXdlDSpRmWIC9YFIvzhEyZMzA9NvQy2v3F9W78nbU9bmM9ycrX+tCaNXrZIu0q y5AIYfE4Oq0eTAkqaQx8FDVP9/oK5kLRJiiBkLT73BYhpClw11Gdo7fgcRo7RzqAZAso 5E0g== X-Gm-Message-State: APt69E2qjjogoRq/1wjj9ZXlqcwCrJETg253ARK7sfWU5clD0Jr3pukG 2QoywAIK5BODxw9csijS6oBz7Xs341Y= X-Google-Smtp-Source: ADUXVKLw27frXqaQ7Y/eyX+pC7q3Ghl2oMiH4lDGp9qL0m9fXmFlTbOnlnvOJkF5ZSBpv4UJ8MMH5g== X-Received: by 2002:a0c:e8cf:: with SMTP id m15-v6mr1004541qvo.52.1527816475314; Thu, 31 May 2018 18:27:55 -0700 (PDT) From: Keno Fischer To: qemu-devel@nongnu.org Date: Thu, 31 May 2018 21:26:14 -0400 Message-Id: X-Mailer: git-send-email 2.8.1 In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400d:c0d::22e Subject: [Qemu-devel] [PATCH v2 19/20] 9p: darwin: virtfs-proxy: Implement setuid code for darwin 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: Keno Fischer , groug@kaod.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Darwin does not have linux capabilities, so make that code linux-only. Darwin also does not have setresuid/gid. The correct way to temporarily drop capabilities is to call seteuid/gid. Also factor out the code that acquires acquire_dac_override into a separate function in the linux implementation. I had originally done this when I thought it made sense to have only one `setugid` function, but I retained this because it seems clearer this way. Signed-off-by: Keno Fischer --- Changes from v1: New patch. fsdev/virtfs-proxy-helper.c | 200 +++++++++++++++++++++++++++-------------= ---- 1 file changed, 125 insertions(+), 75 deletions(-) diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c index d8dd3f5..6baf2a6 100644 --- a/fsdev/virtfs-proxy-helper.c +++ b/fsdev/virtfs-proxy-helper.c @@ -82,6 +82,7 @@ static void do_perror(const char *string) } } =20 +#ifdef CONFIG_LINUX static int do_cap_set(cap_value_t *cap_value, int size, int reset) { cap_t caps; @@ -121,6 +122,85 @@ error: return -1; } =20 +static int acquire_dac_override(void) +{ + cap_value_t cap_list[] =3D { + CAP_DAC_OVERRIDE, + }; + return do_cap_set(cap_list, ARRAY_SIZE(cap_list), 0); +} + +/* + * from man 7 capabilities, section + * Effect of User ID Changes on Capabilities: + * If the effective user ID is changed from nonzero to 0, then the permitt= ed + * set is copied to the effective set. If the effective user ID is changed + * from 0 to nonzero, then all capabilities are are cleared from the effec= tive + * set. + * + * The setfsuid/setfsgid man pages warn that changing the effective user I= D may + * expose the program to unwanted signals, but this is not true anymore: f= or an + * unprivileged (without CAP_KILL) program to send a signal, the real or + * effective user ID of the sending process must equal the real or saved u= ser + * ID of the target process. Even when dropping privileges, it is enough = to + * keep the saved UID to a "privileged" value and virtfs-proxy-helper won't + * be exposed to signals. So just use setresuid/setresgid. + */ +static int setugid(int uid, int gid, int *suid, int *sgid) +{ + int retval; + + *suid =3D geteuid(); + *sgid =3D getegid(); + + if (setresgid(-1, gid, *sgid) =3D=3D -1) { + retval =3D -errno; + goto err_out; + } + + if (setresuid(-1, uid, *suid) =3D=3D -1) { + retval =3D -errno; + goto err_sgid; + } + + if (uid !=3D 0 || gid !=3D 0) { + /* + * We still need DAC_OVERRIDE because we don't change + * supplementary group ids, and hence may be subjected DAC rules + */ + if (acquire_dac_override() < 0) { + retval =3D -errno; + goto err_suid; + } + } + return 0; + +err_suid: + if (setresuid(-1, *suid, *suid) =3D=3D -1) { + abort(); + } +err_sgid: + if (setresgid(-1, *sgid, *sgid) =3D=3D -1) { + abort(); + } +err_out: + return retval; +} + +/* + * This is used to reset the ugid back with the saved values + * There is nothing much we can do checking error values here. + */ +static void resetugid(int suid, int sgid) +{ + if (setresgid(-1, sgid, sgid) =3D=3D -1) { + abort(); + } + if (setresuid(-1, suid, suid) =3D=3D -1) { + abort(); + } +} + static int init_capabilities(void) { /* helper needs following capabilities only */ @@ -135,6 +215,51 @@ static int init_capabilities(void) }; return do_cap_set(cap_list, ARRAY_SIZE(cap_list), 1); } +#else +static int setugid(int uid, int gid, int *suid, int *sgid) +{ + int retval; + + *suid =3D geteuid(); + *sgid =3D getegid(); + + if (setegid(gid) =3D=3D -1) { + retval =3D -errno; + goto err_out; + } + + if (seteuid(uid) =3D=3D -1) { + retval =3D -errno; + goto err_sgid; + } + +err_sgid: + if (setgid(*sgid) =3D=3D -1) { + abort(); + } +err_out: + return retval; +} + +/* + * This is used to reset the ugid back with the saved values + * There is nothing much we can do checking error values here. + */ +static void resetugid(int suid, int sgid) +{ + if (setegid(sgid) =3D=3D -1) { + abort(); + } + if (seteuid(suid) =3D=3D -1) { + abort(); + } +} + +static int init_capabilities(void) +{ + return 0; +} +#endif =20 static int socket_read(int sockfd, void *buff, ssize_t size) { @@ -279,81 +404,6 @@ static int send_status(int sockfd, struct iovec *iovec= , int status) } =20 /* - * from man 7 capabilities, section - * Effect of User ID Changes on Capabilities: - * If the effective user ID is changed from nonzero to 0, then the permitt= ed - * set is copied to the effective set. If the effective user ID is changed - * from 0 to nonzero, then all capabilities are are cleared from the effec= tive - * set. - * - * The setfsuid/setfsgid man pages warn that changing the effective user I= D may - * expose the program to unwanted signals, but this is not true anymore: f= or an - * unprivileged (without CAP_KILL) program to send a signal, the real or - * effective user ID of the sending process must equal the real or saved u= ser - * ID of the target process. Even when dropping privileges, it is enough = to - * keep the saved UID to a "privileged" value and virtfs-proxy-helper won't - * be exposed to signals. So just use setresuid/setresgid. - */ -static int setugid(int uid, int gid, int *suid, int *sgid) -{ - int retval; - - /* - * We still need DAC_OVERRIDE because we don't change - * supplementary group ids, and hence may be subjected DAC rules - */ - cap_value_t cap_list[] =3D { - CAP_DAC_OVERRIDE, - }; - - *suid =3D geteuid(); - *sgid =3D getegid(); - - if (setresgid(-1, gid, *sgid) =3D=3D -1) { - retval =3D -errno; - goto err_out; - } - - if (setresuid(-1, uid, *suid) =3D=3D -1) { - retval =3D -errno; - goto err_sgid; - } - - if (uid !=3D 0 || gid !=3D 0) { - if (do_cap_set(cap_list, ARRAY_SIZE(cap_list), 0) < 0) { - retval =3D -errno; - goto err_suid; - } - } - return 0; - -err_suid: - if (setresuid(-1, *suid, *suid) =3D=3D -1) { - abort(); - } -err_sgid: - if (setresgid(-1, *sgid, *sgid) =3D=3D -1) { - abort(); - } -err_out: - return retval; -} - -/* - * This is used to reset the ugid back with the saved values - * There is nothing much we can do checking error values here. - */ -static void resetugid(int suid, int sgid) -{ - if (setresgid(-1, sgid, sgid) =3D=3D -1) { - abort(); - } - if (setresuid(-1, suid, suid) =3D=3D -1) { - abort(); - } -} - -/* * send response in two parts * 1) ProxyHeader * 2) Response or error status --=20 2.8.1