Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock X-Debbugs-Cc: Alois Schlögl <alois.schlo...@gmail.com>, debian-med-packag...@lists.alioth.debian.org
Please unblock package biosig [ Reason ] Upstream wrote: under certain circumstances, save2gdf from biosig-tools crashes, because of memory corruption. Because this bug could be a security issue, it would be great if we could manage to fix this rather sooner than later. see https://alioth-lists.debian.net/pipermail/debian-med-packaging/2021-April/091120.html [ Impact ] biosig might become an intrusion vector due to the security issue [ Tests ] Unfortunately the package has only superficial tests [ Risks ] The package is basically a leaf package and the risk to break anything by the attached patch is low. [ Checklist ] [x] all changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in testing [ Other info ] There was no actual bug filed by upstream who simply has sent a patch via private mail which I forwarded to the maintainer list. unblock biosig/2.1.2-4
diff -Nru biosig-2.1.2/debian/changelog biosig-2.1.2/debian/changelog --- biosig-2.1.2/debian/changelog 2021-01-26 21:47:42.000000000 +0100 +++ biosig-2.1.2/debian/changelog 2021-04-15 21:04:32.000000000 +0200 @@ -1,3 +1,11 @@ +biosig (2.1.2-4) unstable; urgency=medium + + * libbiosig: cherry pick some patches from upstream + - fix EDF-to-GDF conversion for certain files + - fix JSON export when SampleRate is undefined (e.g. Infinity) + + -- Alois Schlögl <alois.schlo...@gmail.com> Thu, 15 Apr 2021 21:04:32 +0200 + biosig (2.1.2-3) unstable; urgency=medium [ Alois Schlögl ] diff -Nru biosig-2.1.2/debian/patches/fix-edf2gdf-and-json-export.patch biosig-2.1.2/debian/patches/fix-edf2gdf-and-json-export.patch --- biosig-2.1.2/debian/patches/fix-edf2gdf-and-json-export.patch 1970-01-01 01:00:00.000000000 +0100 +++ biosig-2.1.2/debian/patches/fix-edf2gdf-and-json-export.patch 2021-04-15 21:04:32.000000000 +0200 @@ -0,0 +1,155 @@ +Date: Thu, 15 Apr 2021 16:11:34 +0200 +From: Alois Schlögl <alois.schlo...@gmail.com> +Description: add missing sanity check on nmemb in fread(..,..,nmemb,..) - this can avoid memory errors in certain files + under certain circumstances, save2gdf from biosig-tools crashes, because of + memory corruption. + Because this bug could be a security issue, it would be great if we could + manage to fix this rather sooner than later. + +diff --git a/biosig4c++/biosig.c b/biosig4c++/biosig.c +index aea7260f..526a8a9b 100644 +--- a/biosig4c++/biosig.c ++++ b/biosig4c++/biosig.c +@@ -4142,7 +4142,8 @@ else if (!strncmp(MODE,"r",1)) { + hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); + hdr->AS.Header = (uint8_t*) realloc(Header1,hdr->HeadLen); + char *Header2 = (char*)hdr->AS.Header+256; +- count += ifread(hdr->AS.Header+count, 1, hdr->HeadLen-count, hdr); ++ if (hdr->HeadLen > count) ++ count += ifread(hdr->AS.Header+count, 1, hdr->HeadLen-count, hdr); + + if (count < hdr->HeadLen) { + biosigERROR(hdr, B4C_INCOMPLETE_FILE, "reading BDF/EDF variable header failed"); +@@ -4275,7 +4276,7 @@ else if (!strncmp(MODE,"r",1)) { + if (Dur==0.0 && FLAG_BUGGY_NEUROLOGGER_EDF) Dur = hdr->SPR/496.0; + hdr->SampleRate = hdr->SPR/Dur; + +- if (VERBOSE_LEVEL>8) fprintf(stdout,"[EDF 220] #=%i SPR=%i\n",(int)iftell(hdr),(int)hdr->SPR); ++ if (VERBOSE_LEVEL>8) fprintf(stdout,"[EDF 220] #=%i SPR=%i Dur=%g\n",(int)iftell(hdr),(int)hdr->SPR, Dur); + + if (hdr->NRec <= 0) { + struct stat FileBuf; +@@ -4547,7 +4548,8 @@ if (VERBOSE_LEVEL>7) fprintf(stdout,"EDF+ event\n\ts1:\t<%s>\n\ts2:\t<%s>\n\ts3: + hdr->HeadLen += 4; + // read header up to nLenght and nID of foreign data section + hdr->AS.Header = (uint8_t*) realloc(hdr->AS.Header, hdr->HeadLen); +- count += ifread(Header1+count, 1, hdr->HeadLen-count, hdr); ++ if (hdr->HeadLen > count) ++ count += ifread(Header1+count, 1, hdr->HeadLen-count, hdr); + uint32_t POS = hdr->HeadLen; + // read "foreign data section" and "per channel data types section" + hdr->HeadLen += leu16p(hdr->AS.Header + hdr->HeadLen-4) - 4; +@@ -4555,7 +4557,8 @@ if (VERBOSE_LEVEL>7) fprintf(stdout,"EDF+ event\n\ts1:\t<%s>\n\ts2:\t<%s>\n\ts3: + // read "foreign data section" and "per channel data types section" + hdr->HeadLen += 4*hdr->NS; + hdr->AS.Header = (uint8_t*)realloc(Header1, hdr->HeadLen+8); +- count += ifread(Header1+POS, 1, hdr->HeadLen-POS, hdr); ++ if (hdr->HeadLen > POS) ++ count += ifread(Header1+POS, 1, hdr->HeadLen-POS, hdr); + + if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s %i/%i %i/%i %i/%i %i/%i %i/%i \n", \ + __FILE__, __LINE__, __func__, \ +@@ -5596,7 +5599,8 @@ fprintf(stdout,"ACQ EVENT: %i POS: %i\n",k,POS); + + hdr->HeadLen = 1024; + hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, hdr->HeadLen); +- count += ifread(hdr->AS.Header+count,1,hdr->HeadLen-count,hdr); ++ if (hdr->HeadLen > count) ++ count += ifread(hdr->AS.Header+count, 1, hdr->HeadLen-count, hdr); + hdr->NS = leu16p(hdr->AS.Header+2); + hdr->NRec = leu32p(hdr->AS.Header+6); + hdr->SPR = leu32p(hdr->AS.Header+10); +@@ -7451,7 +7455,8 @@ if (VERBOSE_LEVEL > 7) fprintf(stdout,"biosig/%s (line %d): #%d label <%s>\n", _ + + /* read file */ + hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,hdr->HeadLen+1); +- count += ifread(hdr->AS.Header+count,1,hdr->HeadLen-count,hdr); ++ if (hdr->HeadLen > count) ++ count += ifread(hdr->AS.Header+count, 1, hdr->HeadLen-count, hdr); + hdr->AS.Header[count]=0; + + } +@@ -14075,7 +14080,8 @@ if (VERBOSE_LEVEL>7) fprintf(stdout, "asprintf_hdr2json: sz=%i\n", (int)sz); + c += sprintf(STR, "\t\"NumberOfRecords\"\t: %i,\n",(int)hdr->NRec); + c += sprintf(STR, "\t\"SamplesPerRecords\"\t: %i,\n",(int)hdr->SPR); + c += sprintf(STR, "\t\"NumberOfSamples\"\t: %i,\n",(int)(hdr->NRec*hdr->SPR)); +- if (!isnan(hdr->SampleRate)) c += sprintf(STR, "\t\"Samplingrate\"\t: %f,\n",hdr->SampleRate); ++ if ((0.0 <= hdr->SampleRate) && (hdr->SampleRate < INFINITY)) ++ c += sprintf(STR, "\t\"Samplingrate\"\t: %f,\n",hdr->SampleRate); + snprintf_gdfdatetime(tmp, 40, hdr->T0); + c += sprintf(STR, "\t\"StartOfRecording\"\t: \"%s\",\n",tmp); + c += sprintf(STR, "\t\"TimezoneMinutesEastOfUTC\"\t: %i,\n", hdr->tzmin); +@@ -14143,15 +14149,16 @@ if (VERBOSE_LEVEL>7) fprintf(stdout, "asprintf_hdr2json: count=%i\n", (int)c); + c += sprintf(STR,"\n\t\t{\n"); + c += sprintf(STR,"\t\t\"ChannelNumber\"\t: %i,\n", (int)k+1); + c += sprintf(STR,"\t\t\"Label\"\t: \"%s\",\n", hc->Label); ++ double fs = hdr->SampleRate * hc->SPR/hdr->SPR; ++ if ((0.0 <= fs) && (fs < INFINITY)) c += sprintf(STR, "\t\t\"Samplingrate\"\t: %f,\n", fs); + if ( hc->Transducer && strlen(hc->Transducer) ) c += sprintf(STR,"\t\t\"Transducer\"\t: \"%s\",\n", hc->Transducer); +- c += sprintf(STR,"\t\t\"PhysicalUnit\"\t: \"%s\",\n", PhysDim3(hc->PhysDimCode)); + if (!isnan(hc->PhysMax)) c += sprintf(STR,"\t\t\"PhysicalMaximum\"\t: %g,\n", hc->PhysMax); + if (!isnan(hc->PhysMin)) c += sprintf(STR,"\t\t\"PhysicalMinimum\"\t: %g,\n", hc->PhysMin); + if (!isnan(hc->DigMax)) c += sprintf(STR,"\t\t\"DigitalMaximum\"\t: %f,\n", hc->DigMax); + if (!isnan(hc->DigMin)) c += sprintf(STR,"\t\t\"DigitalMinimum\"\t: %f,\n", hc->DigMin); + if (!isnan(hc->Cal)) c += sprintf(STR,"\t\t\"scaling\"\t: %g,\n", hc->Cal); + if (!isnan(hc->Off)) c += sprintf(STR,"\t\t\"offset\"\t: %g,\n", hc->Off); +- if (!isnan(hc->TOffset)) c += sprintf(STR,"\t\t\"TimeDelay\"\t: %g,\n", hc->TOffset); ++ if (!isnan(hc->TOffset)) c += sprintf(STR,"\t\t\"TimeDelay\"\t: %g", hc->TOffset); + uint8_t flag = (0 < hc->LowPass && hc->LowPass<INFINITY) | ((0 < hc->HighPass && hc->HighPass<INFINITY)<<1) | ((0 < hc->Notch && hc->Notch<INFINITY)<<2); + if (flag) { + c += sprintf(STR, "\t\t\"Filter\" : {\n"); +@@ -14168,8 +14175,7 @@ if (VERBOSE_LEVEL>7) fprintf(stdout, "asprintf_hdr2json: count=%i\n", (int)c); + if (!isnan(hc->fZ)) c += sprintf(STR, "\t\t\"fZ\"\t: %g,\n", hc->fZ); + break; + } +- double fs = hdr->SampleRate * hc->SPR/hdr->SPR; +- if (!isnan(fs)) c += sprintf(STR, "\t\t\"Samplingrate\"\t: %f", fs); ++ c += sprintf(STR,"\t\t\"PhysicalUnit\"\t: \"%s\"", PhysDim3(hc->PhysDimCode)); + c += sprintf(STR, "\n\t\t}"); // end-of-CHANNEL + } + c += sprintf(STR, "\n\t]"); // end-of-CHANNELS +@@ -14272,7 +14278,8 @@ int fprintf_hdr2json(FILE *fid, HDRTYPE* hdr) + fprintf(fid,"\t\"NumberOfRecords\"\t: %i,\n",(int)hdr->NRec); + fprintf(fid,"\t\"SamplesPerRecords\"\t: %i,\n",(int)hdr->SPR); + fprintf(fid,"\t\"NumberOfSamples\"\t: %i,\n",(int)(hdr->NRec*hdr->SPR)); +- if (!isnan(hdr->SampleRate)) fprintf(fid,"\t\"Samplingrate\"\t: %f,\n",hdr->SampleRate); ++ if ((0.0 <= hdr->SampleRate) && (hdr->SampleRate < INFINITY)) ++ fprintf(fid,"\t\"Samplingrate\"\t: %f,\n", hdr->SampleRate); + + snprintf_gdfdatetime(tmp, 40, hdr->T0); + fprintf(fid,"\t\"StartOfRecording\"\t: \"%s\",\n",tmp); +@@ -14330,8 +14337,9 @@ int fprintf_hdr2json(FILE *fid, HDRTYPE* hdr) + fprintf(fid,"\n\t\t{\n"); + fprintf(fid,"\t\t\"ChannelNumber\"\t: %i,\n", (int)k+1); + fprintf(fid,"\t\t\"Label\"\t: \"%s\",\n", hc->Label); ++ double fs = hdr->SampleRate * hc->SPR/hdr->SPR; ++ if ((0.0 <= fs) && (fs < INFINITY)) fprintf(fid,"\t\t\"Samplingrate\"\t: %f,\n", fs); + if ( hc->Transducer && strlen(hc->Transducer) ) fprintf(fid,"\t\t\"Transducer\"\t: \"%s\",\n", hc->Transducer); +- fprintf(fid,"\t\t\"PhysicalUnit\"\t: \"%s\",\n", PhysDim3(hc->PhysDimCode)); + if (!isnan(hc->PhysMax)) fprintf(fid,"\t\t\"PhysicalMaximum\"\t: %g,\n", hc->PhysMax); + if (!isnan(hc->PhysMin)) fprintf(fid,"\t\t\"PhysicalMinimum\"\t: %g,\n", hc->PhysMin); + if (!isnan(hc->DigMax)) fprintf(fid,"\t\t\"DigitalMaximum\"\t: %f,\n", hc->DigMax); +@@ -14355,8 +14363,7 @@ int fprintf_hdr2json(FILE *fid, HDRTYPE* hdr) + if (!isnan(hc->fZ)) fprintf(fid,"\t\t\"fZ\"\t: %g,\n", hc->fZ); + break; + } +- double fs = hdr->SampleRate * hc->SPR/hdr->SPR; +- if (!isnan(fs)) fprintf(fid,"\t\t\"Samplingrate\"\t: %f", fs); // no comma at the end because its the last element ++ fprintf(fid,"\t\t\"PhysicalUnit\"\t: \"%s\"", PhysDim3(hc->PhysDimCode)); // no comma at the end because its the last element + fprintf(fid,"\n\t\t}"); // end-of-CHANNEL + } + fprintf(fid,"\n\t]"); // end-of-CHANNELS +diff --git a/biosig4c++/t210/sopen_heka_read.c b/biosig4c++/t210/sopen_heka_read.c +index 5fac494c..f00d1321 100644 +--- a/biosig4c++/t210/sopen_heka_read.c ++++ b/biosig4c++/t210/sopen_heka_read.c +@@ -150,7 +150,8 @@ void sopen_heka(HDRTYPE* hdr, FILE *itx) { + struct stat FileBuf; + stat(hdr->FileName,&FileBuf); + hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, FileBuf.st_size); +- count += ifread(hdr->AS.Header+count, 1, 1024-count, hdr); ++ if (count < 1024) ++ count += ifread(hdr->AS.Header+count, 1, 1024-count, hdr); + hdr->HeadLen = count; + + hdr->FILE.LittleEndian = *(uint8_t*)(hdr->AS.Header+52) > 0; diff -Nru biosig-2.1.2/debian/patches/series biosig-2.1.2/debian/patches/series --- biosig-2.1.2/debian/patches/series 2021-01-26 21:47:42.000000000 +0100 +++ biosig-2.1.2/debian/patches/series 2021-04-15 21:04:32.000000000 +0200 @@ -7,3 +7,4 @@ install_strip.patch sopen-add-support-for-timezone-information-in-GDF-files.patch fix-edfannot-issue-eeglab93.patch +fix-edf2gdf-and-json-export.patch