Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2be5af3d authored by Eric Laurent's avatar Eric Laurent Committed by Sam Lin
Browse files

DO NOT MERGE - IAudioFlinger: add checks on binder calls

Limit number of ports and patches listed by
LIST_AUDIO_PATCHES and LIST_AUDIO_PORTS.

Also fix typo causing wring pointer to be used when writing to Parcel.

Bug: 19573085.
Change-Id: I41a9c710e45738a4f11990160587856c429a4646
(cherry picked from commit 9ef830c6)
parent d7b1b9ad
Loading
Loading
Loading
Loading
+36 −10
Original line number Diff line number Diff line
@@ -83,6 +83,8 @@ enum {
    GET_AUDIO_HW_SYNC
};

#define MAX_ITEMS_PER_LIST 1024

class BpAudioFlinger : public BpInterface<IAudioFlinger>
{
public:
@@ -1289,15 +1291,27 @@ status_t BnAudioFlinger::onTransact(
        } break;
        case LIST_AUDIO_PORTS: {
            CHECK_INTERFACE(IAudioFlinger, data, reply);
            unsigned int num_ports = data.readInt32();
            unsigned int numPortsReq = data.readInt32();
            if (numPortsReq > MAX_ITEMS_PER_LIST) {
                numPortsReq = MAX_ITEMS_PER_LIST;
            }
            unsigned int numPorts = numPortsReq;
            struct audio_port *ports =
                    (struct audio_port *)calloc(num_ports,
                    (struct audio_port *)calloc(numPortsReq,
                                                           sizeof(struct audio_port));
            status_t status = listAudioPorts(&num_ports, ports);
            if (ports == NULL) {
                reply->writeInt32(NO_MEMORY);
                reply->writeInt32(0);
                return NO_ERROR;
            }
            status_t status = listAudioPorts(&numPorts, ports);
            reply->writeInt32(status);
            reply->writeInt32(numPorts);
            if (status == NO_ERROR) {
                reply->writeInt32(num_ports);
                reply->write(&ports, num_ports * sizeof(struct audio_port));
                if (numPortsReq > numPorts) {
                    numPortsReq = numPorts;
                }
                reply->write(ports, numPortsReq * sizeof(struct audio_port));
            }
            free(ports);
            return NO_ERROR;
@@ -1336,15 +1350,27 @@ status_t BnAudioFlinger::onTransact(
        } break;
        case LIST_AUDIO_PATCHES: {
            CHECK_INTERFACE(IAudioFlinger, data, reply);
            unsigned int num_patches = data.readInt32();
            unsigned int numPatchesReq = data.readInt32();
            if (numPatchesReq > MAX_ITEMS_PER_LIST) {
                numPatchesReq = MAX_ITEMS_PER_LIST;
            }
            unsigned int numPatches = numPatchesReq;
            struct audio_patch *patches =
                    (struct audio_patch *)calloc(num_patches,
                    (struct audio_patch *)calloc(numPatchesReq,
                                                 sizeof(struct audio_patch));
            status_t status = listAudioPatches(&num_patches, patches);
            if (patches == NULL) {
                reply->writeInt32(NO_MEMORY);
                reply->writeInt32(0);
                return NO_ERROR;
            }
            status_t status = listAudioPatches(&numPatches, patches);
            reply->writeInt32(status);
            reply->writeInt32(numPatches);
            if (status == NO_ERROR) {
                reply->writeInt32(num_patches);
                reply->write(&patches, num_patches * sizeof(struct audio_patch));
                if (numPatchesReq > numPatches) {
                    numPatchesReq = numPatches;
                }
                reply->write(patches, numPatchesReq * sizeof(struct audio_patch));
            }
            free(patches);
            return NO_ERROR;