All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yang Yingliang <yangyingliang@huawei.com>
To: <minyard@acm.org>
Cc: <cminyard@mvista.com>, <arnd@arndb.de>,
	<gregkh@linuxfoundation.org>,
	<openipmi-developer@lists.sourceforge.net>,
	<qiaonuohan@huawei.com>, <linux-kernel@vger.kernel.org>,
	<stable@vger.kernel.org>
Subject: Re: [Openipmi-developer] [PATCH v2] ipmi_si: fix use-after-free of resource->name
Date: Mon, 28 Jan 2019 09:53:30 +0800	[thread overview]
Message-ID: <5C4E609A.7050609@huawei.com> (raw)
In-Reply-To: <20190126150809.GA11354@minyard.net>



On 2019/1/26 23:08, Corey Minyard wrote:
> On Sat, Jan 26, 2019 at 05:14:54PM +0800, Yang Yingliang wrote:
>> When we excute the following commands, we got oops
>> rmmod ipmi_si
>> cat /proc/ioports
>>
> snip..
>
>> If io_setup is called successful in try_smi_init() but try_smi_init()
>> goes out_err before calling ipmi_register_smi(), so ipmi_unregister_smi()
>> will not be called while removing module. It leads to the resource that
>> allocated in io_setup() can not be freed, but the name(DEVICE_NAME) of
>> resource is freed while removing the module. It causes use-after-free
>> when cat /proc/ioports.
>>
>> Fix this by calling io_cleanup() while try_smi_init() goes to out_err
>> and don't call release_region() if request_region() is not called to
>> avoid error prints.
>>
>> Fixes: 93c303d2045b ("ipmi_si: Clean up shutdown a bit")
>> Cc: stable@vger.kernel.org
>> Reported-by: NuoHan Qiao <qiaonuohan@huawei.com>
>> Suggested-by: Corey Minyard <cminyard@mvista.com>
>> Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
>> ---
>>   drivers/char/ipmi/ipmi_si_intf.c    | 5 +++++
>>   drivers/char/ipmi/ipmi_si_port_io.c | 3 +++
>>   2 files changed, 8 insertions(+)
>>
>> diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
>> index dc8603d..f1b9fda 100644
>> --- a/drivers/char/ipmi/ipmi_si_intf.c
>> +++ b/drivers/char/ipmi/ipmi_si_intf.c
>> @@ -2085,6 +2085,11 @@ static int try_smi_init(struct smi_info *new_smi)
>>   	WARN_ON(new_smi->io.dev->init_name != NULL);
>>   
>>    out_err:
>> +	if (rv && new_smi->io.io_cleanup) {
>> +		new_smi->io.io_cleanup(&new_smi->io);
>> +		new_smi->io.io_cleanup = NULL;
>> +	}
>> +
>>   	kfree(init_name);
>>   	return rv;
>>   }
>> diff --git a/drivers/char/ipmi/ipmi_si_port_io.c b/drivers/char/ipmi/ipmi_si_port_io.c
>> index ef6dffc..0c46a3f 100644
>> --- a/drivers/char/ipmi/ipmi_si_port_io.c
>> +++ b/drivers/char/ipmi/ipmi_si_port_io.c
>> @@ -53,6 +53,9 @@ static void port_cleanup(struct si_sm_io *io)
>>   	unsigned int addr = io->addr_data;
>>   	int          idx;
>>   
>> +	if (io->regsize != 1 && io->regsize != 2 && io->regsize != 4)
>> +		return;
>> +
> Why do you need this part?  I can't see the reason for it.  The addr
> part below should handle that, especially with the above change.
>
> -corey
If ipmi_si_port_setup() returns in default case, request_region() won't 
be called,
so we don't need to call release_region() or it will prints some warning 
messages like
this "Trying to free nonexistent resource...".

We don't need call io_cleanup() until the io_setup() returns successful.
How about change this part like this:

diff --git a/drivers/char/ipmi/ipmi_si_port_io.c 
b/drivers/char/ipmi/ipmi_si_port_io.c
index ef6dffc..03924c3 100644
--- a/drivers/char/ipmi/ipmi_si_port_io.c
+++ b/drivers/char/ipmi/ipmi_si_port_io.c
@@ -68,8 +68,6 @@ int ipmi_si_port_setup(struct si_sm_io *io)
         if (!addr)
                 return -ENODEV;

-       io->io_cleanup = port_cleanup;
-
         /*
          * Figure out the actual inb/inw/inl/etc routine to use based
          * upon the register size.
@@ -109,5 +107,8 @@ int ipmi_si_port_setup(struct si_sm_io *io)
                         return -EIO;
                 }
         }
+
+       io->io_cleanup = port_cleanup;
+
         return 0;
  }

Thanks,
Yang
>
>>   	if (addr) {
>>   		for (idx = 0; idx < io->io_size; idx++)
>>   			release_region(addr + idx * io->regspacing,
>> -- 
>> 1.8.3
>>
>>
>>
>>
>> _______________________________________________
>> Openipmi-developer mailing list
>> Openipmi-developer@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/openipmi-developer
> .
>



  reply	other threads:[~2019-01-28  1:53 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-26  9:14 [PATCH v2] ipmi_si: fix use-after-free of resource->name Yang Yingliang
2019-01-26 15:08 ` [Openipmi-developer] " Corey Minyard
2019-01-28  1:53   ` Yang Yingliang [this message]
2019-01-28  2:36     ` Corey Minyard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5C4E609A.7050609@huawei.com \
    --to=yangyingliang@huawei.com \
    --cc=arnd@arndb.de \
    --cc=cminyard@mvista.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=minyard@acm.org \
    --cc=openipmi-developer@lists.sourceforge.net \
    --cc=qiaonuohan@huawei.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.