Commit message: Memory Squeezing: LCMS2: CLUTElemDup

Check for allocation failures and tidy up if found.
CVE: CVE-2013-4160
CWE: NVD-CWE-Other
Vulnerability description: Little CMS (lcms2) before 2.5, as used in OpenJDK 7 and possibly other products, allows remote attackers to cause a denial of service (NULL pointer dereference and crash) via vectors related to (1) cmsStageAllocLabV2ToV4curves, (2) cmsPipelineDup, (3) cmsAllocProfileSequenceDescription, (4) CurvesAlloc, and (5) cmsnamed.

Project: Little-CMS
File: cmslut.c

void* CurveSetDup(cmsStage* mpe)
{
    _cmsStageToneCurvesData* Data = (_cmsStageToneCurvesData*) mpe ->Data;
    _cmsStageToneCurvesData* NewElem;
    cmsUInt32Number i;

    NewElem = (_cmsStageToneCurvesData*) _cmsMallocZero(mpe ->ContextID, sizeof(_cmsStageToneCurvesData));
    if (NewElem == NULL) return NULL;

    NewElem ->nCurves   = Data ->nCurves;
    NewElem ->TheCurves = (cmsToneCurve**) _cmsCalloc(mpe ->ContextID, NewElem ->nCurves, sizeof(cmsToneCurve*));

    if (NewElem ->TheCurves == NULL) goto Error;

    for (i=0; i < NewElem ->nCurves; i++) {

        // Duplicate each curve. It may fail.
        NewElem ->TheCurves[i] = cmsDupToneCurve(Data ->TheCurves[i]);
        if (NewElem ->TheCurves[i] == NULL) goto Error;


    }
    return (void*) NewElem;

Error:

    if (NewElem ->TheCurves != NULL) {
        for (i=0; i < NewElem ->nCurves; i++) {
            if (NewElem ->TheCurves[i])
                cmsFreeToneCurve(NewElem ->TheCurves[i]);
        }
    }
    _cmsFree(mpe ->ContextID, NewElem ->TheCurves);
    _cmsFree(mpe ->ContextID, NewElem);
    return NULL;
}

Project: Little-CMS
File: cmslut.c

void* CLUTElemDup(cmsStage* mpe)
{
    _cmsStageCLutData* Data = (_cmsStageCLutData*) mpe ->Data;
    _cmsStageCLutData* NewElem;


    NewElem = (_cmsStageCLutData*) _cmsMallocZero(mpe ->ContextID, sizeof(_cmsStageCLutData));
    if (NewElem == NULL) return NULL;

    NewElem ->nEntries       = Data ->nEntries;
    NewElem ->HasFloatValues = Data ->HasFloatValues;

    if (Data ->Tab.T) {

        if (Data ->HasFloatValues) {
            NewElem ->Tab.TFloat = (cmsFloat32Number*) _cmsDupMem(mpe ->ContextID, Data ->Tab.TFloat, Data ->nEntries * sizeof (cmsFloat32Number));
            if (NewElem ->Tab.TFloat == NULL)
                goto Error;
        } else {
            NewElem ->Tab.T = (cmsUInt16Number*) _cmsDupMem(mpe ->ContextID, Data ->Tab.T, Data ->nEntries * sizeof (cmsUInt16Number));
            if (NewElem ->Tab.TFloat == NULL)
                goto Error;
        }
    }

    NewElem ->Params   = _cmsComputeInterpParamsEx(mpe ->ContextID,
                                                   Data ->Params ->nSamples,
                                                   Data ->Params ->nInputs,
                                                   Data ->Params ->nOutputs,
                                                   NewElem ->Tab.T,
                                                   Data ->Params ->dwFlags);
    if (NewElem->Params != NULL)
        return (void*) NewElem;
 Error:
    if (NewElem->Tab.T)
        // This works for both types
        _cmsFree(mpe ->ContextID, NewElem -> Tab.T);
    _cmsFree(mpe ->ContextID, NewElem);
    return NULL;
}

Project: Little-CMS
File: cmslut.c

cmsStage* CMSEXPORT cmsStageDup(cmsStage* mpe)
{
    cmsStage* NewMPE;

    if (mpe == NULL) return NULL;
    NewMPE = _cmsStageAllocPlaceholder(mpe ->ContextID,
                                     mpe ->Type,
                                     mpe ->InputChannels,
                                     mpe ->OutputChannels,
                                     mpe ->EvalPtr,
                                     mpe ->DupElemPtr,
                                     mpe ->FreePtr,
                                     NULL);
    if (NewMPE == NULL) return NULL;

    NewMPE ->Implements = mpe ->Implements;

    if (mpe ->DupElemPtr) {

        NewMPE ->Data = mpe ->DupElemPtr(mpe);

        if (NewMPE->Data == NULL) {

            cmsStageFree(NewMPE);
            return NULL;
        }

    } else {

        NewMPE ->Data       = NULL;
    }

    return NewMPE;
}