Received: by 2002:a25:868d:0:0:0:0:0 with SMTP id z13csp3816612ybk; Tue, 19 May 2020 13:41:46 -0700 (PDT) X-Google-Smtp-Source: ABdhPJztIhoaTTBatMHFsfuHdcpN+F2MZz6+5a6/elzvylGXkCiteIH5+uuAQQHGXcENCVxtzqlS X-Received: by 2002:a17:906:dbd6:: with SMTP id yc22mr921374ejb.345.1589920906482; Tue, 19 May 2020 13:41:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1589920906; cv=none; d=google.com; s=arc-20160816; b=dj1rDMTsZeODCeN0s9bjPnoxzbdR6WPXkcQtJC35LBZRc2Qsyt3LjNw2BMaX/BAOg7 Mscm1l9mti3yzYejI9paUxqsJ0oW+yWNOiivI6JUmYciVmKBSOlX9tGDiHKm/j0zb4Iy zGp9kvOYgYxvQsvFjx+6ahigjcvpVYnX9ifsb++DvCMGeRkiKiHgbmJxp2G+MnkVh1oZ H2ioaZ+U5hzRMXK0GdyQecMEjyU0B8Ay53MlBf5ha014N8oFKlMhehW9JXaFiM+20GBu 0CkcmyhWqplU+xkkG1wm4vP3lsahsdQOV9Zwhct5/OFaTuR18WUj1QbNrvAnGyKN2fq5 iLMg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :dkim-signature; bh=1ajSll4bK53Qb2Ak/L8hDSxkSGAnkpDcgNlbRYtpvdY=; b=bZLxYXgNLxf+mZcYD9z52IabozbDKZqEqeuq9E/BPuGKSHaJGU7iTq3sbLR0bJLKK7 iQORoRgPKpCp4Wg1oxpjmWViB9vnq+uakniQpvwdjlfFgBt+8M7Yd7rCSTMNQxsOK21X 2/O8Qs/98ssSHM4ffG86yo+cXEHMKNlJdaKnr1hnT4SGNAf4Lg1icl56rkQx+8+Vxdwh 55usVbb156rOGAVaiYzdSSUHWaulKLzLXoynpCT6AxNRqFRjdaDVanfwCxh7tWtFD+LO uQS/n4Q6cl9MfgDRFSO2kWgGOxcsTQxmD8j03s5Ytbste+jsOXCVR0DN03zjfIr+VW6z lqLA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=bdpue+Oj; 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=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id f19si510242eje.519.2020.05.19.13.41.22; Tue, 19 May 2020 13:41:46 -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=@chromium.org header.s=google header.b=bdpue+Oj; 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=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726925AbgESUiB (ORCPT + 99 others); Tue, 19 May 2020 16:38:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58244 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726030AbgESUiA (ORCPT ); Tue, 19 May 2020 16:38:00 -0400 Received: from mail-pg1-x544.google.com (mail-pg1-x544.google.com [IPv6:2607:f8b0:4864:20::544]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A135BC08C5C1 for ; Tue, 19 May 2020 13:38:00 -0700 (PDT) Received: by mail-pg1-x544.google.com with SMTP id c75so375728pga.3 for ; Tue, 19 May 2020 13:38:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=1ajSll4bK53Qb2Ak/L8hDSxkSGAnkpDcgNlbRYtpvdY=; b=bdpue+Ojf13IRe6EAqF+S2fM9FW1U9KJIwBTq1d4UtGhfpgkzxqbNMwL2t9gD/HgLg dzeF1gIHEz8PErdvGj7aC4MbQMcPkV3d3d2qYtkVu2Wif68mY8/Wm6UD9TIbyOM18bXQ GIF7TGksPetl0XqMWhyuq9wcVAqbqi+bOu8+A= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=1ajSll4bK53Qb2Ak/L8hDSxkSGAnkpDcgNlbRYtpvdY=; b=tOFlU3e3D/G9scEPSK6UZLQAB7++TjDKAVbPl6GgCPA+XqDf3817MBjqPN21pOgIEz w/gacTp4/qs3iKUw2T1ssHqN0SwI1B3v1f0Vi1eSfhQLMAnnadMfhXf/FMYfyM84CY82 XMKg84xLTY2HDunR0w0DV3Ikct2IL5ffZOQKDmRalnMyC/i57KYeqOyWEmPFScU0jY+A SvokbCJ9rnv16IHEOpXavHrU/wG8HSWQlnfQbBpXKEeI6Lh/MzbAYtYVKweGdChWG3Zn Nistnb7G1DT4xuKNX9snky6sLRGQkTSvcY2LwOebp1COznTtJwSZptinIN/Wpdi7RL2d dmUA== X-Gm-Message-State: AOAM533pJ4v3DXjlh7vpgbVhquXJNqz//9rOo0WkqovVVKGNEbgV6gyn vIXA210pBmfPfWOVv2Lo300esw== X-Received: by 2002:aa7:91da:: with SMTP id z26mr954615pfa.18.1589920680112; Tue, 19 May 2020 13:38:00 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id i184sm278051pgc.36.2020.05.19.13.37.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 May 2020 13:37:59 -0700 (PDT) Date: Tue, 19 May 2020 13:37:57 -0700 From: Kees Cook To: "Eric W. Biederman" Cc: linux-kernel@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Jann Horn , Greg Ungerer , Rob Landley , Bernd Edlinger , linux-fsdevel@vger.kernel.org, Al Viro , Alexey Dobriyan , Andrew Morton , Casey Schaufler , linux-security-module@vger.kernel.org, James Morris , "Serge E. Hallyn" , Andy Lutomirski Subject: Re: [PATCH v2 8/8] exec: Remove recursion from search_binary_handler Message-ID: <202005191320.230EFDFCB@keescook> References: <87h7wujhmz.fsf@x220.int.ebiederm.org> <87sgga6ze4.fsf@x220.int.ebiederm.org> <87v9l4zyla.fsf_-_@x220.int.ebiederm.org> <877dx822er.fsf_-_@x220.int.ebiederm.org> <87sgfwyd84.fsf_-_@x220.int.ebiederm.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <87sgfwyd84.fsf_-_@x220.int.ebiederm.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, May 18, 2020 at 07:34:19PM -0500, Eric W. Biederman wrote: > > Recursion in kernel code is generally a bad idea as it can overflow > the kernel stack. Recursion in exec also hides that the code is > looping and that the loop changes bprm->file. > > Instead of recursing in search_binary_handler have the methods that > would recurse set bprm->interpreter and return 0. Modify exec_binprm > to loop when bprm->interpreter is set. Consolidate all of the > reassignments of bprm->file in that loop to make it clear what is > going on. > > The structure of the new loop in exec_binprm is that all errors return > immediately, while successful completion (ret == 0 && > !bprm->interpreter) just breaks out of the loop and runs what > exec_bprm has always run upon successful completion. > > Fail if the an interpreter is being call after execfd has been set. > The code has never properly handled an interpreter being called with > execfd being set and with reassignments of bprm->file and the > assignment of bprm->executable in generic code it has finally become > possible to test and fail when if this problematic condition happens. > > With the reassignments of bprm->file and the assignment of > bprm->executable moved into the generic code add a test to see if > bprm->executable is being reassigned. > > In search_binary_handler remove the test for !bprm->file. With all > reassignments of bprm->file moved to exec_binprm bprm->file can never > be NULL in search_binary_handler. > > Signed-off-by: "Eric W. Biederman" Lovely! Reviewed-by: Kees Cook I spent some time following the file lifetimes of deny/allow_write_access() and the fget/fput() paths. It all looks correct to me; it's tricky (especially bprm->executable) but so very much cleaner than before. :) The only suggestion I could come up with is more comments (surprise) to help anyone new to this loop realize what the "common" path is (and similarly, a compiler hint too): diff --git a/fs/exec.c b/fs/exec.c index a9f421ec9e27..738051a698e1 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1790,15 +1790,19 @@ static int exec_binprm(struct linux_binprm *bprm) /* This allows 4 levels of binfmt rewrites before failing hard. */ for (depth = 0;; depth++) { struct file *exec; + if (depth > 5) return -ELOOP; ret = search_binary_handler(bprm); + /* Unrecoverable error, give up. */ if (ret < 0) return ret; - if (!bprm->interpreter) + /* Found final handler, start execution. */ + if (likely(!bprm->interpreter)) break; + /* Found an interpreter, so try again and attempt to run it. */ exec = bprm->file; bprm->file = bprm->interpreter; bprm->interpreter = NULL; -- Kees Cook