lkml.org 
[lkml]   [2019]   [Jan]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.20 20/65] ALSA: usb-audio: Check mixer unit descriptors more strictly
    Date
    4.20-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Takashi Iwai <tiwai@suse.de>

    commit 0bfe5e434e6665b3590575ec3c5e4f86a1ce51c9 upstream.

    We've had some sanity checks of the mixer unit descriptors but they
    are too loose and some corner cases are overlooked. Add more strict
    checks in uac_mixer_unit_get_channels() for avoiding possible OOB
    accesses by malformed descriptors.

    This also changes the semantics of uac_mixer_unit_get_channels()
    slightly. Now it returns zero for the cases where the descriptor
    lacks of bmControls instead of -EINVAL. Then the caller side skips
    the mixer creation for such unit while it keeps parsing it.
    This corresponds to the case like Maya44.

    Cc: <stable@vger.kernel.org>
    Signed-off-by: Takashi Iwai <tiwai@suse.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    sound/usb/mixer.c | 15 +++++++++++----
    1 file changed, 11 insertions(+), 4 deletions(-)

    --- a/sound/usb/mixer.c
    +++ b/sound/usb/mixer.c
    @@ -753,8 +753,9 @@ static int uac_mixer_unit_get_channels(s
    struct uac_mixer_unit_descriptor *desc)
    {
    int mu_channels;
    + void *c;

    - if (desc->bLength < 11)
    + if (desc->bLength < sizeof(*desc))
    return -EINVAL;
    if (!desc->bNrInPins)
    return -EINVAL;
    @@ -763,6 +764,8 @@ static int uac_mixer_unit_get_channels(s
    case UAC_VERSION_1:
    case UAC_VERSION_2:
    default:
    + if (desc->bLength < sizeof(*desc) + desc->bNrInPins + 1)
    + return 0; /* no bmControls -> skip */
    mu_channels = uac_mixer_unit_bNrChannels(desc);
    break;
    case UAC_VERSION_3:
    @@ -772,7 +775,11 @@ static int uac_mixer_unit_get_channels(s
    }

    if (!mu_channels)
    - return -EINVAL;
    + return 0;
    +
    + c = uac_mixer_unit_bmControls(desc, state->mixer->protocol);
    + if (c - (void *)desc + (mu_channels - 1) / 8 >= desc->bLength)
    + return 0; /* no bmControls -> skip */

    return mu_channels;
    }
    @@ -944,7 +951,7 @@ static int check_input_term(struct mixer
    struct uac_mixer_unit_descriptor *d = p1;

    err = uac_mixer_unit_get_channels(state, d);
    - if (err < 0)
    + if (err <= 0)
    return err;

    term->channels = err;
    @@ -2118,7 +2125,7 @@ static int parse_audio_mixer_unit(struct
    if (err < 0)
    continue;
    /* no bmControls field (e.g. Maya44) -> ignore */
    - if (desc->bLength <= 10 + input_pins)
    + if (!num_outs)
    continue;
    err = check_input_term(state, desc->baSourceID[pin], &iterm);
    if (err < 0)

    \
     
     \ /
      Last update: 2019-01-11 15:43    [W:3.502 / U:0.176 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site