Blob Blame History Raw
From ef4db239cda2d74f53120e223643b0f5bbf947c1 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 17 Jul 2018 23:12:33 +0200
Subject: [PATCH] ALSA: rawmidi: Use kvmalloc() for buffers
Git-commit: ef4db239cda2d74f53120e223643b0f5bbf947c1
Patch-mainline: v4.19-rc1
References: bsc#1121278

The size of in-kernel rawmidi buffers may be big up to 1MB, and it can
be specified freely by user-space; which implies that user-space may
trigger kmalloc() errors frequently.

This patch replaces the buffer allocation via kvmalloc() for dealing
with bigger buffers gracefully.

Signed-off-by: Takashi Iwai <tiwai@suse.de>

---
 sound/core/rawmidi.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index cc944a3637a2..69517e18ef07 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -29,6 +29,7 @@
 #include <linux/mutex.h>
 #include <linux/module.h>
 #include <linux/delay.h>
+#include <linux/mm.h>
 #include <sound/rawmidi.h>
 #include <sound/info.h>
 #include <sound/control.h>
@@ -128,7 +129,7 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
 		runtime->avail = 0;
 	else
 		runtime->avail = runtime->buffer_size;
-	runtime->buffer = kmalloc(runtime->buffer_size, GFP_KERNEL);
+	runtime->buffer = kvmalloc(runtime->buffer_size, GFP_KERNEL);
 	if (!runtime->buffer) {
 		kfree(runtime);
 		return -ENOMEM;
@@ -142,7 +143,7 @@ static int snd_rawmidi_runtime_free(struct snd_rawmidi_substream *substream)
 {
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
-	kfree(runtime->buffer);
+	kvfree(runtime->buffer);
 	kfree(runtime);
 	substream->runtime = NULL;
 	return 0;
@@ -654,7 +655,7 @@ static int resize_runtime_buffer(struct snd_rawmidi_runtime *runtime,
 	if (params->avail_min < 1 || params->avail_min > params->buffer_size)
 		return -EINVAL;
 	if (params->buffer_size != runtime->buffer_size) {
-		newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
+		newbuf = kvmalloc(params->buffer_size, GFP_KERNEL);
 		if (!newbuf)
 			return -ENOMEM;
 		spin_lock_irq(&runtime->lock);
@@ -663,7 +664,7 @@ static int resize_runtime_buffer(struct snd_rawmidi_runtime *runtime,
 		runtime->buffer_size = params->buffer_size;
 		__reset_runtime_ptrs(runtime, is_input);
 		spin_unlock_irq(&runtime->lock);
-		kfree(oldbuf);
+		kvfree(oldbuf);
 	}
 	runtime->avail_min = params->avail_min;
 	return 0;
-- 
2.20.1