Received: by 2002:a05:6a10:c604:0:0:0:0 with SMTP id y4csp276248pxt; Fri, 6 Aug 2021 01:33:13 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxnkqEgvPD8KJ2y7hvlVpsgsDbYrnkNYOsdRP/Sv3oMVoeIhKjF2eO3Hd4Lw6+nT5oapfua X-Received: by 2002:a17:906:b855:: with SMTP id ga21mr8584297ejb.262.1628238792813; Fri, 06 Aug 2021 01:33:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1628238792; cv=none; d=google.com; s=arc-20160816; b=pQZF/n0Hceh5qy0i2GwWYh2sbdXximTFwFqdVBkEXzJZpDRNVfWT/gMi0sHdH+EVz5 HQtBGhe2WuZQEgd/kjkh5PuGHX3gWeElxvX51unDah6JK6pf+s3mfIIokKQVrgAEt4gX v3IGKF4EGA+bjf5C718c1S073eZRqXeqcSKr6MQrpozAvf8TJTNklGUb6+CidTo6QFx6 ophtzNaCnjlyxNIuPRixVUSREb11lDI2ceX3AiGg9yVqtn7CaNz/39ROh8DY0x0cQTAz Nixh6rPCpN6/LFS86173OK9c9YTmB6j0FQtdWMipjMBcpILneI0F1Vqruo2RrNUbClCL dKiQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=K/7VZdsD0kvuXLXJN0Hxz/V1UWqWN2j9QnpBmRsIinU=; b=b6E10+MvIvDtRUKdGftfaR8hG82A2aj9Fdn5QZc3ZrcAwqqKdrYGQk48r5+L8eaTh+ JjFDmSsfSoGWF7xx59/wWE9ZtkRZ4DfIn1P6EmrzGJEOnYDk/9SZLtW3qt6OsNrnp948 rZV/m8YHRmt8Pq+eFu/dOClmG0URQ5Wr7L+/gw1r+FKRMXmrRTUQCtz+ta8WOEufiS4Q T5G71xETzvpRrTNtqGNbkZOzNa0SWbAh4gf7URQO+lXL+UpyM6r8FJRWn+g+hyw/ob6p p/4JQjev2HsFGNOXq4A5gJpaHP4jcxx9rhWdZvtOh5cTZdbcWdXYYsghaF52opnN3VFh EzVw== ARC-Authentication-Results: i=1; mx.google.com; dkim=temperror (no key for signature) header.i=@szeredi.hu header.s=google header.b=j7PbhC3w; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k13si8236973ejp.411.2021.08.06.01.32.46; Fri, 06 Aug 2021 01:33:12 -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=temperror (no key for signature) header.i=@szeredi.hu header.s=google header.b=j7PbhC3w; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244213AbhHFI2N (ORCPT + 99 others); Fri, 6 Aug 2021 04:28:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58990 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244211AbhHFI2L (ORCPT ); Fri, 6 Aug 2021 04:28:11 -0400 Received: from mail-vs1-xe2d.google.com (mail-vs1-xe2d.google.com [IPv6:2607:f8b0:4864:20::e2d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5B441C0612E8 for ; Fri, 6 Aug 2021 01:22:33 -0700 (PDT) Received: by mail-vs1-xe2d.google.com with SMTP id j10so4723851vsl.10 for ; Fri, 06 Aug 2021 01:22:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=szeredi.hu; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=K/7VZdsD0kvuXLXJN0Hxz/V1UWqWN2j9QnpBmRsIinU=; b=j7PbhC3w+UIrt4Z4VMtrxMZLYbBm2D/n5snIzK50TkfmeP+1txpOo1oL1WKoe9lFpu Te4zFR/fANLwAx2rBj4K83LiuJkxppIfVTQfBj9gn2XkOXqEGrh8vkf5/YbhaznaTSa0 7g6y/q9w/GG71WiXd4VLSc00irkaVaX1p/ukQ= 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; bh=K/7VZdsD0kvuXLXJN0Hxz/V1UWqWN2j9QnpBmRsIinU=; b=MmDF3lmeJPU3l5ki1S08/xpU1mSUv71+EdOeN4jWkUs/sNc1HhFfYXz9LR00gaMLRy wYPPl2HoTUuidCsHL4u+1Oh0HC0Z3/1nb0uGU3wYcbiZWGNtNdoKenO+KkccKzVClSd2 hLeYLjzWT8N7S/nsqMFeZz9fbqB3pRpNWtOz/Z483nUpjxuOy/2Z30RKX0r1gpNNi8Xx 424Sc6VJEa65Mx4bQ/fJAWGTL7kzyX8GxkAS645QAmqxb3gLtOIUX4OKIhlgMHqB9t85 JKEGv8qr1BNC2+CyXaMxj6BGzRfKm+2xIXLdVQ9dwdfcgA9IZvhEk8l4nnCT5w+MNMw0 lKcQ== X-Gm-Message-State: AOAM531dYJGF1uYgI+vGWlDdw/SjSYKZYfvaUp43vROAKei0d6rfetUo rJyGVssdI/9UIStFT5c/W1c4izLUVFfeDPBlc6OHyg== X-Received: by 2002:a05:6102:34d9:: with SMTP id a25mr8076699vst.0.1628238152502; Fri, 06 Aug 2021 01:22:32 -0700 (PDT) MIME-Version: 1.0 References: <737687ee-3449-aa3d-ee29-bd75ca0a18a9@canonical.com> In-Reply-To: From: Miklos Szeredi Date: Fri, 6 Aug 2021 10:22:21 +0200 Message-ID: Subject: Re: ovl: uninitialized pointer read in ovl_lookup_real_one To: Amir Goldstein Cc: Colin Ian King , overlayfs , "linux-kernel@vger.kernel.org" Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sat, 24 Jul 2021 at 09:36, Amir Goldstein wrote: > > On Sat, Jul 24, 2021 at 1:26 AM Colin Ian King wrote: > > > > Hi, > > > > Static analysis with Coverity has detected an uninitialized pointer read > > in function ovl_lookup_real_one in fs/overlayfs/export.c > > > > The issue was introduced with the following commit: > > > > commit 3985b70a3e3f58109dc6ae347eafe6e8610be41e > > Author: Amir Goldstein > > Date: Thu Dec 28 18:36:16 2017 +0200 > > > > ovl: decode connected upper dir file handles > > > > The analysis is as follows: > > > > 365static struct dentry *ovl_lookup_real_one(struct dentry *connected, > > 366 struct dentry *real, > > 367 const struct ovl_layer *layer) > > 368{ > > 369 struct inode *dir = d_inode(connected); > > 370 struct dentry *this, *parent = NULL; > > > > 1. var_decl: Declaring variable name without initializer. > > > > 371 struct name_snapshot name; > > 372 int err; > > 373 > > 374 /* > > 375 * Lookup child overlay dentry by real name. The dir mutex > > protects us > > 376 * from racing with overlay rename. If the overlay dentry > > that is above > > 377 * real has already been moved to a parent that is not under the > > 378 * connected overlay dir, we return -ECHILD and restart the > > lookup of > > 379 * connected real path from the top. > > 380 */ > > 381 inode_lock_nested(dir, I_MUTEX_PARENT); > > 382 err = -ECHILD; > > 383 parent = dget_parent(real); > > > > 2. Condition ovl_dentry_real_at(connected, layer->idx) != parent, > > taking true branch. > > > > 384 if (ovl_dentry_real_at(connected, layer->idx) != parent) > > > > 3. Jumping to label fail. > > > > 385 goto fail; > > 386 > > 387 /* > > 388 * We also need to take a snapshot of real dentry name to > > protect us > > 389 * from racing with underlying layer rename. In this case, we > > don't > > 390 * care about returning ESTALE, only from dereferencing a > > free name > > 391 * pointer because we hold no lock on the real dentry. > > 392 */ > > 393 take_dentry_name_snapshot(&name, real); > > 394 this = lookup_one_len(name.name.name, connected, name.name.len); > > 395 err = PTR_ERR(this); > > 396 if (IS_ERR(this)) { > > 397 goto fail; > > 398 } else if (!this || !this->d_inode) { > > 399 dput(this); > > 400 err = -ENOENT; > > 401 goto fail; > > 402 } else if (ovl_dentry_real_at(this, layer->idx) != real) { > > 403 dput(this); > > 404 err = -ESTALE; > > 405 goto fail; > > 406 } > > 407 > > 408out: > > > > Uninitialized pointer read > > 6. uninit_use_in_call: Using uninitialized value name.name.name when > > calling release_dentry_name_snapshot. > > > > 409 release_dentry_name_snapshot(&name); > > 410 dput(parent); > > 411 inode_unlock(dir); > > 412 return this; > > 413 > > 414fail: > > > > 4. Condition ___ratelimit(&_rs, ), taking false branch > > . > > 415 pr_warn_ratelimited("failed to lookup one by real (%pd2, > > layer=%d, connected=%pd2, err=%i)\n", > > 416 real, layer->idx, connected, err); > > 417 this = ERR_PTR(err); > > > > 5. Jumping to label out. > > > > 418 goto out; > > 419} > > > > The error exit path on line 395 ends up with an uninitialized structure > > name being passed to function release_dentry_name_snapshot() on line 409 > > and this accesses the pointer name.name.name, see /fs/dcache.c as follows: > > > > 303void release_dentry_name_snapshot(struct name_snapshot *name) > > 304{ > > > > 1. read_value: Reading value name->name.name. > > 2. Condition !!(name->name.name != name->inline_name), taking true > > branch. > > > > 305 if (unlikely(name->name.name != name->inline_name)) { > > 306 struct external_name *p; > > > > 3. Condition 0 /* !!(!__builtin_types_compatible_p() && > > !__builtin_types_compatible_p()) */, taking false branch. > > > > > > I suspect name should be initialized in line 371, e.g. name = { } and a > > null name check should be performed on line 409 before calling > > release_dentry_name_snapshot, but this seems a bit message as a fix. > > > > Thanks for the report. > A simpler fix is to move take_dentry_name_snapshot() to top of the > function before goto fail. Even simpler: move the release_dentry_name_snapshot to just after lookup. Commit 89741437981a ("ovl: fix uninitialized pointer read in ovl_lookup_real_one()") pushed to #overlayfs-next. Thanks, Miklos