[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#865355: stretch-pu: package libopenmpt/0.2.7386~beta20.3-3+deb9u1



Package: release.debian.org
Severity: normal
Tags: stretch
User: release.debian.org@packages.debian.org
Usertags: pu

Hi,

This update contains a number of security fixes to libopenmpt which
upstream has specifically asked me to get into stretch. Upstream asked
me to fix these earlier this month and since none of them looked
"critical" I decided to wait and file a stretch-pu bug (although maybe I
was a little lazy...) The worst bugs fixed here are NULL pointer
dereferences - I don't think there is any remote code execution here.

Upstream kindly backported all the fixes to the version Debian has in
stretch and they were taken from this announcement:
https://lib.openmpt.org/libopenmpt/md_announce-2017-06-02.html

I omitted 2 patches which seem to be impossible to exploit or which only
have minor cosmetic effects.

Debdiff attached.

Thanks,
James

-- System Information:
Debian Release: 9.0
  APT prefers unstable-debug
  APT policy: (500, 'unstable-debug'), (500, 'unstable'), (500,
'testing'), (1, 'experimental-debug'), (1, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 4.9.0-2-amd64 (SMP w/8 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8),
LANGUAGE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
diff -Nru libopenmpt-0.2.7386~beta20.3/debian/changelog libopenmpt-0.2.7386~beta20.3/debian/changelog
--- libopenmpt-0.2.7386~beta20.3/debian/changelog	2017-01-12 17:17:13.000000000 +0000
+++ libopenmpt-0.2.7386~beta20.3/debian/changelog	2017-06-20 08:58:50.000000000 +0100
@@ -1,3 +1,14 @@
+libopenmpt (0.2.7386~beta20.3-3+deb9u1) stretch; urgency=medium
+
+  * Add various security patches (Closes: #864195).
+    - up1: Division by zero in temp calculation.
+    - up2: Infinite loop with cyclic plugin routing.
+    - up3: Excessive CPU consumption on malformed DMF and MDL files.
+    - up5: Excessive CPU consumption on malformed AMS files.
+    - up6: Invalid memory read when applying NNAs to effect plugins.
+
+ -- James Cowgill <jcowgill@debian.org>  Tue, 20 Jun 2017 08:58:50 +0100
+
 libopenmpt (0.2.7386~beta20.3-3) unstable; urgency=medium
 
   * debian/tests:
diff -Nru libopenmpt-0.2.7386~beta20.3/debian/patches/series libopenmpt-0.2.7386~beta20.3/debian/patches/series
--- libopenmpt-0.2.7386~beta20.3/debian/patches/series	2017-01-12 17:09:08.000000000 +0000
+++ libopenmpt-0.2.7386~beta20.3/debian/patches/series	2017-06-20 08:58:50.000000000 +0100
@@ -1 +1,6 @@
 01_libmodplug_symver.patch
+up1-division-by-zero-in-tempo-calculation.patch
+up2-infinite-loop-in-plugin-routing.patch
+up3-excessive-cpu-consumption-on-malformed-files-dmf-mdl.patch
+up5-excessive-cpu-consumption-on-malformed-files-ams.patch
+up6-invalid-memory-read-when-applying-nnas-to-effect-plugins.patch
diff -Nru libopenmpt-0.2.7386~beta20.3/debian/patches/up1-division-by-zero-in-tempo-calculation.patch libopenmpt-0.2.7386~beta20.3/debian/patches/up1-division-by-zero-in-tempo-calculation.patch
--- libopenmpt-0.2.7386~beta20.3/debian/patches/up1-division-by-zero-in-tempo-calculation.patch	1970-01-01 01:00:00.000000000 +0100
+++ libopenmpt-0.2.7386~beta20.3/debian/patches/up1-division-by-zero-in-tempo-calculation.patch	2017-06-20 08:58:50.000000000 +0100
@@ -0,0 +1,51 @@
+Description: Guard against division by zero in tempo calculation
+ See https://lib.openmpt.org/libopenmpt/md_announce-2017-06-02.html
+Origin: upstream, https://source.openmpt.org/browse/openmpt?op=revision&rev=8235
+Bug-Debian: https://bugs.debian.org/864195
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/soundlib/Sndfile.cpp
++++ b/soundlib/Sndfile.cpp
+@@ -1542,15 +1542,15 @@ void CSoundFile::RecalculateSamplesPerTi
+ 	{
+ 	case tempoModeClassic:
+ 	default:
+-		m_PlayState.m_nSamplesPerTick = Util::muldiv(m_MixerSettings.gdwMixingFreq, 5 * TEMPO::fractFact, m_PlayState.m_nMusicTempo.GetRaw() << 1);
++		m_PlayState.m_nSamplesPerTick = Util::muldiv(m_MixerSettings.gdwMixingFreq, 5 * TEMPO::fractFact, std::max(TEMPO::store_t(1), m_PlayState.m_nMusicTempo.GetRaw() << 1));
+ 		break;
+ 
+ 	case tempoModeModern:
+-		m_PlayState.m_nSamplesPerTick = static_cast<uint32>((Util::mul32to64_unsigned(m_MixerSettings.gdwMixingFreq, 60 * TEMPO::fractFact) * Util::mul32to64_unsigned(m_PlayState.m_nMusicSpeed, m_PlayState.m_nCurrentRowsPerBeat)) / m_PlayState.m_nMusicTempo.GetRaw());
++		m_PlayState.m_nSamplesPerTick = static_cast<uint32>((Util::mul32to64_unsigned(m_MixerSettings.gdwMixingFreq, 60 * TEMPO::fractFact) / std::max(uint64(1),  Util::mul32to64_unsigned(m_PlayState.m_nMusicSpeed, m_PlayState.m_nCurrentRowsPerBeat) * m_PlayState.m_nMusicTempo.GetRaw())));
+ 		break;
+ 
+ 	case tempoModeAlternative:
+-		m_PlayState.m_nSamplesPerTick = Util::muldiv(m_MixerSettings.gdwMixingFreq, TEMPO::fractFact, m_PlayState.m_nMusicTempo.GetRaw());
++		m_PlayState.m_nSamplesPerTick = Util::muldiv(m_MixerSettings.gdwMixingFreq, TEMPO::fractFact, std::max(TEMPO::store_t(1), m_PlayState.m_nMusicTempo.GetRaw()));
+ 		break;
+ 	}
+ #ifndef MODPLUG_TRACKER
+@@ -1572,11 +1572,11 @@ uint32 CSoundFile::GetTickDuration(PlayS
+ 	{
+ 	case tempoModeClassic:
+ 	default:
+-		retval = Util::muldiv(m_MixerSettings.gdwMixingFreq, 5 * TEMPO::fractFact, playState.m_nMusicTempo.GetRaw() << 1);
++		retval = Util::muldiv(m_MixerSettings.gdwMixingFreq, 5 * TEMPO::fractFact, std::max(TEMPO::store_t(1), playState.m_nMusicTempo.GetRaw() << 1));
+ 		break;
+ 
+ 	case tempoModeAlternative:
+-		retval = Util::muldiv(m_MixerSettings.gdwMixingFreq, TEMPO::fractFact, playState.m_nMusicTempo.GetRaw());
++		retval = Util::muldiv(m_MixerSettings.gdwMixingFreq, TEMPO::fractFact, std::max(TEMPO::store_t(1), playState.m_nMusicTempo.GetRaw()));
+ 		break;
+ 
+ 	case tempoModeModern:
+--- a/soundlib/Snd_defs.h
++++ b/soundlib/Snd_defs.h
+@@ -481,6 +481,7 @@ protected:
+ 
+ public:
+ 	static const size_t fractFact = FFact;
++	typedef T store_t;
+ 
+ 	FPInt() : v(0) { }
+ 	FPInt(const FPInt<fractFact, T> &other) : v(other.v) { }
diff -Nru libopenmpt-0.2.7386~beta20.3/debian/patches/up2-infinite-loop-in-plugin-routing.patch libopenmpt-0.2.7386~beta20.3/debian/patches/up2-infinite-loop-in-plugin-routing.patch
--- libopenmpt-0.2.7386~beta20.3/debian/patches/up2-infinite-loop-in-plugin-routing.patch	1970-01-01 01:00:00.000000000 +0100
+++ libopenmpt-0.2.7386~beta20.3/debian/patches/up2-infinite-loop-in-plugin-routing.patch	2017-06-20 08:58:50.000000000 +0100
@@ -0,0 +1,22 @@
+Description: Fix infinite loop with cyclic plugin routing
+ See https://lib.openmpt.org/libopenmpt/md_announce-2017-06-02.html
+Origin: upstream, https://source.openmpt.org/browse/openmpt?op=revision&rev=8236
+Bug-Debian: https://bugs.debian.org/864195
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/soundlib/Fastmix.cpp
++++ b/soundlib/Fastmix.cpp
+@@ -597,10 +597,11 @@ void CSoundFile::ProcessPlugins(uint32 n
+ 					// Samples or plugins are being rendered, so turn off auto-bypass for this master effect.
+ 					if(plugin.pMixPlugin != nullptr) plugin.pMixPlugin->ResetSilence();
+ 					SNDMIXPLUGIN *chain = &plugin;
+-					PLUGINDEX out = chain->GetOutputPlugin();
+-					while(out > plug && out < MAX_MIXPLUGINS)
++					PLUGINDEX out = chain->GetOutputPlugin(), prevOut = plug;
++					while(out > prevOut && out < MAX_MIXPLUGINS)
+ 					{
+ 						chain = &m_MixPlugins[out];
++						prevOut = out;
+ 						out = chain->GetOutputPlugin();
+ 						if(chain->pMixPlugin)
+ 						{
diff -Nru libopenmpt-0.2.7386~beta20.3/debian/patches/up3-excessive-cpu-consumption-on-malformed-files-dmf-mdl.patch libopenmpt-0.2.7386~beta20.3/debian/patches/up3-excessive-cpu-consumption-on-malformed-files-dmf-mdl.patch
--- libopenmpt-0.2.7386~beta20.3/debian/patches/up3-excessive-cpu-consumption-on-malformed-files-dmf-mdl.patch	1970-01-01 01:00:00.000000000 +0100
+++ libopenmpt-0.2.7386~beta20.3/debian/patches/up3-excessive-cpu-consumption-on-malformed-files-dmf-mdl.patch	2017-06-20 08:58:50.000000000 +0100
@@ -0,0 +1,351 @@
+Description: Fix excessive CPU consumption on malformed DMF and MDL files
+ See https://lib.openmpt.org/libopenmpt/md_announce-2017-06-02.html
+ This patch prevents loading of DMF and MDL modules taking multiple minutes if
+ the module contains truncated compressed samples.
+Origin: upstream, https://source.openmpt.org/browse/openmpt?op=revision&rev=8237
+Bug-Debian: https://bugs.debian.org/864195
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/soundlib/Load_dmf.cpp
++++ b/soundlib/Load_dmf.cpp
+@@ -16,6 +16,7 @@
+ #include "stdafx.h"
+ #include "Loaders.h"
+ #include "ChunkReader.h"
++#include <stdexcept>
+ 
+ OPENMPT_NAMESPACE_BEGIN
+ 
+@@ -1087,68 +1088,66 @@ struct DMFHTree
+ 	int bitnum;
+ 	int lastnode, nodecount;
+ 	DMFHNode nodes[256];
+-};
+-
+ 
+-// DMF Huffman ReadBits
+-static uint8 DMFReadBits(DMFHTree *tree, uint32 nbits)
+-//----------------------------------------------------
+-{
+-	uint8 x = 0, bitv = 1;
+-	while(nbits--)
++	// DMF Huffman ReadBits
++	uint8 DMFReadBits(int nbits)
+ 	{
+-		if (tree->bitnum)
+-		{
+-			tree->bitnum--;
+-		} else
++		if(bitnum < nbits)
+ 		{
+-			tree->bitbuf = (tree->ibuf < tree->ibufmax) ? *(tree->ibuf++) : 0;
+-			tree->bitnum = 7;
++			if(ibuf < ibufmax)
++			{
++				bitbuf |= (((uint32)(*ibuf++)) << bitnum);
++				bitnum += 8;
++			} else
++			{
++				throw std::range_error("Truncated DMF sample block");
++			}
+ 		}
+-		if (tree->bitbuf & 1) x |= bitv;
+-		bitv <<= 1;
+-		tree->bitbuf >>= 1;
++
++		uint8 v = static_cast<uint8>(bitbuf & ((1 << nbits) - 1));
++		bitbuf >>= nbits;
++		bitnum -= nbits;
++		return v;
+ 	}
+-	return x;
+-}
+ 
+-//
+-// tree: [8-bit value][12-bit index][12-bit index] = 32-bit
+-//
+ 
+-static void DMFNewNode(DMFHTree *tree)
+-//------------------------------------
+-{
+-	uint8 isleft, isright;
+-	int actnode;
+-
+-	actnode = tree->nodecount;
+-	if (actnode > 255) return;
+-	tree->nodes[actnode].value = DMFReadBits(tree, 7);
+-	isleft = DMFReadBits(tree, 1);
+-	isright = DMFReadBits(tree, 1);
+-	actnode = tree->lastnode;
+-	if (actnode > 255) return;
+-	tree->nodecount++;
+-	tree->lastnode = tree->nodecount;
+-	if(isleft)
+-	{
+-		tree->nodes[actnode].left = (int16)tree->lastnode;
+-		DMFNewNode(tree);
+-	} else
+-	{
+-		tree->nodes[actnode].left = -1;
+-	}
+-	tree->lastnode = tree->nodecount;
+-	if(isright)
+-	{
+-		tree->nodes[actnode].right = (int16)tree->lastnode;
+-		DMFNewNode(tree);
+-	} else
+-	{
+-		tree->nodes[actnode].right = -1;
++	//
++	// tree: [8-bit value][12-bit index][12-bit index] = 32-bit
++	//
++
++	void DMFNewNode()
++	{
++		uint8 isleft, isright;
++		int actnode;
++
++		actnode = nodecount;
++		if(actnode > 255) return;
++		nodes[actnode].value = DMFReadBits(7);
++		isleft = DMFReadBits(1);
++		isright = DMFReadBits(1);
++		actnode = lastnode;
++		if(actnode > 255) return;
++		nodecount++;
++		lastnode = nodecount;
++		if(isleft)
++		{
++			nodes[actnode].left = (int16)lastnode;
++			DMFNewNode();
++		} else
++		{
++			nodes[actnode].left = -1;
++		}
++		lastnode = nodecount;
++		if(isright)
++		{
++			nodes[actnode].right = (int16)lastnode;
++			DMFNewNode();
++		} else
++		{
++			nodes[actnode].right = -1;
++		}
+ 	}
+-}
++};
+ 
+ 
+ uintptr_t DMFUnpack(uint8 *psample, const uint8 *ibuf, const uint8 *ibufmax, uint32 maxlen)
+@@ -1159,30 +1158,32 @@ uintptr_t DMFUnpack(uint8 *psample, cons
+ 	MemsetZero(tree);
+ 	tree.ibuf = ibuf;
+ 	tree.ibufmax = ibufmax;
+-	DMFNewNode(&tree);
++	tree.DMFNewNode();
+ 	uint8 value = 0, delta = 0;
+ 
+-	for(uint32 i = 0; i < maxlen; i++)
++	try
+ 	{
+-		int actnode = 0;
+-		uint8 sign = DMFReadBits(&tree, 1);
+-		do
+-		{
+-			if(DMFReadBits(&tree, 1))
+-				actnode = tree.nodes[actnode].right;
+-			else
+-				actnode = tree.nodes[actnode].left;
+-			if(actnode > 255) break;
+-			delta = tree.nodes[actnode].value;
+-			if((tree.ibuf >= tree.ibufmax) && (!tree.bitnum)) break;
+-		} while ((tree.nodes[actnode].left >= 0) && (tree.nodes[actnode].right >= 0));
+-		if(sign) delta ^= 0xFF;
+-		value += delta;
+-		psample[i] = (i) ? value : 0;
++		for(uint32 i = 0; i < maxlen; i++)
++		{
++			int actnode = 0;
++			uint8 sign = tree.DMFReadBits(1);
++			do
++			{
++				if(tree.DMFReadBits(1))
++					actnode = tree.nodes[actnode].right;
++				else
++					actnode = tree.nodes[actnode].left;
++				if(actnode > 255) break;
++				delta = tree.nodes[actnode].value;
++			} while((tree.nodes[actnode].left >= 0) && (tree.nodes[actnode].right >= 0));
++			if(sign) delta ^= 0xFF;
++			value += delta;
++			psample[i] = value;
++		}
++	} catch(const std::range_error &)
++	{
++		//AddToLog(LogWarning, "Truncated DMF sample block");
+ 	}
+-#ifdef DMFLOG
+-//	Log("DMFUnpack: %d remaining bytes\n", tree.ibufmax-tree.ibuf);
+-#endif
+ 	return tree.ibuf - ibuf;
+ }
+ 
+--- a/soundlib/SampleIO.cpp
++++ b/soundlib/SampleIO.cpp
+@@ -19,13 +19,14 @@
+ #ifndef MODPLUG_NO_FILESAVE
+ #include "../common/mptFileIO.h"
+ #endif
++#include <stdexcept>
+ 
+ 
+ OPENMPT_NAMESPACE_BEGIN
+ 
+ // Sample decompression routines in other source files
+ void AMSUnpack(const int8 * const source, size_t sourceSize, void * const dest, const size_t destSize, char packCharacter);
+-uint16 MDLReadBits(uint32 &bitbuf, uint32 &bitnum, const uint8 *(&ibuf), size_t &bytesLeft, int8 n);
++uint8 MDLReadBits(uint32 &bitbuf, int32 &bitnum, const uint8 *(&ibuf), size_t &bytesLeft, int8 n);
+ uintptr_t DMFUnpack(uint8 *psample, const uint8 *ibuf, const uint8 *ibufmax, uint32 maxlen);
+ 
+ 
+@@ -133,48 +134,61 @@ size_t SampleIO::ReadSample(ModSample &s
+ 	} else if(GetEncoding() == MDL && GetChannelFormat() == mono && GetBitDepth() <= 16)
+ 	{
+ 		// Huffman MDL compressed samples
+-		fileSize = file.ReadUint32LE();
+-		FileReader chunk = file.ReadChunk(fileSize);
+-		bytesRead = chunk.GetLength() + 4;
+-		if(chunk.CanRead(4))
++		if(file.CanRead(8) && (fileSize = file.ReadUint32LE()) >= 4)
+ 		{
+-			uint32 bitBuf = chunk.ReadUint32LE(), bitNum = 32;
++			FileReader chunk = file.ReadChunk(fileSize);
++			bytesRead = chunk.GetLength() + 4;
++			uint32 bitBuf = chunk.ReadUint32LE();
++			int32 bitNum = 32;
+ 
+ 			restrictedSampleDataView = chunk.GetPinnedRawDataView();
+ 			sourceBuf = restrictedSampleDataView.data();
+ 
+ 			const uint8 *inBuf = reinterpret_cast<const uint8*>(sourceBuf);
+-			size_t bytesLeft = chunk.GetLength() - 4;
++			size_t bytesLeft = chunk.BytesLeft();
+ 
+ 			uint8 dlt = 0, lowbyte = 0;
+-			const bool _16bit = GetBitDepth() == 16;
+-			for(SmpLength j = 0; j < sample.nLength; j++)
++			const bool is16bit = GetBitDepth() == 16;
++			try
+ 			{
+-				uint8 hibyte;
+-				uint8 sign;
+-				if(_16bit)
++				for(SmpLength j = 0; j < sample.nLength; j++)
+ 				{
+-					lowbyte = static_cast<uint8>(MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 8));
+-				}
+-				sign = static_cast<uint8>(MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 1));
+-				if (MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 1))
+-				{
+-					hibyte = static_cast<uint8>(MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 3));
+-				} else
+-				{
+-					hibyte = 8;
+-					while (!MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 1)) hibyte += 0x10;
+-					hibyte += static_cast<uint8>(MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 4));
+-				}
+-				if (sign) hibyte = ~hibyte;
+-				dlt += hibyte;
+-				if(!_16bit)
+-				{
+-					sample.pSample8[j] = dlt;
+-				} else
+-				{
+-					sample.pSample16[j] = lowbyte | (dlt << 8);
++					uint8 hibyte;
++					if(is16bit)
++					{
++						lowbyte = MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 8);
++					}
++					bool sign = MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 1) != 0;
++					if(MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 1))
++					{
++						hibyte = MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 3);
++					} else
++					{
++						hibyte = 8;
++						while(!MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 1))
++						{
++							hibyte += 0x10;
++						}
++						hibyte += MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 4);
++					}
++					if(sign)
++					{
++						hibyte = ~hibyte;
++					}
++					dlt += hibyte;
++					if(!is16bit)
++					{
++						sample.pSample8[j] = dlt;
++					}
++					else
++					{
++						sample.pSample16[j] = lowbyte | (dlt << 8);
++					}
+ 				}
++			} catch(const std::range_error &)
++			{
++				// Data is not sufficient to decode the whole sample
++				//AddToLog(LogWarning, "Truncated MDL sample block");
+ 			}
+ 		}
+ 	} else if(GetEncoding() == DMF && GetChannelFormat() == mono && GetBitDepth() <= 16)
+--- a/soundlib/Load_mdl.cpp
++++ b/soundlib/Load_mdl.cpp
+@@ -12,6 +12,8 @@
+ #include "Loaders.h"
+ #include "ChunkReader.h"
+ 
++#include <stdexcept>
++
+ OPENMPT_NAMESPACE_BEGIN
+ 
+ #ifdef NEEDS_PRAGMA_PACK
+@@ -933,23 +935,25 @@ bool CSoundFile::ReadMDL(FileReader &fil
+ // MDL Sample Unpacking
+ 
+ // MDL Huffman ReadBits compression
+-uint16 MDLReadBits(uint32 &bitbuf, uint32 &bitnum, const uint8 *(&ibuf), size_t &bytesLeft, int8 n)
+-//-------------------------------------------------------------------------------------------------
++uint8 MDLReadBits(uint32 &bitbuf, int32 &bitnum, const uint8 *(&ibuf), size_t &bytesLeft, int8 n)
++//-----------------------------------------------------------------------------------------------
+ {
+-	uint16 v = (uint16)(bitbuf & ((1 << n) - 1) );
+-	bitbuf >>= n;
+-	bitnum -= n;
+-	if (bitnum <= 24)
++	if(bitnum < n)
+ 	{
+-		if(!bytesLeft)
++		if(bytesLeft)
+ 		{
++			bitbuf |= (((uint32)(*ibuf++)) << bitnum);
+ 			bitnum += 8;
+-			return uint16_max;
++			bytesLeft--;
++		} else
++		{
++			throw std::range_error("Truncated MDL sample block");
+ 		}
+-		bitbuf |= (((uint32)(*ibuf++)) << bitnum);
+-		bitnum += 8;
+-		bytesLeft--;
+ 	}
++
++	uint8 v = static_cast<uint8>(bitbuf & ((1 << n) - 1));
++	bitbuf >>= n;
++	bitnum -= n;
+ 	return v;
+ }
+ 
diff -Nru libopenmpt-0.2.7386~beta20.3/debian/patches/up5-excessive-cpu-consumption-on-malformed-files-ams.patch libopenmpt-0.2.7386~beta20.3/debian/patches/up5-excessive-cpu-consumption-on-malformed-files-ams.patch
--- libopenmpt-0.2.7386~beta20.3/debian/patches/up5-excessive-cpu-consumption-on-malformed-files-ams.patch	1970-01-01 01:00:00.000000000 +0100
+++ libopenmpt-0.2.7386~beta20.3/debian/patches/up5-excessive-cpu-consumption-on-malformed-files-ams.patch	2017-06-20 08:58:50.000000000 +0100
@@ -0,0 +1,45 @@
+Description: Fix excessive CPU consumption on malformed AMS files
+ See https://lib.openmpt.org/libopenmpt/md_announce-2017-06-02.html
+ This patch prevents loading of AMS modules taking multiple minutes if the
+ module contains truncated samples.
+Origin: upstream, https://source.openmpt.org/browse/openmpt?op=revision&rev=8239
+Bug-Debian: https://bugs.debian.org/864195
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/soundlib/Load_ams.cpp
++++ b/soundlib/Load_ams.cpp
+@@ -1024,6 +1024,7 @@ void AMSUnpack(const int8 * const source
+ //------------------------------------------------------------------------------------------------------------------------
+ {
+ 	std::vector<int8> tempBuf(destSize, 0);
++	size_t depackSize = destSize;
+ 
+ 	// Unpack Loop
+ 	{
+@@ -1058,6 +1059,8 @@ void AMSUnpack(const int8 * const source
+ 				j--;
+ 			}
+ 		}
++		// j should only be non-zero for truncated samples
++		depackSize -= j;
+ 	}
+ 
+ 	// Bit Unpack Loop
+@@ -1066,7 +1069,7 @@ void AMSUnpack(const int8 * const source
+ 		uint16 bitcount = 0x80;
+ 		size_t k = 0;
+ 		uint8 *dst = static_cast<uint8 *>(dest);
+-		for(size_t i = 0; i < destSize; i++)
++		for(size_t i = 0; i < depackSize; i++)
+ 		{
+ 			uint8 al = *out++;
+ 			uint16 dh = 0;
+@@ -1090,7 +1093,7 @@ void AMSUnpack(const int8 * const source
+ 	{
+ 		int8 old = 0;
+ 		int8 *out = static_cast<int8 *>(dest);
+-		for(size_t i = destSize; i != 0; i--)
++		for(size_t i = depackSize; i != 0; i--)
+ 		{
+ 			int pos = *reinterpret_cast<uint8 *>(out);
+ 			if(pos != 128 && (pos & 0x80) != 0)
diff -Nru libopenmpt-0.2.7386~beta20.3/debian/patches/up6-invalid-memory-read-when-applying-nnas-to-effect-plugins.patch libopenmpt-0.2.7386~beta20.3/debian/patches/up6-invalid-memory-read-when-applying-nnas-to-effect-plugins.patch
--- libopenmpt-0.2.7386~beta20.3/debian/patches/up6-invalid-memory-read-when-applying-nnas-to-effect-plugins.patch	1970-01-01 01:00:00.000000000 +0100
+++ libopenmpt-0.2.7386~beta20.3/debian/patches/up6-invalid-memory-read-when-applying-nnas-to-effect-plugins.patch	2017-06-20 08:58:50.000000000 +0100
@@ -0,0 +1,22 @@
+Description: Fix invalid memory read when applying NNAs to effect plugins
+ See https://lib.openmpt.org/libopenmpt/md_announce-2017-06-02.html
+Origin: upstream, https://source.openmpt.org/browse/openmpt?op=revision&rev=8240
+Bug: https://bugs.openmpt.org/view.php?id=951
+Bug-Debian: https://bugs.debian.org/864195
+
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/soundlib/Snd_fx.cpp
++++ b/soundlib/Snd_fx.cpp
+@@ -2053,9 +2053,9 @@ CHANNELINDEX CSoundFile::CheckNNA(CHANNE
+ 				// (and if it is playing a note, we know that would be the last note played on this chan).
+ 				ModCommand::NOTE note = pChn->nNote;
+ 				// Caution: When in compatible mode, ModChannel::nNote stores the "real" note, not the mapped note!
+-				if(m_playBehaviour[kITRealNoteMapping] && note < CountOf(pChn->pModInstrument->NoteMap))
++				if(m_playBehaviour[kITRealNoteMapping] && note < CountOf(p->pModInstrument->NoteMap))
+ 				{
+-					note = pChn->pModInstrument->NoteMap[note - 1];
++					note = p->pModInstrument->NoteMap[note - 1];
+ 				}
+ 				applyNNAtoPlug = pPlugin->IsNotePlaying(note, GetBestMidiChannel(nChn), nChn);
+ 			}

Attachment: signature.asc
Description: OpenPGP digital signature


Reply to: