[PATCH] ALSA: fireface: fix info leak in hwdep_read()
If "ff->dev_lock_changed" has not changed and "count" is too large then this will copy data beyond the end of the struct to user space.
Fixes: f656edd5fb33 ("ALSA: fireface: add hwdep interface") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com --- sound/firewire/fireface/ff-hwdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/firewire/fireface/ff-hwdep.c b/sound/firewire/fireface/ff-hwdep.c index 4b2e0dff5ddb..b84dde609a03 100644 --- a/sound/firewire/fireface/ff-hwdep.c +++ b/sound/firewire/fireface/ff-hwdep.c @@ -35,12 +35,12 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, }
memset(&event, 0, sizeof(event)); + count = min_t(long, count, sizeof(event.lock_status)); if (ff->dev_lock_changed) { event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; event.lock_status.status = (ff->dev_lock_count > 0); ff->dev_lock_changed = false;
- count = min_t(long, count, sizeof(event.lock_status)); }
spin_unlock_irq(&ff->lock);
Hi Dan,
Le 21/01/2021 à 07:10, Dan Carpenter a écrit :
If "ff->dev_lock_changed" has not changed
According to the "while (!ff->dev_lock_changed) { ... }" just above and the lock in place, can this ever happen?
In other word, I wonder if the "if (ff->dev_lock_changed)" test makes sense and if it could be removed.
(same for your other patch against sound/firewire/oxfw/oxfw-hwdep.c)
CJ
and "count" is too large then this will copy data beyond the end of the struct to user space.
Fixes: f656edd5fb33 ("ALSA: fireface: add hwdep interface") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com
sound/firewire/fireface/ff-hwdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/firewire/fireface/ff-hwdep.c b/sound/firewire/fireface/ff-hwdep.c index 4b2e0dff5ddb..b84dde609a03 100644 --- a/sound/firewire/fireface/ff-hwdep.c +++ b/sound/firewire/fireface/ff-hwdep.c @@ -35,12 +35,12 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, }
memset(&event, 0, sizeof(event));
- count = min_t(long, count, sizeof(event.lock_status)); if (ff->dev_lock_changed) { event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; event.lock_status.status = (ff->dev_lock_count > 0); ff->dev_lock_changed = false;
count = min_t(long, count, sizeof(event.lock_status));
}
spin_unlock_irq(&ff->lock);
On Thu, Jan 21, 2021 at 09:42:04PM +0100, Christophe JAILLET wrote:
Hi Dan,
Le 21/01/2021 à 07:10, Dan Carpenter a écrit :
If "ff->dev_lock_changed" has not changed
According to the "while (!ff->dev_lock_changed) { ... }" just above and the lock in place, can this ever happen?
In other word, I wonder if the "if (ff->dev_lock_changed)" test makes sense and if it could be removed.
(same for your other patch against sound/firewire/oxfw/oxfw-hwdep.c)
Yeah. That's a good point. I'll resend.
regards, dan carpenter
Smatch complains that "count" isn't clamped properly and "oxfw->dev_lock_changed" is false then it leads to an information leak. But it turns out that "oxfw->dev_lock_changed" is always set and the condition can be removed.
Signed-off-by: Dan Carpenter dan.carpenter@oracle.com --- v2: this version just removes the condition
sound/firewire/oxfw/oxfw-hwdep.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/sound/firewire/oxfw/oxfw-hwdep.c b/sound/firewire/oxfw/oxfw-hwdep.c index 9e1b3e151bad..a0fe99618554 100644 --- a/sound/firewire/oxfw/oxfw-hwdep.c +++ b/sound/firewire/oxfw/oxfw-hwdep.c @@ -35,13 +35,11 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, }
memset(&event, 0, sizeof(event)); - if (oxfw->dev_lock_changed) { - event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; - event.lock_status.status = (oxfw->dev_lock_count > 0); - oxfw->dev_lock_changed = false; + event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; + event.lock_status.status = (oxfw->dev_lock_count > 0); + oxfw->dev_lock_changed = false;
- count = min_t(long, count, sizeof(event.lock_status)); - } + count = min_t(long, count, sizeof(event.lock_status));
spin_unlock_irq(&oxfw->lock);
On Mon, Jan 25, 2021 at 02:12:54PM +0300, Dan Carpenter wrote:
Smatch complains that "count" isn't clamped properly and "oxfw->dev_lock_changed" is false then it leads to an information leak. But it turns out that "oxfw->dev_lock_changed" is always set and the condition can be removed.
Signed-off-by: Dan Carpenter dan.carpenter@oracle.com
v2: this version just removes the condition
sound/firewire/oxfw/oxfw-hwdep.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
Acked-by: Takashi Sakamoto o-takashi@sakamocchi.jp
diff --git a/sound/firewire/oxfw/oxfw-hwdep.c b/sound/firewire/oxfw/oxfw-hwdep.c index 9e1b3e151bad..a0fe99618554 100644 --- a/sound/firewire/oxfw/oxfw-hwdep.c +++ b/sound/firewire/oxfw/oxfw-hwdep.c @@ -35,13 +35,11 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, }
memset(&event, 0, sizeof(event));
- if (oxfw->dev_lock_changed) {
event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
event.lock_status.status = (oxfw->dev_lock_count > 0);
oxfw->dev_lock_changed = false;
- event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
- event.lock_status.status = (oxfw->dev_lock_count > 0);
- oxfw->dev_lock_changed = false;
count = min_t(long, count, sizeof(event.lock_status));
- }
count = min_t(long, count, sizeof(event.lock_status));
spin_unlock_irq(&oxfw->lock);
-- 2.29.2
Regards
Takashi Sakamoto
On Mon, 25 Jan 2021 12:12:54 +0100, Dan Carpenter wrote:
Smatch complains that "count" isn't clamped properly and "oxfw->dev_lock_changed" is false then it leads to an information leak. But it turns out that "oxfw->dev_lock_changed" is always set and the condition can be removed.
Signed-off-by: Dan Carpenter dan.carpenter@oracle.com
v2: this version just removes the condition
Applied now. Thanks.
Takashi
Smatch complains that "count" is not clamped when "ff->dev_lock_changed" and it leads to an information leak. Fortunately, that's not actually possible and the condition can be deleted.
Signed-off-by: Dan Carpenter dan.carpenter@oracle.com --- v2: just delet the condition
sound/firewire/fireface/ff-hwdep.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/sound/firewire/fireface/ff-hwdep.c b/sound/firewire/fireface/ff-hwdep.c index 4b2e0dff5ddb..ea64a2a41eea 100644 --- a/sound/firewire/fireface/ff-hwdep.c +++ b/sound/firewire/fireface/ff-hwdep.c @@ -35,13 +35,11 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, }
memset(&event, 0, sizeof(event)); - if (ff->dev_lock_changed) { - event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; - event.lock_status.status = (ff->dev_lock_count > 0); - ff->dev_lock_changed = false; + event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; + event.lock_status.status = (ff->dev_lock_count > 0); + ff->dev_lock_changed = false;
- count = min_t(long, count, sizeof(event.lock_status)); - } + count = min_t(long, count, sizeof(event.lock_status));
spin_unlock_irq(&ff->lock);
Hi,
On Mon, Jan 25, 2021 at 02:13:44PM +0300, Dan Carpenter wrote:
Smatch complains that "count" is not clamped when "ff->dev_lock_changed" and it leads to an information leak. Fortunately, that's not actually possible and the condition can be deleted.
Signed-off-by: Dan Carpenter dan.carpenter@oracle.com
v2: just delet the condition
sound/firewire/fireface/ff-hwdep.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
Acked-by: Takashi Sakamoto o-takashi@sakamocchi.jp
ALSA firewire stack includes some drivers. Although some of them implement unique event as well as the lock event, the others supports the lock event only. The condition statement comes from the former, I guess. ALSA BeBoB, OXFW, and Fireface drivers are the latter. Later I'll post the similar patch for ALSA BeBoB driver.
Anyway, thank you to find the issue ;)
diff --git a/sound/firewire/fireface/ff-hwdep.c b/sound/firewire/fireface/ff-hwdep.c index 4b2e0dff5ddb..ea64a2a41eea 100644 --- a/sound/firewire/fireface/ff-hwdep.c +++ b/sound/firewire/fireface/ff-hwdep.c @@ -35,13 +35,11 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, }
memset(&event, 0, sizeof(event));
- if (ff->dev_lock_changed) {
event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
event.lock_status.status = (ff->dev_lock_count > 0);
ff->dev_lock_changed = false;
- event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
- event.lock_status.status = (ff->dev_lock_count > 0);
- ff->dev_lock_changed = false;
count = min_t(long, count, sizeof(event.lock_status));
- }
count = min_t(long, count, sizeof(event.lock_status));
spin_unlock_irq(&ff->lock);
-- 2.29.2
Thanks
Takashi Sakamoto
On Mon, 25 Jan 2021 12:13:44 +0100, Dan Carpenter wrote:
Smatch complains that "count" is not clamped when "ff->dev_lock_changed" and it leads to an information leak. Fortunately, that's not actually possible and the condition can be deleted.
Signed-off-by: Dan Carpenter dan.carpenter@oracle.com
v2: just delet the condition
Applied now. Thanks.
Takashi
participants (4)
-
Christophe JAILLET
-
Dan Carpenter
-
Takashi Iwai
-
Takashi Sakamoto