2009-07-06 22:30:48

by Catalin Marinas

[permalink] [raw]
Subject: Possible memory leak in fs/sysfs/bin.c

Hi,

I get about 28 (after 1 hour uptime) kmemleak reports like the one below:

unreferenced object 0xc24ab090 (size 4096):
comm "cat", pid 2930, jiffies 4294902918
backtrace:
[<c01e0c3a>] create_object+0xfa/0x250
[<c01e1e7d>] kmemleak_alloc+0x5d/0x70
[<c01dbc2d>] __kmalloc_track_caller+0x10d/0x1e0
[<c01bf5e4>] memdup_user+0x24/0x70
[<c02394d9>] write+0xb9/0x1b0
[<c01e480c>] vfs_write+0x9c/0x190
[<c01e49bd>] sys_write+0x3d/0x70
[<c010300c>] sysenter_do_call+0x12/0x38
[<ffffffff>] 0xffffffff

This is the write() function in the file mention in subject. It looks
to me like commit 1c8542c7bb replaced kmalloc() with memdup_user() but
also dropped the kfree(temp). The memdup_user() function allocates
memory but that's never freed in write().

Maybe something like this:

diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index 9345806..bde6602 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -164,6 +164,7 @@ static ssize_t write(struct file *file, const char
__user *userbuf,
mutex_lock(&bb->mutex);

memcpy(bb->buffer, temp, count);
+ kfree(temp);

count = flush_write(dentry, bb->buffer, offs, count);
mutex_unlock(&bb->mutex);

--
Catalin


2009-07-06 23:12:33

by Parag Warudkar

[permalink] [raw]
Subject: Re: Possible memory leak in fs/sysfs/bin.c

Hi

Catalin Marinas <catalin.marinas <at> arm.com> writes:


> --- a/fs/sysfs/bin.c
> +++ b/fs/sysfs/bin.c
> @@ -164,6 +164,7 @@ static ssize_t write(struct file *file, const char
> __user *userbuf,
> mutex_lock(&bb->mutex);
>
> memcpy(bb->buffer, temp, count);
> + kfree(temp);

Does the kfree() need to be inside the mutex_lock? Otherwise looks OK to me.

Parag



2009-07-07 13:16:32

by Catalin Marinas

[permalink] [raw]
Subject: Re: Possible memory leak in fs/sysfs/bin.c

Parag Warudkar <[email protected]> wrote:
> Catalin Marinas <catalin.marinas <at> arm.com> writes:
>
>> --- a/fs/sysfs/bin.c
>> +++ b/fs/sysfs/bin.c
>> @@ -164,6 +164,7 @@ static ssize_t write(struct file *file, const char
>> __user *userbuf,
>> mutex_lock(&bb->mutex);
>>
>> memcpy(bb->buffer, temp, count);
>> + kfree(temp);
>
> Does the kfree() need to be inside the mutex_lock? Otherwise looks
> OK to me.

Here's the updated patch:


Free the memory allocated by memdup_user() in fs/sysfs/bin.c

Commit 1c8542c7bb replaced kmalloc() with memdup_user() in the write()
function but also dropped the kfree(temp). The memdup_user() function
allocates memory which is never freed.

Signed-off-by: Catalin Marinas <[email protected]>
---
fs/sysfs/bin.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index 9345806..2524714 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -171,6 +171,7 @@ static ssize_t write(struct file *file, const char __user *userbuf,
if (count > 0)
*off = offs + count;

+ kfree(temp);
return count;
}


--
Catalin