Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp512687pxv; Thu, 22 Jul 2021 05:55:17 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwOzDeAtEWcBsySzLmMQXCB5A/Xdsqkwyr3kyYLzwSMdU2W/5Tv2V2UA+pwt0fA6OaMFBq0 X-Received: by 2002:a50:fb95:: with SMTP id e21mr54647245edq.65.1626958517390; Thu, 22 Jul 2021 05:55:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626958517; cv=none; d=google.com; s=arc-20160816; b=l01R757V7FAIt04lzXOEZBOBSiZS+OArMJxtLZfJVGG9KoXSbtTGa7BWof0c3cTqRH J9hcWaHWiRiZ+uocQyqJ3NlzBSORjQ1BovJV8tCAvQnFPcWZTTfJSiqNO3cZ36eF37rt 8NnlspUjMt8Dviu501qkIs8qceMOG+Dv4Pne2hCf1Y4u/C0k9u5rpPly0ZvOLoL14D2X kkSLFIygt7mJsi4jPfdDsZ7LH8ZfuBgnSIp+P12H6cu7cpOu3nOjjwHvIky6kOGcj9/w IlWplcYP58uIoWVGTXxfFy8K8yH8g89xM5J/+hqYs8wPTll7FC27pHJHl+RjJHdPKOPM 3cHg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:content-language :in-reply-to:mime-version:user-agent:date:message-id:from:references :cc:to:subject; bh=gr1Ak/ATGqO2JikxexcRSGasgzarlavh334cbUuBdfA=; b=JcRVdaWnf/4dgHlkMNbHh5KKZFDPG2tc1CWhaAnBdTxclOAjBYAOp8TOPYRbejZsoH yKaugBxArTifv5+gU8YCIEF01bbtyJ6HfxxhGwfacdBgAs8DSdSksYZkgEqE2F+XnMDL uiUyTUSaMOnI4Kh0gaxE7JHKlN97WUsjwwi5gaNYIGuYpO9Dl4CS1eCzTa1uzOa1zRvg 4sI5UxuTP3rrSgMrWv/z6L8LJJS2MHt25J41LcGH0AM1SoLn157GS5Wy9LKEAl9iaBdy bWCmVNL7bCAbEjVDfX0B4lQFgix2P0LvZLfZKvQIsYsUdRr4jvo/M9x/zoZmBKE61KAb LgDg== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (p=NONE sp=NONE dis=NONE) header.from=huawei.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bo10si21590850edb.577.2021.07.22.05.54.54; Thu, 22 Jul 2021 05:55:17 -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; 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=fail (p=NONE sp=NONE dis=NONE) header.from=huawei.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231939AbhGVMMy (ORCPT + 99 others); Thu, 22 Jul 2021 08:12:54 -0400 Received: from szxga03-in.huawei.com ([45.249.212.189]:12286 "EHLO szxga03-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231824AbhGVMMx (ORCPT ); Thu, 22 Jul 2021 08:12:53 -0400 Received: from dggeml757-chm.china.huawei.com (unknown [172.30.72.54]) by szxga03-in.huawei.com (SkyGuard) with ESMTP id 4GVshJ0KWzz7tCv; Thu, 22 Jul 2021 20:48:48 +0800 (CST) Received: from [10.174.179.200] (10.174.179.200) by dggeml757-chm.china.huawei.com (10.1.199.137) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2; Thu, 22 Jul 2021 20:53:24 +0800 Subject: Re: [PATCH net v2] can: raw: fix raw_rcv panic for sock UAF To: Oliver Hartkopp CC: , , , , , References: <20210722070819.1048263-1-william.xuanziyang@huawei.com> From: "Ziyang Xuan (William)" Message-ID: Date: Thu, 22 Jul 2021 20:53:24 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset="utf-8" Content-Language: en-US Content-Transfer-Encoding: 8bit X-Originating-IP: [10.174.179.200] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To dggeml757-chm.china.huawei.com (10.1.199.137) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org >> diff --git a/net/can/raw.c b/net/can/raw.c >> index ed4fcb7ab0c3..cd5a49380116 100644 >> --- a/net/can/raw.c >> +++ b/net/can/raw.c >> @@ -546,10 +546,18 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, >>                   return -EFAULT; >>           } >>   +        rtnl_lock(); >>           lock_sock(sk); >>   -        if (ro->bound && ro->ifindex) >> +        if (ro->bound && ro->ifindex) { >>               dev = dev_get_by_index(sock_net(sk), ro->ifindex); >> +            if (!dev) { > > >> +                if (count > 1) >> +                    kfree(filter); > > This was NOT suggested! > > I've been talking about removing the other kfree() "improvement" you suggested. > > The kfree() should only be done when ro->bound and ro->ifindex are cleared. > > So when you remove these two lines it should be ok. > > Please try to increase the context in the diff. > > Thanks, > Oliver Sorry, I am a little confused. The following codes are the latest raw_setsockopt function realization(ignore some non-key parts) with my patch. Now we assume the condition that count more than 1, ro->bound and ro->ifindex are not zero, dev_get_by_index() will return NULL. We analyze the code logic. static int raw_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval, unsigned int optlen) { ...... struct can_filter *filter = NULL; ...... switch (optname) { case CAN_RAW_FILTER: ...... if (count > 1) { /* filter does not fit into dfilter => alloc space */ filter = memdup_sockptr(optval, optlen); // filter point to a heap memory if (IS_ERR(filter)) return PTR_ERR(filter); } else if (count == 1) { ...... } rtnl_lock(); lock_sock(sk); if (ro->bound && ro->ifindex) { dev = dev_get_by_index(sock_net(sk), ro->ifindex); /* * dev == NULL is exception. The function will exit abnormally. * Memory pointed by filer does not forward to anyone for maintenance. * If we do not kfree(filter) here, memory will be leaked after function exit. */ if (!dev) { if (count > 1) kfree(filter); err = -ENODEV; goto out_fil; } } if (ro->bound) { /* (try to) register the new filters */ if (count == 1) err = raw_enable_filters(sock_net(sk), dev, sk, &sfilter, 1); else err = raw_enable_filters(sock_net(sk), dev, sk, filter, count); if (err) { if (count > 1) kfree(filter); goto out_fil; } /* remove old filter registrations */ raw_disable_filters(sock_net(sk), dev, sk, ro->filter, ro->count); } /* remove old filter space */ if (ro->count > 1) kfree(ro->filter); /* link new filters to the socket */ if (count == 1) { /* copy filter data for single filter */ ro->dfilter = sfilter; filter = &ro->dfilter; } ro->filter = filter; ro->count = count; out_fil: if (dev) dev_put(dev); release_sock(sk); rtnl_unlock(); break; ...... return err; } So I think my modification is right. Thank you.