Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.

Commit 10aff53

Browse files
Linux Build Service AccountGerrit - the friendly Code Review server
Linux Build Service Account
authored and
Gerrit - the friendly Code Review server
committedJun 20, 2018
Merge "ANDROID: sound: rawmidi: Hold lock around realloc" into LA.BR.1.2.9.1_rb1.5
2 parents bd37f05 + 2bfcf07 commit 10aff53

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed
 

‎include/sound/rawmidi.h

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ struct snd_rawmidi_runtime {
7777
size_t xruns; /* over/underruns counter */
7878
/* misc */
7979
spinlock_t lock;
80+
struct mutex realloc_mutex;
8081
wait_queue_head_t sleep;
8182
/* event handler (new bytes, input only) */
8283
void (*event)(struct snd_rawmidi_substream *substream);

‎sound/core/rawmidi.c

+38-5
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
108108
return -ENOMEM;
109109
runtime->substream = substream;
110110
spin_lock_init(&runtime->lock);
111+
mutex_init(&runtime->realloc_mutex);
111112
init_waitqueue_head(&runtime->sleep);
112113
INIT_WORK(&runtime->event_work, snd_rawmidi_input_event_work);
113114
runtime->event = NULL;
@@ -622,8 +623,9 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
622623
struct snd_rawmidi_params * params)
623624
{
624625
char *newbuf;
626+
char *oldbuf;
625627
struct snd_rawmidi_runtime *runtime = substream->runtime;
626-
628+
unsigned long flags;
627629
if (substream->append && substream->use_count > 1)
628630
return -EBUSY;
629631
snd_rawmidi_drain_output(substream);
@@ -634,13 +636,22 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
634636
return -EINVAL;
635637
}
636638
if (params->buffer_size != runtime->buffer_size) {
637-
newbuf = krealloc(runtime->buffer, params->buffer_size,
639+
mutex_lock(&runtime->realloc_mutex);
640+
newbuf = __krealloc(runtime->buffer, params->buffer_size,
638641
GFP_KERNEL);
639-
if (!newbuf)
642+
if (!newbuf) {
643+
mutex_unlock(&runtime->realloc_mutex);
640644
return -ENOMEM;
645+
}
646+
spin_lock_irqsave(&runtime->lock, flags);
647+
oldbuf = runtime->buffer;
641648
runtime->buffer = newbuf;
642649
runtime->buffer_size = params->buffer_size;
643650
runtime->avail = runtime->buffer_size;
651+
spin_unlock_irqrestore(&runtime->lock, flags);
652+
if (oldbuf != newbuf)
653+
kfree(oldbuf);
654+
mutex_unlock(&runtime->realloc_mutex);
644655
}
645656
runtime->avail_min = params->avail_min;
646657
substream->active_sensing = !params->no_active_sensing;
@@ -651,7 +662,9 @@ int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
651662
struct snd_rawmidi_params * params)
652663
{
653664
char *newbuf;
665+
char *oldbuf;
654666
struct snd_rawmidi_runtime *runtime = substream->runtime;
667+
unsigned long flags;
655668

656669
snd_rawmidi_drain_input(substream);
657670
if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) {
@@ -661,12 +674,21 @@ int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
661674
return -EINVAL;
662675
}
663676
if (params->buffer_size != runtime->buffer_size) {
664-
newbuf = krealloc(runtime->buffer, params->buffer_size,
677+
mutex_lock(&runtime->realloc_mutex);
678+
newbuf = __krealloc(runtime->buffer, params->buffer_size,
665679
GFP_KERNEL);
666-
if (!newbuf)
680+
if (!newbuf) {
681+
mutex_unlock(&runtime->realloc_mutex);
667682
return -ENOMEM;
683+
}
684+
spin_lock_irqsave(&runtime->lock, flags);
685+
oldbuf = runtime->buffer;
668686
runtime->buffer = newbuf;
669687
runtime->buffer_size = params->buffer_size;
688+
spin_unlock_irqrestore(&runtime->lock, flags);
689+
if (oldbuf != newbuf)
690+
kfree(oldbuf);
691+
mutex_unlock(&runtime->realloc_mutex);
670692
}
671693
runtime->avail_min = params->avail_min;
672694
return 0;
@@ -935,6 +957,8 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream,
935957
long result = 0, count1;
936958
struct snd_rawmidi_runtime *runtime = substream->runtime;
937959

960+
if (userbuf)
961+
mutex_lock(&runtime->realloc_mutex);
938962
while (count > 0 && runtime->avail) {
939963
count1 = runtime->buffer_size - runtime->appl_ptr;
940964
if (count1 > count)
@@ -948,6 +972,7 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream,
948972
spin_unlock_irqrestore(&runtime->lock, flags);
949973
if (copy_to_user(userbuf + result,
950974
runtime->buffer + runtime->appl_ptr, count1)) {
975+
mutex_unlock(&runtime->realloc_mutex);
951976
return result > 0 ? result : -EFAULT;
952977
}
953978
spin_lock_irqsave(&runtime->lock, flags);
@@ -959,6 +984,8 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream,
959984
result += count1;
960985
count -= count1;
961986
}
987+
if (userbuf)
988+
mutex_unlock(&runtime->realloc_mutex);
962989
return result;
963990
}
964991

@@ -1168,10 +1195,14 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
11681195
return -EINVAL;
11691196

11701197
result = 0;
1198+
if (userbuf)
1199+
mutex_lock(&runtime->realloc_mutex);
11711200
spin_lock_irqsave(&runtime->lock, flags);
11721201
if (substream->append) {
11731202
if ((long)runtime->avail < count) {
11741203
spin_unlock_irqrestore(&runtime->lock, flags);
1204+
if (userbuf)
1205+
mutex_unlock(&runtime->realloc_mutex);
11751206
return -EAGAIN;
11761207
}
11771208
}
@@ -1203,6 +1234,8 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
12031234
__end:
12041235
count1 = runtime->avail < runtime->buffer_size;
12051236
spin_unlock_irqrestore(&runtime->lock, flags);
1237+
if (userbuf)
1238+
mutex_unlock(&runtime->realloc_mutex);
12061239
if (count1)
12071240
snd_rawmidi_output_trigger(substream, 1);
12081241
return result;

0 commit comments

Comments
 (0)
This repository has been archived.