Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp6220937yba; Tue, 14 May 2019 04:01:37 -0700 (PDT) X-Google-Smtp-Source: APXvYqyKb94GXTrsbUYFDfCVd2gU0Zbya4Giw9JLm+458gaP+dOPcWcs+CngXA455ATR4r5A2MgG X-Received: by 2002:a63:58b:: with SMTP id 133mr37645833pgf.138.1557831697683; Tue, 14 May 2019 04:01:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1557831697; cv=none; d=google.com; s=arc-20160816; b=rX2Zcyo/kHiUlvmCDnHHdpojatGphE4Bm1P+csSg8kwvFNWcM633XgD95aCrh3lAdQ 3Zsf19t/JwWNQATCzJFwkp6dMb7PLeysm8YAieyrke0sETKDqUiCvzT5l7NizL9l9qF4 NQmifwUZ88+KSG7jn6lVx4u+Uo+I5Fg/jEpqOkQUuxXtyey3Md2Tuvy9Z5w++PTGnmz7 E0Lb0enrycoIn6t47piEXxIl9jd3lnm/Xo8PdPZHp4/JmepqVqG+Egm2hucEvt3owmj/ G1b32eN8muC/tTE0IGEHan/Q6F26qnBVnbDo0uzz7rKz/vBMZawuqMNIUkeHSI+DmoMJ z5YQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dmarc-filter :dkim-signature:dkim-signature; bh=GyIcsy4M4C7UjJ7EFP6jLJcmBpGpCppmjBRqxPswBuo=; b=EWcBz6K1V4NLbG8+M38zC6HhGuXLqfSvHhZjntBIRCLp3usyRPxrdmSH0HR6Gx/nMr vpV1bENHzqFF9/Bzo+xbXXu4lHXHQ9jA8rhtkGEVSsZrVzBH34t3C/6jxecqs6Pg84o6 L2d6VI7V+MxA/tGcvYyBJL+8BPs73mOzCsjXwaD0curNolyqA4Dg72HXkzjciR+LE15n FjEpKLLfB1Y+hNyoJplFIalplEUSUFXNWruZ0qGJz0n1HcETW0nxsyHEGU3Cpfv1N4pg O5gG55eYiZNDbtkLmC0phBR1sVHfXYwOnEgmBczLoB/3HQpwm3B8zv7soFxogSxPnuAO yrRw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=WN0wzIFU; dkim=pass header.i=@codeaurora.org header.s=default header.b=cQr12Gmm; 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 l21si20656685pgc.190.2019.05.14.04.01.13; Tue, 14 May 2019 04:01:37 -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=@codeaurora.org header.s=default header.b=WN0wzIFU; dkim=pass header.i=@codeaurora.org header.s=default header.b=cQr12Gmm; 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 S1726338AbfENLAF (ORCPT + 99 others); Tue, 14 May 2019 07:00:05 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:39894 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725892AbfENLAF (ORCPT ); Tue, 14 May 2019 07:00:05 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id C2305608D4; Tue, 14 May 2019 11:00:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1557831603; bh=xSkLRV2QGI8N8EyzVbCKEkYGEF5Z3gTYYuoMnN/Fx/8=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From; b=WN0wzIFUs/GOugJhJ2WWH+4B1BLt7/EuR82KpU0l5iifupcZxiPPlw4teYFs7RiEV esBndgilyoz3FTgcIaCe/khyFI6xgw0uJdpQ7Xg0zCY/9xqUcQNpnOVgYG2FCi4Ljb HAQaeok+69ZbUJkOskb7ll+uwsY4PthnU2/DLlDg= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_INVALID,DKIM_SIGNED autolearn=no autolearn_force=no version=3.4.0 Received: from [10.204.79.19] (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: prsood@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 4F388601D4; Tue, 14 May 2019 11:00:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1557831602; bh=xSkLRV2QGI8N8EyzVbCKEkYGEF5Z3gTYYuoMnN/Fx/8=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From; b=cQr12GmmGBse208Ems1ZU5Jlz2+rPQke82kPfVbGROSm09QNxE9x/F2DwCUneUySx 8P2c92Sepp3lJMeB+J9N+EeGHNpNkHxVK0A/y9Mhgd079eVYT+yBgkHIIQ7gASe8ej 1hi+Y65hgY8avea0YUg1rRv7SseTQji8kYNHT4sk= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 4F388601D4 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=prsood@codeaurora.org Subject: Re: [PATCH] driver core: Fix use-after-free and double free on glue directory To: Mukesh Ojha , Muchun Song , gregkh@linuxfoundation.org, rafael@kernel.org Cc: Benjamin Herrenschmidt , linux-kernel References: <20190423143258.96706-1-smuchun@gmail.com> <24b0fff3775147c04b006282727d94fea7f408b4.camel@kernel.crashing.org> <79fbc203bc9fa09d88ab2c4bff8635be4c293d49.camel@kernel.crashing.org> From: Prateek Sood Message-ID: Date: Tue, 14 May 2019 16:29:58 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 5/14/19 4:26 PM, Mukesh Ojha wrote: > ++ > > On 5/4/2019 8:17 PM, Muchun Song wrote: >> Benjamin Herrenschmidt 于2019年5月2日周四 下午2:25写道: >> >>>>> The basic idea yes, the whole bool *locked is horrid though. >>>>> Wouldn't it >>>>> work to have a get_device_parent_locked that always returns with >>>>> the mutex held, >>>>> or just move the mutex to the caller or something simpler like this >>>>> ? >>>>> >>>> Greg and Rafael, do you have any suggestions for this? Or you also >>>> agree with Ben? >>> Ping guys ? This is worth fixing... >> I also agree with you. But Greg and Rafael seem to be high latency right now. >> >>  From your suggestions, I think introduce get_device_parent_locked() may easy >> to fix. So, do you agree with the fix of the following code snippet >> (You can also >> view attachments)? >> >> I introduce a new function named get_device_parent_locked_if_glue_dir() which >> always returns with the mutex held only when we live in glue dir. We should call >> unlock_if_glue_dir() to release the mutex. The >> get_device_parent_locked_if_glue_dir() >> and unlock_if_glue_dir() should be called in pairs. >> >> --- >> drivers/base/core.c | 44 ++++++++++++++++++++++++++++++++++++-------- >> 1 file changed, 36 insertions(+), 8 deletions(-) >> >> diff --git a/drivers/base/core.c b/drivers/base/core.c >> index 4aeaa0c92bda..5112755c43fa 100644 >> --- a/drivers/base/core.c >> +++ b/drivers/base/core.c >> @@ -1739,8 +1739,9 @@ class_dir_create_and_add(struct class *class, >> struct kobject *parent_kobj) >> static DEFINE_MUTEX(gdp_mutex); >> -static struct kobject *get_device_parent(struct device *dev, >> -                    struct device *parent) >> +static struct kobject *__get_device_parent(struct device *dev, >> +                    struct device *parent, >> +                    bool lock) >> { >>     if (dev->class) { >>         struct kobject *kobj = NULL; >> @@ -1779,14 +1780,16 @@ static struct kobject >> *get_device_parent(struct device *dev, >>             } >>         spin_unlock(&dev->class->p->glue_dirs.list_lock); >>         if (kobj) { >> -           mutex_unlock(&gdp_mutex); >> +           if (!lock) >> +               mutex_unlock(&gdp_mutex); >>             return kobj; >>         } >>         /* or create a new class-directory at the parent device */ >>         k = class_dir_create_and_add(dev->class, parent_kobj); >>         /* do not emit an uevent for this simple "glue" directory */ >> -       mutex_unlock(&gdp_mutex); >> +       if (!lock) >> +           mutex_unlock(&gdp_mutex); >>         return k; >>     } >> @@ -1799,6 +1802,19 @@ static struct kobject *get_device_parent(struct >> device *dev, >>     return NULL; >> } >> +static inline struct kobject *get_device_parent(struct device *dev, >> +                       struct device *parent) >> +{ >> +   return __get_device_parent(dev, parent, false); >> +} >> + >> +static inline struct kobject * >> +get_device_parent_locked_if_glue_dir(struct device *dev, >> +                struct device *parent) >> +{ >> +   return __get_device_parent(dev, parent, true); >> +} >> + >> static inline bool live_in_glue_dir(struct kobject *kobj, >>                  struct device *dev) >> { >> @@ -1831,6 +1847,16 @@ static void cleanup_glue_dir(struct device >> *dev, struct kobject *glue_dir) >>     mutex_unlock(&gdp_mutex); >> } >> +static inline void unlock_if_glue_dir(struct device *dev, >> +                struct kobject *glue_dir) >> +{ >> +   /* see if we live in a "glue" directory */ >> +   if (!live_in_glue_dir(glue_dir, dev)) >> +       return; >> + >> +   mutex_unlock(&gdp_mutex); >> +} >> + >> static int device_add_class_symlinks(struct device *dev) >> { >>     struct device_node *of_node = dev_of_node(dev); >> @@ -2040,7 +2066,7 @@ int device_add(struct device *dev) >>     pr_debug("device: '%s': %s\n", dev_name(dev), __func__); >>     parent = get_device(dev->parent); >> -   kobj = get_device_parent(dev, parent); >> +   kobj = get_device_parent_locked_if_glue_dir(dev, parent); >>     if (IS_ERR(kobj)) { >>         error = PTR_ERR(kobj); >>         goto parent_error; >> @@ -2055,10 +2081,12 @@ int device_add(struct device *dev) >>     /* first, register with generic layer. */ >>     /* we require the name to be set before, and pass NULL */ >>     error = kobject_add(&dev->kobj, dev->kobj.parent, NULL); >> -   if (error) { >> -       glue_dir = get_glue_dir(dev); >> + >> +   glue_dir = get_glue_dir(dev); >> +   unlock_if_glue_dir(dev, glue_dir); >> + >> +   if (error) >>         goto Error; >> -   } >>     /* notify platform of device entry */ >>     error = device_platform_notify(dev, KOBJ_ADD); >> -- This change has been done in device_add(). AFAICT, locked version of get_device_parent should be used in device_move() also. Thanks -- Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project