Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[PATCH] sg.c: fix a memory leak in devices seq_file implementation

I know that scsi procfs is legacy code but this is a fix for a memory leak.

While reading through sg.c I realized that the implementation of
/proc/scsi/sg/devices with seq_file is leaking memory due to freeing the
pointer returned by the next() iterator method. Since next() might return
NULL or an error this is wrong. This patch fixes it through using the
seq_files private field for holding the reference to the iterator object.

Here is a small bash script to trigger the leak. Use slabtop to watch
the size-32 usage grow and grow.

#!/bin/sh

while true; do
cat /proc/scsi/sg/devices > /dev/null
done

Signed-off-by: Jan Blunck <j.blunck@tu-harburg.de>
Acked-by: James Bottomley <James.Bottomley@steeleye.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Jan Blunck and committed by
Linus Torvalds
729d70f5 8126fdbc

+6 -7
+6 -7
drivers/scsi/sg.c
··· 2971 2971 { 2972 2972 struct sg_proc_deviter * it = kmalloc(sizeof(*it), GFP_KERNEL); 2973 2973 2974 + s->private = it; 2974 2975 if (! it) 2975 2976 return NULL; 2977 + 2976 2978 if (NULL == sg_dev_arr) 2977 - goto err1; 2979 + return NULL; 2978 2980 it->index = *pos; 2979 2981 it->max = sg_last_dev(); 2980 2982 if (it->index >= it->max) 2981 - goto err1; 2983 + return NULL; 2982 2984 return it; 2983 - err1: 2984 - kfree(it); 2985 - return NULL; 2986 2985 } 2987 2986 2988 2987 static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos) 2989 2988 { 2990 - struct sg_proc_deviter * it = (struct sg_proc_deviter *) v; 2989 + struct sg_proc_deviter * it = s->private; 2991 2990 2992 2991 *pos = ++it->index; 2993 2992 return (it->index < it->max) ? it : NULL; ··· 2994 2995 2995 2996 static void dev_seq_stop(struct seq_file *s, void *v) 2996 2997 { 2997 - kfree (v); 2998 + kfree(s->private); 2998 2999 } 2999 3000 3000 3001 static int sg_proc_open_dev(struct inode *inode, struct file *file)