[PATCH] ALSA: rawmidi: Another workaround for false-positive mutex lockdep warning

Takashi Iwai <[email protected]>
Newsgroups gmane.linux.sound
Message-ID <[email protected]>
While we attempted to work around the false-positive lockdep warning
due to the nested mutex lock in rawmidi at the open path for a UMP
legacy rawmidi, it didn't cover the similar locking at its close path,
and this still caused another false-positive reports by syzkaller.

Add a similar workaround to snd_rawmidi_kernel_release() as done in
the former commit 9c04742e73b3 ("ALSA: rawmidi: Work around
false-positive mutex lockdep warning") to cover completely.

Reported-by: [email protected]
Closes: https://lore.kernel.org/[email protected]
Signed-off-by: Takashi Iwai <[email protected]>
---
 include/sound/rawmidi.h | 8 +++++++-
 sound/core/rawmidi.c    | 9 ++++++---
 sound/core/ump.c        | 3 ++-
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
index 88a6159364d0..4154035af414 100644
--- a/include/sound/rawmidi.h
+++ b/include/sound/rawmidi.h
@@ -179,7 +179,8 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info
 int snd_rawmidi_kernel_open_nested(struct snd_rawmidi *rmidi, int subdevice,
 				   int mode, struct snd_rawmidi_file *rfile,
 				   int depth);
-int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile);
+int snd_rawmidi_kernel_release_nested(struct snd_rawmidi_file *rfile,
+				      int depth);
 int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
 			      struct snd_rawmidi_params *params);
 int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
@@ -201,6 +202,11 @@ static inline int snd_rawmidi_kernel_open(struct snd_rawmidi *rmidi,
 	return snd_rawmidi_kernel_open_nested(rmidi, subdevice, mode, rfile, 0);
 }
 
+static inline int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile)
+{
+	return snd_rawmidi_kernel_release_nested(rfile, 0);
+}
+
 /* set up the tied devices */
 static inline void snd_rawmidi_tie_devices(struct snd_rawmidi *r1,
 					   struct snd_rawmidi *r2)
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index bf504e27f73e..b688fd76f5d5 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -571,7 +571,6 @@ static void rawmidi_release_priv(struct snd_rawmidi_file *rfile)
 	struct snd_rawmidi *rmidi;
 
 	rmidi = rfile->rmidi;
-	guard(mutex)(&rmidi->open_mutex);
 	if (rfile->input) {
 		close_substream(rmidi, rfile->input, 1);
 		rfile->input = NULL;
@@ -585,7 +584,8 @@ static void rawmidi_release_priv(struct snd_rawmidi_file *rfile)
 }
 
 /* called from sound/core/seq/seq_midi.c */
-int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile)
+int snd_rawmidi_kernel_release_nested(struct snd_rawmidi_file *rfile,
+				      int depth)
 {
 	struct snd_rawmidi *rmidi;
 
@@ -593,7 +593,9 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile)
 		return -ENXIO;
 
 	rmidi = rfile->rmidi;
+	mutex_lock_nested(&rmidi->open_mutex, depth);
 	rawmidi_release_priv(rfile);
+	mutex_unlock(&rmidi->open_mutex);
 	module_put(rmidi->card->module);
 	return 0;
 }
@@ -607,7 +609,8 @@ static int snd_rawmidi_release(struct inode *inode, struct file *file)
 
 	rfile = file->private_data;
 	rmidi = rfile->rmidi;
-	rawmidi_release_priv(rfile);
+	scoped_guard(mutex, &rmidi->open_mutex)
+		rawmidi_release_priv(rfile);
 	kfree(rfile);
 	module = rmidi->card->module;
 	snd_card_file_remove(rmidi->card, file);
diff --git a/sound/core/ump.c b/sound/core/ump.c
index 82ad155c56e6..d183c8a000bd 100644
--- a/sound/core/ump.c
+++ b/sound/core/ump.c
@@ -1184,7 +1184,8 @@ static int snd_ump_legacy_close(struct snd_rawmidi_substream *substream)
 		ump->legacy_substreams[dir][group] = NULL;
 	if (dir == SNDRV_RAWMIDI_STREAM_OUTPUT) {
 		if (!--ump->legacy_out_opens)
-			snd_rawmidi_kernel_release(&ump->legacy_out_rfile);
+			snd_rawmidi_kernel_release_nested(&ump->legacy_out_rfile,
+							  SINGLE_DEPTH_NESTING);
 	}
 	return 0;
 }
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.