ALSA: core: Don't ignore errors at creating proc files
authorTakashi Iwai <tiwai@suse.de>
Wed, 22 Apr 2015 20:29:10 +0000 (22:29 +0200)
committerTakashi Iwai <tiwai@suse.de>
Fri, 24 Apr 2015 15:31:06 +0000 (17:31 +0200)
So far we've ignored the errors at creating proc files in many places.
But they should be rather treated seriously.

Also, by assuring the error handling, we can get rid of superfluous
snd_info_free_entry() calls as they will be removed by the parent in
the caller side.

This patch fixes the missing error checks and reduces the superfluous
free calls.

Acked-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/core/info.c
sound/core/init.c
sound/core/seq/seq_info.c
sound/core/sound.c
sound/core/sound_oss.c

index 339f90a3aa29bb9a089b3ecff01d9049bb06d6e1..4169062fabf5cc2d548ea402481068f28e0eba11 100644 (file)
@@ -482,10 +482,11 @@ int __init snd_info_init(void)
        if (!snd_seq_root)
                goto error;
 #endif
-       snd_info_version_init();
-       snd_minor_info_init();
-       snd_minor_info_oss_init();
-       snd_card_info_init();
+       if (snd_info_version_init() < 0 ||
+           snd_minor_info_init() < 0 ||
+           snd_minor_info_oss_init() < 0 ||
+           snd_card_info_init() < 0)
+               goto error;
        return 0;
 
  error:
@@ -847,11 +848,7 @@ static int __init snd_info_version_init(void)
        if (entry == NULL)
                return -ENOMEM;
        entry->c.text.read = snd_info_version_read;
-       if (snd_info_register(entry) < 0) {
-               snd_info_free_entry(entry);
-               return -ENOMEM;
-       }
-       return 0;
+       return snd_info_register(entry); /* freed in error path */
 }
 
 #endif /* CONFIG_PROC_FS */
index 0af34fac04990a59bab53ccc670a1756ce79406e..769a783757ff293085dc69372a6b7c38c50b16ba 100644 (file)
@@ -853,18 +853,16 @@ int __init snd_card_info_init(void)
        if (! entry)
                return -ENOMEM;
        entry->c.text.read = snd_card_info_read;
-       if (snd_info_register(entry) < 0) {
-               snd_info_free_entry(entry);
-               return -ENOMEM;
-       }
+       if (snd_info_register(entry) < 0)
+               return -ENOMEM; /* freed in error path */
 
 #ifdef MODULE
        entry = snd_info_create_module_entry(THIS_MODULE, "modules", NULL);
-       if (entry) {
-               entry->c.text.read = snd_card_module_info_read;
-               if (snd_info_register(entry) < 0)
-                       snd_info_free_entry(entry);
-       }
+       if (!entry)
+               return -ENOMEM;
+       entry->c.text.read = snd_card_module_info_read;
+       if (snd_info_register(entry) < 0)
+               return -ENOMEM; /* freed in error path */
 #endif
 
        return 0;
index acf7769419f06972cfb179991ca6754fda6df531..d3c65e780e9ea20ec7aa239eca450be52d93f5c7 100644 (file)
@@ -51,6 +51,13 @@ create_info_entry(char *name, void (*read)(struct snd_info_entry *,
        return entry;
 }
 
+static void free_info_entries(void)
+{
+       snd_info_free_entry(queues_entry);
+       snd_info_free_entry(clients_entry);
+       snd_info_free_entry(timer_entry);
+}
+
 /* create all our /proc entries */
 int __init snd_seq_info_init(void)
 {
@@ -59,14 +66,18 @@ int __init snd_seq_info_init(void)
        clients_entry = create_info_entry("clients",
                                          snd_seq_info_clients_read);
        timer_entry = create_info_entry("timer", snd_seq_info_timer_read);
+       if (!queues_entry || !clients_entry || !timer_entry)
+               goto error;
        return 0;
+
+ error:
+       free_info_entries();
+       return -ENOMEM;
 }
 
 int __exit snd_seq_info_done(void)
 {
-       snd_info_free_entry(queues_entry);
-       snd_info_free_entry(clients_entry);
-       snd_info_free_entry(timer_entry);
+       free_info_entries();
        return 0;
 }
 #endif
index d584944c8fe55d37459cfed5ff53582d3fe0d657..8fc402e4ff3520beab9ba66a8da51e7d43866361 100644 (file)
@@ -386,14 +386,10 @@ int __init snd_minor_info_init(void)
        struct snd_info_entry *entry;
 
        entry = snd_info_create_module_entry(THIS_MODULE, "devices", NULL);
-       if (entry) {
-               entry->c.text.read = snd_minor_info_read;
-               if (snd_info_register(entry) < 0) {
-                       snd_info_free_entry(entry);
-                       entry = NULL;
-               }
-       }
-       return 0;
+       if (!entry)
+               return -ENOMEM;
+       entry->c.text.read = snd_minor_info_read;
+       return snd_info_register(entry); /* freed in error path */
 }
 #endif /* CONFIG_PROC_FS */
 
index 5fc3c6534225dc122803b594e6d8cd81ace2e9db..56d2f409f1efb67612754d4f370f8410454174df 100644 (file)
@@ -260,12 +260,10 @@ int __init snd_minor_info_oss_init(void)
        struct snd_info_entry *entry;
 
        entry = snd_info_create_module_entry(THIS_MODULE, "devices", snd_oss_root);
-       if (entry) {
-               entry->c.text.read = snd_minor_info_oss_read;
-               if (snd_info_register(entry) < 0)
-                       snd_info_free_entry(entry);
-       }
-       return 0;
+       if (!entry)
+               return -ENOMEM;
+       entry->c.text.read = snd_minor_info_oss_read;
+       return snd_info_register(entry); /* freed in error path */
 }
 #endif /* CONFIG_PROC_FS */