Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: fireface: add field for the number of messages copied to user space

Current structure includes no field to express the number of messages
copied to user space, thus user space application needs to information
out of the structure to parse the content of structure.

This commit adds a field to express the number of messages copied to user
space since It is more preferable to use self-contained structure.

Kees Cook proposed an idea of annotation for bound of flexible arrays
in his future improvement for flexible-length array in kernel. The
additional field for message count is suitable to the idea as well.

Reference: https://people.kernel.org/kees/bounded-flexible-arrays-in-c
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Link: https://lore.kernel.org/r/20230202133708.163936-1-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Takashi Sakamoto and committed by
Takashi Iwai
0d9eb7ed d045bcef

+18 -12
+2
include/uapi/sound/firewire.h
··· 78 78 * operating hardware knob. 79 79 * 80 80 * @type: Fixed to SNDRV_FIREWIRE_EVENT_FF400_MESSAGE. 81 + * @message_count: The number of messages. 81 82 * @messages.message: The messages expressing hardware knob operation. 82 83 * @messages.tstamp: The isochronous cycle at which the request subaction of asynchronous 83 84 * transaction was sent to deliver the message. It has 16 bit unsigned integer ··· 90 89 */ 91 90 struct snd_firewire_event_ff400_message { 92 91 unsigned int type; 92 + unsigned int message_count; 93 93 struct { 94 94 __u32 message; 95 95 __u32 tstamp;
+16 -12
sound/firewire/fireface/ff-protocol-former.c
··· 677 677 678 678 static long ff400_copy_msg_to_user(struct snd_ff *ff, char __user *buf, long count) 679 679 { 680 + struct snd_firewire_event_ff400_message ev = { 681 + .type = SNDRV_FIREWIRE_EVENT_FF400_MESSAGE, 682 + .message_count = 0, 683 + }; 680 684 struct ff400_msg_parser *parser = ff->msg_parser; 681 - u32 type = SNDRV_FIREWIRE_EVENT_FF400_MESSAGE; 682 685 long consumed = 0; 683 - int ret = 0; 686 + long ret = 0; 684 687 685 - if (count < 8) 688 + if (count < sizeof(ev) || parser->pull_pos == parser->push_pos) 686 689 return 0; 687 690 688 - spin_unlock_irq(&ff->lock); 689 - if (copy_to_user(buf, &type, sizeof(type))) 690 - ret = -EFAULT; 691 - spin_lock_irq(&ff->lock); 692 - if (ret) 693 - return ret; 694 - 695 - count -= sizeof(type); 696 - consumed += sizeof(type); 691 + count -= sizeof(ev); 692 + consumed += sizeof(ev); 697 693 698 694 while (count >= sizeof(*parser->msgs) && parser->pull_pos != parser->push_pos) { 699 695 spin_unlock_irq(&ff->lock); ··· 703 707 ++parser->pull_pos; 704 708 if (parser->pull_pos >= FF400_QUEUE_SIZE) 705 709 parser->pull_pos = 0; 710 + ++ev.message_count; 706 711 count -= sizeof(*parser->msgs); 707 712 consumed += sizeof(*parser->msgs); 708 713 } 714 + 715 + spin_unlock_irq(&ff->lock); 716 + if (copy_to_user(buf, &ev, sizeof(ev))) 717 + ret = -EFAULT; 718 + spin_lock_irq(&ff->lock); 719 + if (ret) 720 + return ret; 709 721 710 722 return consumed; 711 723 }