From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752469Ab2INUGF (ORCPT ); Fri, 14 Sep 2012 16:06:05 -0400 Received: from mx1.redhat.com ([209.132.183.28]:7335 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750734Ab2INUGC (ORCPT ); Fri, 14 Sep 2012 16:06:02 -0400 Date: Fri, 14 Sep 2012 16:05:57 -0400 From: Aristeu Rozanski To: Sasha Levin Cc: tj@kernel.org, dan.carpenter@oracle.com, fengguang.wu@intel.com, linux-kernel@vger.kernel.org Subject: Re: [PATCH 1/2] Revert "xattr: mark variable as uninitialized to make both gcc and smatch happy" Message-ID: <20120914200557.GP19694@redhat.com> References: <1347651354-16289-1-git-send-email-levinsasha928@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1347651354-16289-1-git-send-email-levinsasha928@gmail.com> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Sasha, On Fri, Sep 14, 2012 at 09:35:53PM +0200, Sasha Levin wrote: > This reverts commit 0142145ddb1d6c841be4eae2c7a32dd18ad34b24. > > Short version: > > Not initializing 'new_xattr' at the beginning of __simple_xattr_set() may lead to > dereferencing it later on in the function. > > > Long version: > > The fix for the warnings generated by smatch due to 'new_xattr' being dereferenced > without a check from being non-NULL is incorrect. > > The problem is that the fix removed initialization of new_xattr with NULL, which > meant that new_xattr could be anything at the beginning of __simple_xattr_set(), > and might have not been initialized at any point throughout the function. > > In case new_xattr does get left uninitialized ('value == 0' case) and XATTR_REPLACE > being set, the fix will actually lead us to dereferencing new_xattr even if we wouldn't > have done so before. > > Why? Looking at the original code: > > if (flags & XATTR_REPLACE) { > xattr = new_xattr; > err = -ENODATA; > } else if (new_xattr) { > list_add(&new_xattr->list, &xattrs->head); > xattr = NULL; > } > out: > spin_unlock(&xattrs->lock); > if (xattr) { > kfree(xattr->name); > kfree(xattr); > } > return err; not to mention this: list_for_each_entry(xattr, &xattrs->head, list) { if (!strcmp(name, xattr->name)) { if (flags & XATTR_CREATE) { xattr = new_xattr; err = -EEXIST; } else if (new_xattr) { list_replace(&xattr->list, &new_xattr->list); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ } else { list_del(&xattr->list); } goto out; } } Good catch. -- Aristeu