ALSA: seq: Do error checks at creating system ports
authorTakashi Iwai <tiwai@suse.de>
Tue, 28 Aug 2018 10:49:43 +0000 (12:49 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 Nov 2019 16:59:41 +0000 (17:59 +0100)
[ Upstream commit b8e131542b47b81236ecf6768c923128e1f5db6e ]

snd_seq_system_client_init() doesn't check the errors returned from
its port creations.  Let's do it properly and handle the error paths.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
sound/core/seq/seq_system.c

index 8ce1d0b40dce1f0821f9cf9c144fed1ed27e413d..ce1f1e4727ab1e6d96434359d168cf0d81f4462f 100644 (file)
@@ -123,6 +123,7 @@ int __init snd_seq_system_client_init(void)
 {
        struct snd_seq_port_callback pcallbacks;
        struct snd_seq_port_info *port;
+       int err;
 
        port = kzalloc(sizeof(*port), GFP_KERNEL);
        if (!port)
@@ -144,7 +145,10 @@ int __init snd_seq_system_client_init(void)
        port->flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
        port->addr.client = sysclient;
        port->addr.port = SNDRV_SEQ_PORT_SYSTEM_TIMER;
-       snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_CREATE_PORT, port);
+       err = snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_CREATE_PORT,
+                                       port);
+       if (err < 0)
+               goto error_port;
 
        /* register announcement port */
        strcpy(port->name, "Announce");
@@ -154,16 +158,24 @@ int __init snd_seq_system_client_init(void)
        port->flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
        port->addr.client = sysclient;
        port->addr.port = SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE;
-       snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_CREATE_PORT, port);
+       err = snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_CREATE_PORT,
+                                       port);
+       if (err < 0)
+               goto error_port;
        announce_port = port->addr.port;
 
        kfree(port);
        return 0;
+
+ error_port:
+       snd_seq_system_client_done();
+       kfree(port);
+       return err;
 }
 
 
 /* unregister our internal client */
-void __exit snd_seq_system_client_done(void)
+void snd_seq_system_client_done(void)
 {
        int oldsysclient = sysclient;