Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp4466031pxf; Tue, 16 Mar 2021 14:22:58 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyOvXotRC93F3sed/M1tKmMXHNdink+Aim0DHjQIZmTYjAyXqBQTsBtjLoXo7eOadu3mnX6 X-Received: by 2002:a05:6402:3049:: with SMTP id bu9mr39159418edb.104.1615929777903; Tue, 16 Mar 2021 14:22:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1615929777; cv=none; d=google.com; s=arc-20160816; b=Jc62h6GRJqIryVvVTcmVm3BMb1auD7FgfcvNPLEbbawTZhtaeyyk9wmt2eq09CZl6m 16rhoyqt/7M8Mye7kQU7wdzeZl0WLvIWS7v/UCVIA7FYS2xMV/ss6GJ4bsRa8KEzB61N t55g7BXNKEEQpcYQ5dbjlo55mvx3IOuLuw8ybNY1UbtU7ktPBKLMe/aMRPnjccbZBK5r Hw28o05ZnUTQS3cxi+YfVyZhbRsxVqft9Rlmo4ponU9r+ZVVbHZuNNmI3GYgEnN6SlSw ZBzFAxuyx4RNMNvM3C+gcJ6CHoyEsk0ONRCOkcL57ddpwilI9ag5vrQXukUWeApcq4KZ u1Lw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=785OaxI1+asEokVAhJYel0XTVJCjRIlanfaE3sEk6NA=; b=ebiiVR7q6Pqojb4rXD1L4XZnynPA5fZV9MX2fi9eR0SaLLAyJrTInFrustFgpy9fOC 5AUEo6ozc2h0CyLFDPBMn03bHJvqS3V/bf2E5BRXI8hD1M9rMlVyEEzhcvXYxoJsZqMA YsaMXV1GLAjLw4TxRByuuI4U972/iZcgzLIm3U4bj8wlnzZjANP7hhYWDKU9PFJIhbUk nfNsY/SE8gKxAFdRAvWZxd6JwBO9nyGkD0QVd1we5VW46G1vpVZJUXd/xo1CdPkb8eI4 xmO/ttnmZAaKG4u+76R+OJjcsGChkZY4Kr5HvoBR4RpLfX/8r4r8UP9D4anT+nB7UhXc uIFw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=YML5LJOi; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id dn18si13620909ejc.590.2021.03.16.14.22.35; Tue, 16 Mar 2021 14:22:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=YML5LJOi; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237633AbhCPTdA (ORCPT + 99 others); Tue, 16 Mar 2021 15:33:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32980 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240544AbhCPTcZ (ORCPT ); Tue, 16 Mar 2021 15:32:25 -0400 Received: from mail-lj1-x234.google.com (mail-lj1-x234.google.com [IPv6:2a00:1450:4864:20::234]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6D0F1C06175F for ; Tue, 16 Mar 2021 12:32:24 -0700 (PDT) Received: by mail-lj1-x234.google.com with SMTP id f16so250322ljm.1 for ; Tue, 16 Mar 2021 12:32:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=785OaxI1+asEokVAhJYel0XTVJCjRIlanfaE3sEk6NA=; b=YML5LJOi/F1KCfVmVt+vteVo9RZ0Nf4OfZSU78l6Yo7zVYJNXY4kDB0R9sp6dSuVGv wwG+M9YEHq6hIKnJ+OZf0V/jL0U0+6oEp4dvZISrHGz0VD85aaegQQ0e51E5TkIXwh1w wOrmoK69CB+I15nBsASOeEHTZZcqf43NuyBmzXchlmia61al84mOrYBSPlOPaTyxnGPU PrWfKqddx443z87DJmQ6SIaI0f8dtpRF1nV2c2L7ioUSzmmgzBnNaK4grKubI3YUfxo6 qHPjVxbHT1hlE5vAeBqUYJ8nh9hVw1NoR2g9WafVuEz/7KbpyRhGrI4M53SGQGFJW59E xiRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=785OaxI1+asEokVAhJYel0XTVJCjRIlanfaE3sEk6NA=; b=qiHmq0W9rnbrVSrVjQXo+8fyp7/q0LFGsaSWkpwpbuhb1DkPGA0mcWe3KynF9sDhxR xtc/qym6t7rBdG7vXS3k3/HrypsnFSGADua+MhcyjqmIfXqUoHdu4zrB6jp7rQcC3JIu ZF0F886e/4MiWsogQwTB//1UrtDU//uAWEIxj8AC7v9PnPql8QX5sNZjYLYVUdUWJo1W Nj+y51JGIXC3xaRU/2BuG9kaY+bXdq90Ihup+O8jLxW/v9KoWwIOMPtWFi38EzbboEtw 4DfeDfhrQSuk/+K0cRrLKNRhG/AOHSDxCP9smAp3WjGSIIcTJn28n5E4V8vwnplCCx4o +ZXA== X-Gm-Message-State: AOAM530VXcaF+ZI1uFM9sHiYnXj/EFLlBCiIwPGlxdU6w3PA4p4zGRX0 RyJNR2hy9bHYbzgdFV6zR4RdSRiSi2EEp1YHCgc4wg== X-Received: by 2002:a2e:b6d4:: with SMTP id m20mr157623ljo.448.1615923142605; Tue, 16 Mar 2021 12:32:22 -0700 (PDT) MIME-Version: 1.0 References: <20210316170135.226381-1-mic@digikod.net> <20210316170135.226381-2-mic@digikod.net> In-Reply-To: From: Jann Horn Date: Tue, 16 Mar 2021 20:31:56 +0100 Message-ID: Subject: Re: [PATCH v4 1/1] fs: Allow no_new_privs tasks to call chroot(2) To: =?UTF-8?B?TWlja2HDq2wgU2FsYcO8bg==?= Cc: Al Viro , James Morris , Serge Hallyn , Andy Lutomirski , Casey Schaufler , Christian Brauner , Christoph Hellwig , David Howells , Dominik Brodowski , "Eric W . Biederman" , John Johansen , Kees Cook , Kentaro Takeda , Tetsuo Handa , Kernel Hardening , linux-fsdevel , kernel list , linux-security-module , =?UTF-8?B?TWlja2HDq2wgU2FsYcO8bg==?= Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Mar 16, 2021 at 8:26 PM Micka=C3=ABl Sala=C3=BCn = wrote: > On 16/03/2021 20:04, Jann Horn wrote: > > On Tue, Mar 16, 2021 at 6:02 PM Micka=C3=ABl Sala=C3=BCn wrote: > >> One could argue that chroot(2) is useless without a properly populated > >> root hierarchy (i.e. without /dev and /proc). However, there are > >> multiple use cases that don't require the chrooting process to create > >> file hierarchies with special files nor mount points, e.g.: > >> * A process sandboxing itself, once all its libraries are loaded, may > >> not need files other than regular files, or even no file at all. > >> * Some pre-populated root hierarchies could be used to chroot into, > >> provided for instance by development environments or tailored > >> distributions. > >> * Processes executed in a chroot may not require access to these speci= al > >> files (e.g. with minimal runtimes, or by emulating some special file= s > >> with a LD_PRELOADed library or seccomp). > >> > >> Unprivileged chroot is especially interesting for userspace developers > >> wishing to harden their applications. For instance, chroot(2) and Yam= a > >> enable to build a capability-based security (i.e. remove filesystem > >> ambient accesses) by calling chroot/chdir with an empty directory and > >> accessing data through dedicated file descriptors obtained with > >> openat2(2) and RESOLVE_BENEATH/RESOLVE_IN_ROOT/RESOLVE_NO_MAGICLINKS. > > > > I don't entirely understand. Are you writing this with the assumption > > that a future change will make it possible to set these RESOLVE flags > > process-wide, or something like that? > > No, this scenario is for applications willing to sandbox themselves and > only use the FDs to access legitimate data. But if you're chrooted to /proc/self/fdinfo and have an fd to some directory - let's say /home/user/Downloads - there is nothing that ensures that you only use that fd with RESOLVE_BENEATH, right? If the application is compromised, it can do something like openat(fd, "../.bashrc", O_RDWR), right? Or am I missing something? > > As long as that doesn't exist, I think that to make this safe, you'd > > have to do something like the following - let a child process set up a > > new mount namespace for you, and then chroot() into that namespace's > > root: > > > > struct shared_data { > > int root_fd; > > }; > > int helper_fn(void *args) { > > struct shared_data *shared =3D args; > > mount("none", "/tmp", "tmpfs", MS_NOSUID|MS_NODEV, ""); > > mkdir("/tmp/old_root", 0700); > > pivot_root("/tmp", "/tmp/old_root"); > > umount("/tmp/old_root", ""); > > shared->root_fd =3D open("/", O_PATH); > > } > > void setup_chroot() { > > struct shared_data shared =3D {}; > > prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); > > clone(helper_fn, my_stack, > > CLONE_VFORK|CLONE_VM|CLONE_FILES|CLONE_NEWUSER|CLONE_NEWNS|SIGCHLD, > > NULL); > > fchdir(shared.root_fd); > > chroot("."); > > } > > What about this? > chdir("/proc/self/fdinfo"); > chroot("."); > close(all unnecessary FDs); That breaks down if you can e.g. get a unix domain socket connected to a process in a different chroot, right? Isn't that a bit too fragile?