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

Reply via email to