Received: by 2002:ac0:a581:0:0:0:0:0 with SMTP id m1-v6csp1162409imm; Fri, 22 Jun 2018 11:22:14 -0700 (PDT) X-Google-Smtp-Source: ADUXVKKhdXs/gpLRYZQ2zBku2YC3Ka9SNB4X1haMFVhCxUTyl9HtHpG++YwX3EwPXLX9lv80qa6V X-Received: by 2002:a17:902:7891:: with SMTP id q17-v6mr2827724pll.186.1529691734563; Fri, 22 Jun 2018 11:22:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529691734; cv=none; d=google.com; s=arc-20160816; b=luwYxOSmwSbnd+7yG+i/a1dBNgohYMZwpuor3rVNgWJ1dPOJmj7JaxdHZfukNlztuq TyHzAT44eyYEzOCq/8WEf1sJqW1trli3J2u/Q4ZWXHCEB2yyU4GdScgMy9OAqs3LdJcK aQT+DE+bWjQm/+yieSRiQlYsepfE383VJfheQtLbjigXlS6j0pUatLN3mSJ9VeaINvFF rhZd4tot45e2SOFuoK6rYUvv51RW2U2237mRTL8fXK+pWMO9LHDouLzCLzVCGIHbMM0x ePXvTj1e1MAbTy941YJMLq98bChkOrbVdlbGEhQ8Nn4/+GqVL0E1cfDE23QSw4u+28wN Ertw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:to:references:message-id :content-transfer-encoding:cc:date:in-reply-to:from:subject :mime-version:dkim-signature:arc-authentication-results; bh=Z5U7xO27ugme0b2zNqmiAUgMkQRPxwGUVTB+32vXUO0=; b=vnFd1tl1sqheT+PQojtcQ/x1Ev9zH7Yz4oVt/Tq6G5qtLpIP/S+iWgegdr/jyUzuh9 1dlbIxEeZ/9XSpIEma243oRBxWuroqZ6awMao1ABDEcyImHJMdzeJ2GwAkMewZ70GLBI ZK3KygoaHZjyZXBkuGWXrqXLkpNmt88sHxQO+BmZYkIe9ChBGvjpB24LdzDZ9pl0gJLW xhpu6kpJe/wFduxZ2CzcqfU6MAGcQX83ZPwFpqu9ccnlmddGTLe3pNmbXwz02htsF9Md 7NiL8aYoIgtpLNYSMG0MfM9IpnMeukeC5u54REUmqyy9nhsI9qEEQVQfKpELHHKliJHd AtRw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amacapital-net.20150623.gappssmtp.com header.s=20150623 header.b=pMEvdvVN; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 1-v6si2585500pla.509.2018.06.22.11.21.59; Fri, 22 Jun 2018 11:22:14 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@amacapital-net.20150623.gappssmtp.com header.s=20150623 header.b=pMEvdvVN; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934040AbeFVSVP (ORCPT + 99 others); Fri, 22 Jun 2018 14:21:15 -0400 Received: from mail-pf0-f194.google.com ([209.85.192.194]:39976 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933646AbeFVSVO (ORCPT ); Fri, 22 Jun 2018 14:21:14 -0400 Received: by mail-pf0-f194.google.com with SMTP id z24-v6so3583888pfe.7 for ; Fri, 22 Jun 2018 11:21:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amacapital-net.20150623.gappssmtp.com; s=20150623; h=mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=Z5U7xO27ugme0b2zNqmiAUgMkQRPxwGUVTB+32vXUO0=; b=pMEvdvVNVSF3G3R3jP7wracOjMQGvwqJx3k6Xfnhs0AxDAL1mALub2pSSSAZKl6iHJ DIcjJ+dT2TvV/2pn9CAtntXvEXP9vtPlGHj7thQfHl1FaZNhV+dd9K2ky40QLdxryUhk yEZgi9gKQTWYCiwayUdan3VokOKRdJW+s4M9/ueoaXHci1TJhFYx9GWCdJxikiTdD4wW gaWW25fCKcbX03hwrU6lGvYDlyuTDcv54VisuJw1MgV+b0viZzgCH+TZulOxP4AI7xcq TsSwpAB17Un4WkicKmY6VsCMS9K+EVkm553oLqN+CYc9cw+PcTGIEpEx2qgYfoWlCdXp jsVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=Z5U7xO27ugme0b2zNqmiAUgMkQRPxwGUVTB+32vXUO0=; b=I4Syp6WWwaKVtxmm663WbP12t9/C21fUG9PiJJrTf16cakyfkffZh6cczgqAhNNrhJ o3cFyUBVrE+izs6EsIaEEhTp3Qkwnki4Nt7nBNm5oFHGrVzLVRo3P5+CCRJ7rL+0GHZ3 ySyVS5UZxdZrcqYvsHeqXSCHF5lhFMdwfhJo/LnOvG5B/feVzeUaSGyY7eBvSCkDuEtP AsPFNP1BlJjabI7pRYv/XFlwm9SMJz4ETslIwdsbrsREIHmi1SlgDbp1JU2iun/iPYwz tdZ+PZnVuheQvkIvePxH9OwCOO1vFUVS8kz0oPemdU9PZ/OExdCOwHoIYqbNFkILiLlL MF4A== X-Gm-Message-State: APt69E1/et6uPAAnSz9crV9euPIQSLv8+q58tLlAJemOlyRhoVjp2Bz+ jJQUWk72xKRqtfrFMiN+oVr8oCQ9ATA= X-Received: by 2002:a62:c61d:: with SMTP id m29-v6mr2902605pfg.26.1529691673113; Fri, 22 Jun 2018 11:21:13 -0700 (PDT) Received: from ?IPv6:2600:1010:b065:2cd9:e530:8535:a508:f820? ([2600:1010:b065:2cd9:e530:8535:a508:f820]) by smtp.gmail.com with ESMTPSA id d6-v6sm10955156pgc.38.2018.06.22.11.21.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 22 Jun 2018 11:21:12 -0700 (PDT) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (1.0) Subject: Re: [PATCH v4 4/4] seccomp: add support for passing fds via USER_NOTIF From: Andy Lutomirski X-Mailer: iPhone Mail (15F79) In-Reply-To: Date: Fri, 22 Jun 2018 11:21:08 -0700 Cc: Tycho Andersen , Kees Cook , kernel list , containers@lists.linux-foundation.org, Linux API , Oleg Nesterov , "Eric W. Biederman" , "Serge E. Hallyn" , Christian Brauner , Tyler Hicks , suda.akihiro@lab.ntt.co.jp, "Tobin C. Harding" Content-Transfer-Encoding: quoted-printable Message-Id: <8C2AA818-2F53-4F40-842F-288B4C709414@amacapital.net> References: <20180621220416.5412-1-tycho@tycho.ws> <20180621220416.5412-5-tycho@tycho.ws> To: Jann Horn Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org > On Jun 22, 2018, at 9:23 AM, Jann Horn wrote: >=20 >> On Fri, Jun 22, 2018 at 12:05 AM Tycho Andersen wrote: >>=20 >> The idea here is that the userspace handler should be able to pass an fd >> back to the trapped task, for example so it can be returned from socket()= . >>=20 >> I've proposed one API here, but I'm open to other options. In particular,= >> this only lets you return an fd from a syscall, which may not be enough i= n >> all cases. For example, if an fd is written to an output parameter instea= d >> of returned, the current API can't handle this. Another case is that >> netlink takes as input fds sometimes (IFLA_NET_NS_FD, e.g.). If netlink >> ever decides to install an fd and output it, we wouldn't be able to handl= e >> this either. >>=20 >> Still, the vast majority of interesting cases are covered by this API, so= >> perhaps it is Enough. >>=20 >> I've left it as a separate commit for two reasons: >> * It illustrates the way in which we would grow struct seccomp_notif and= >> struct seccomp_notif_resp without using netlink >> * It shows just how little code is needed to accomplish this :) >>=20 > [...] >> @@ -1669,10 +1706,20 @@ static ssize_t seccomp_notify_write(struct file *= file, const char __user *buf, >> goto out; >> } >>=20 >> + if (resp.return_fd) { >> + knotif->flags =3D resp.fd_flags; >> + knotif->file =3D fget(resp.fd); >> + if (!knotif->file) { >> + ret =3D -EBADF; >> + goto out; >> + } >> + } >> + >=20 > I think this is a security bug. Imagine the following scenario: >=20 > - attacker creates processes A and B > - process A installs a seccomp filter and sends the notification fd > to process B > - process A starts a syscall for which the filter returns > SECCOMP_RET_USER_NOTIF > - process B reads the notification from the notification fd > - process B uses dup2() to copy the notification fd to file > descriptor 1 (stdout) > - process B executes a setuid root binary > - the setuid root binary opens some privileged file descriptor > (something like open("/etc/shadow", O_RDWR)) > - the setuid root binary tries to write some attacker-controlled data to s= tdout > - seccomp_notify_write() interprets the start of the written data as > a struct seccomp_notif_resp > - seccomp_notify_write() grabs the privileged file descriptor and > installs a copy in process A > - process A now has access to the privileged file (e.g. /etc/shadow) >=20 > It isn't clear whether it would actually be exploitable - you'd need a > setuid binary that performs the right actions - but it's still bad. Jann is right. ->read and ->write must not reference any of the calling task= =E2=80=99s state except the literal memory passed in. >=20 > Unless I'm missing something, can you please turn the ->read and > ->write handlers into an ->unlocked_ioctl handler? Something like > this: >=20 > struct seccomp_user_notif_args { > u64 buf; > u64 size; > }; >=20 > static long unlocked_ioctl(struct file *file, unsigned int cmd, > unsigned long arg) > { > struct seccomp_user_notif_args args; > struct seccomp_user_notif_args __user *uargs; >=20 > if (cmd !=3D SECCOMP_USER_NOTIF_READ && cmd !=3D SECCOMP_USER_NOTIF_= WRITE) > return -EINVAL; >=20 > if (copy_from_user(&args, uargs, sizeof(args))) > return -EFAULT; >=20 > switch (cmd) { > case SECCOMP_USER_NOTIF_READ: > return seccomp_notify_read(file, (char __user > *)args.buf, (size_t)args.size); > case SECCOMP_USER_NOTIF_WRITE: > return seccomp_notify_write(file, (char __user > *)args.buf, (size_t)args.size); > default: > return -EINVAL; > } > }