[Debian-med-packaging] Bug#987027: unblock: biosig/2.1.2-4

Andreas Tille tille at debian.org
Thu Apr 15 20:50:02 BST 2021


Package: release.debian.org
Severity: normal
User: release.debian.org at packages.debian.org
Usertags: unblock
X-Debbugs-Cc: Alois Schlögl <alois.schloegl at gmail.com>, debian-med-packaging at 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
-------------- next part --------------
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.schloegl at 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.schloegl at 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


More information about the Debian-med-packaging mailing list