Resolves: rhbz#2210191 CVE-2023-0950 Array Index UnderFlow in Calc Formula Parsing
This commit is contained in:
		
							parent
							
								
									97992112e9
								
							
						
					
					
						commit
						5faf9f0999
					
				@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					From b66d735cf3dc8b80783cb161c0aff5b990db1bb0 Mon Sep 17 00:00:00 2001
 | 
				
			||||||
 | 
					From: Eike Rathke <erack@redhat.com>
 | 
				
			||||||
 | 
					Date: Thu, 16 Feb 2023 20:20:31 +0100
 | 
				
			||||||
 | 
					Subject: [PATCH 1/3] Obtain actual 0-parameter count for OR(), AND() and
 | 
				
			||||||
 | 
					 1-parameter functions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OR and AND for legacy infix notation are classified as binary
 | 
				
			||||||
 | 
					operators but in fact are functions with parameter count. In case
 | 
				
			||||||
 | 
					no argument is supplied, GetByte() returns 0 and for that case the
 | 
				
			||||||
 | 
					implicit binary operator 2 parameters were wrongly assumed.
 | 
				
			||||||
 | 
					Similar for functions expecting 1 parameter, without argument 1
 | 
				
			||||||
 | 
					was assumed. For "real" unary and binary operators the compiler
 | 
				
			||||||
 | 
					already checks parameters. Omit OR and AND and 1-parameter
 | 
				
			||||||
 | 
					functions from this implicit assumption and return the actual 0
 | 
				
			||||||
 | 
					count.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Change-Id: Ie05398c112a98021ac2875cf7b6de994aee9d882
 | 
				
			||||||
 | 
					Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147173
 | 
				
			||||||
 | 
					Reviewed-by: Eike Rathke <erack@redhat.com>
 | 
				
			||||||
 | 
					Tested-by: Jenkins
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(cherry picked from commit e7ce9bddadb2db222eaa5f594ef1de2e36d57e5c)
 | 
				
			||||||
 | 
					Conflicts:
 | 
				
			||||||
 | 
					        sc/source/core/tool/interpr4.cxx
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					 formula/source/core/api/token.cxx | 13 +++++--------
 | 
				
			||||||
 | 
					 sc/source/core/tool/interpr4.cxx  | 10 +++++++++-
 | 
				
			||||||
 | 
					 2 files changed, 14 insertions(+), 9 deletions(-)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
 | 
				
			||||||
 | 
					index 17594207234f..0db0c3464610 100644
 | 
				
			||||||
 | 
					--- a/formula/source/core/api/token.cxx
 | 
				
			||||||
 | 
					+++ b/formula/source/core/api/token.cxx
 | 
				
			||||||
 | 
					@@ -95,17 +95,14 @@ sal_uInt8 FormulaToken::GetParamCount() const
 | 
				
			||||||
 | 
					         return 0;       // parameters and specials
 | 
				
			||||||
 | 
					                         // ocIf... jump commands not for FAP, have cByte then
 | 
				
			||||||
 | 
					 //2do: bool parameter whether FAP or not?
 | 
				
			||||||
 | 
					-    else if ( GetByte() )
 | 
				
			||||||
 | 
					+    else if (GetByte())
 | 
				
			||||||
 | 
					         return GetByte();   // all functions, also ocExternal and ocMacro
 | 
				
			||||||
 | 
					-    else if (SC_OPCODE_START_BIN_OP <= eOp && eOp < SC_OPCODE_STOP_BIN_OP)
 | 
				
			||||||
 | 
					-        return 2;           // binary
 | 
				
			||||||
 | 
					-    else if ((SC_OPCODE_START_UN_OP <= eOp && eOp < SC_OPCODE_STOP_UN_OP)
 | 
				
			||||||
 | 
					-            || eOp == ocPercentSign)
 | 
				
			||||||
 | 
					-        return 1;           // unary
 | 
				
			||||||
 | 
					+    else if (SC_OPCODE_START_BIN_OP <= eOp && eOp < SC_OPCODE_STOP_BIN_OP && eOp != ocAnd && eOp != ocOr)
 | 
				
			||||||
 | 
					+        return 2;           // binary operators, compiler checked; OR and AND legacy but are functions
 | 
				
			||||||
 | 
					+    else if ((SC_OPCODE_START_UN_OP <= eOp && eOp < SC_OPCODE_STOP_UN_OP) || eOp == ocPercentSign)
 | 
				
			||||||
 | 
					+        return 1;           // unary operators, compiler checked
 | 
				
			||||||
 | 
					     else if (SC_OPCODE_START_NO_PAR <= eOp && eOp < SC_OPCODE_STOP_NO_PAR)
 | 
				
			||||||
 | 
					         return 0;           // no parameter
 | 
				
			||||||
 | 
					-    else if (SC_OPCODE_START_1_PAR <= eOp && eOp < SC_OPCODE_STOP_1_PAR)
 | 
				
			||||||
 | 
					-        return 1;           // one parameter
 | 
				
			||||||
 | 
					     else if (FormulaCompiler::IsOpCodeJumpCommand( eOp ))
 | 
				
			||||||
 | 
					         return 1;           // only the condition counts as parameter
 | 
				
			||||||
 | 
					     else
 | 
				
			||||||
 | 
					diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
 | 
				
			||||||
 | 
					index eb3fb987c034..94235c33eaef 100644
 | 
				
			||||||
 | 
					--- a/sc/source/core/tool/interpr4.cxx
 | 
				
			||||||
 | 
					+++ b/sc/source/core/tool/interpr4.cxx
 | 
				
			||||||
 | 
					@@ -4012,7 +4012,15 @@ StackVar ScInterpreter::Interpret()
 | 
				
			||||||
 | 
					                 else if (sp >= pCur->GetParamCount())
 | 
				
			||||||
 | 
					                     nStackBase = sp - pCur->GetParamCount();
 | 
				
			||||||
 | 
					                 else
 | 
				
			||||||
 | 
					-                    nStackBase = sp;    // underflow?!?
 | 
				
			||||||
 | 
					+                {
 | 
				
			||||||
 | 
					+                    SAL_WARN("sc.core", "Stack anomaly at " << aPos.Format(
 | 
				
			||||||
 | 
					+                                ScRefFlags::VALID | ScRefFlags::FORCE_DOC | ScRefFlags::TAB_3D, pDok)
 | 
				
			||||||
 | 
					+                            << "  eOp: " << static_cast<int>(eOp)
 | 
				
			||||||
 | 
					+                            << "  params: " << static_cast<int>(pCur->GetParamCount())
 | 
				
			||||||
 | 
					+                            << "  nStackBase: " << nStackBase << "  sp: " << sp);
 | 
				
			||||||
 | 
					+                    nStackBase = sp;
 | 
				
			||||||
 | 
					+                    assert(!"underflow");
 | 
				
			||||||
 | 
					+                }
 | 
				
			||||||
 | 
					             }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					             switch( eOp )
 | 
				
			||||||
 | 
					-- 
 | 
				
			||||||
 | 
					2.41.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,82 @@
 | 
				
			|||||||
 | 
					From c0e926365dc7651dcb5eee48f50e6990523662ad Mon Sep 17 00:00:00 2001
 | 
				
			||||||
 | 
					From: Eike Rathke <erack@redhat.com>
 | 
				
			||||||
 | 
					Date: Fri, 17 Feb 2023 12:03:54 +0100
 | 
				
			||||||
 | 
					Subject: [PATCH 2/3] Stack check safety belt before fishing in muddy waters
 | 
				
			||||||
 | 
					MIME-Version: 1.0
 | 
				
			||||||
 | 
					Content-Type: text/plain; charset=UTF-8
 | 
				
			||||||
 | 
					Content-Transfer-Encoding: 8bit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Have it hit hard in debug builds.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Change-Id: I9ea54844a0661fd7a75616a2876983a74b2d5bad
 | 
				
			||||||
 | 
					Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147205
 | 
				
			||||||
 | 
					Reviewed-by: Eike Rathke <erack@redhat.com>
 | 
				
			||||||
 | 
					Tested-by: Jenkins
 | 
				
			||||||
 | 
					(cherry picked from commit 9d91fbba6f374fa1c10b38eae003da89bd4e6d4b)
 | 
				
			||||||
 | 
					Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147245
 | 
				
			||||||
 | 
					Reviewed-by: Caolán McNamara <caolanm@redhat.com>
 | 
				
			||||||
 | 
					(cherry picked from commit 166a07062dd4ffedca6106f439a6fcddaeee5eb5)
 | 
				
			||||||
 | 
					Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147391
 | 
				
			||||||
 | 
					Tested-by: Michael Stahl <michael.stahl@allotropia.de>
 | 
				
			||||||
 | 
					Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
 | 
				
			||||||
 | 
					(cherry picked from commit f8efb098f2abbf054a15dcf7daaaacfa575685ae)
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					 sc/source/core/inc/interpre.hxx  | 12 ++++++++++++
 | 
				
			||||||
 | 
					 sc/source/core/tool/interpr1.cxx |  4 ++--
 | 
				
			||||||
 | 
					 2 files changed, 14 insertions(+), 2 deletions(-)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
 | 
				
			||||||
 | 
					index 3b902524d901..c7d4527dbf57 100644
 | 
				
			||||||
 | 
					--- a/sc/source/core/inc/interpre.hxx
 | 
				
			||||||
 | 
					+++ b/sc/source/core/inc/interpre.hxx
 | 
				
			||||||
 | 
					@@ -235,6 +235,7 @@ private:
 | 
				
			||||||
 | 
					     inline bool MustHaveParamCount( short nAct, short nMust );
 | 
				
			||||||
 | 
					     inline bool MustHaveParamCount( short nAct, short nMust, short nMax );
 | 
				
			||||||
 | 
					     inline bool MustHaveParamCountMin( short nAct, short nMin );
 | 
				
			||||||
 | 
					+    inline bool MustHaveParamCountMinWithStackCheck( short nAct, short nMin );
 | 
				
			||||||
 | 
					     void PushParameterExpected();
 | 
				
			||||||
 | 
					     void PushIllegalParameter();
 | 
				
			||||||
 | 
					     void PushIllegalArgument();
 | 
				
			||||||
 | 
					@@ -1086,6 +1087,17 @@ inline bool ScInterpreter::MustHaveParamCountMin( short nAct, short nMin )
 | 
				
			||||||
 | 
					     return false;
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+inline bool ScInterpreter::MustHaveParamCountMinWithStackCheck( short nAct, short nMin )
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+    assert(sp >= nAct);
 | 
				
			||||||
 | 
					+    if (sp < nAct)
 | 
				
			||||||
 | 
					+    {
 | 
				
			||||||
 | 
					+        PushParameterExpected();
 | 
				
			||||||
 | 
					+        return false;
 | 
				
			||||||
 | 
					+    }
 | 
				
			||||||
 | 
					+    return MustHaveParamCountMin( nAct, nMin);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 inline bool ScInterpreter::CheckStringPositionArgument( double & fVal )
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					     if (!rtl::math::isFinite( fVal))
 | 
				
			||||||
 | 
					diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
 | 
				
			||||||
 | 
					index e375f1626ec5..4b093cb62d4f 100644
 | 
				
			||||||
 | 
					--- a/sc/source/core/tool/interpr1.cxx
 | 
				
			||||||
 | 
					+++ b/sc/source/core/tool/interpr1.cxx
 | 
				
			||||||
 | 
					@@ -7524,7 +7524,7 @@ void ScInterpreter::ScVLookup()
 | 
				
			||||||
 | 
					 void ScInterpreter::ScSubTotal()
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					     sal_uInt8 nParamCount = GetByte();
 | 
				
			||||||
 | 
					-    if ( MustHaveParamCountMin( nParamCount, 2 ) )
 | 
				
			||||||
 | 
					+    if ( MustHaveParamCountMinWithStackCheck( nParamCount, 2 ) )
 | 
				
			||||||
 | 
					     {
 | 
				
			||||||
 | 
					         // We must fish the 1st parameter deep from the stack! And push it on top.
 | 
				
			||||||
 | 
					         const FormulaToken* p = pStack[ sp - nParamCount ];
 | 
				
			||||||
 | 
					@@ -7571,7 +7571,7 @@ void ScInterpreter::ScSubTotal()
 | 
				
			||||||
 | 
					 void ScInterpreter::ScAggregate()
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					     sal_uInt8 nParamCount = GetByte();
 | 
				
			||||||
 | 
					-    if ( MustHaveParamCountMin( nParamCount, 3 ) )
 | 
				
			||||||
 | 
					+    if ( MustHaveParamCountMinWithStackCheck( nParamCount, 3 ) )
 | 
				
			||||||
 | 
					     {
 | 
				
			||||||
 | 
					         // fish the 1st parameter from the stack and push it on top.
 | 
				
			||||||
 | 
					         const FormulaToken* p = pStack[ sp - nParamCount ];
 | 
				
			||||||
 | 
					-- 
 | 
				
			||||||
 | 
					2.41.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										50
									
								
								0003-Always-push-a-result-even-if-it-s-only-an-error.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								0003-Always-push-a-result-even-if-it-s-only-an-error.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					From 7e128f02a7cb513e4e57dbb1970fa316f456aa45 Mon Sep 17 00:00:00 2001
 | 
				
			||||||
 | 
					From: Eike Rathke <erack@redhat.com>
 | 
				
			||||||
 | 
					Date: Mon, 27 Feb 2023 16:10:06 +0100
 | 
				
			||||||
 | 
					Subject: [PATCH 3/3] Always push a result, even if it's only an error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PERCENTILE() and QUARTILE() if an error was passed as argument (or
 | 
				
			||||||
 | 
					an error encountered during obtaining arguments) omitted to push
 | 
				
			||||||
 | 
					an error result, only setting the error.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fallout from
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    commit f336f63da900d76c2bf6e5690f1c8a7bd15a0aa2
 | 
				
			||||||
 | 
					    CommitDate: Thu Mar 3 16:28:59 2016 +0000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        tdf#94635 Add FORECAST.ETS functions to Calc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Change-Id: I23e276fb0ce735cfd6383cc963446499dcf819f4
 | 
				
			||||||
 | 
					Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147922
 | 
				
			||||||
 | 
					Reviewed-by: Eike Rathke <erack@redhat.com>
 | 
				
			||||||
 | 
					Tested-by: Jenkins
 | 
				
			||||||
 | 
					(cherry picked from commit 64914560e279c71ff1233f4bab851e2a292797e6)
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					 sc/source/core/tool/interpr3.cxx | 4 ++--
 | 
				
			||||||
 | 
					 1 file changed, 2 insertions(+), 2 deletions(-)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx
 | 
				
			||||||
 | 
					index f219beca9386..d442d4eee224 100644
 | 
				
			||||||
 | 
					--- a/sc/source/core/tool/interpr3.cxx
 | 
				
			||||||
 | 
					+++ b/sc/source/core/tool/interpr3.cxx
 | 
				
			||||||
 | 
					@@ -3474,7 +3474,7 @@ void ScInterpreter::ScPercentile( bool bInclusive )
 | 
				
			||||||
 | 
					     GetNumberSequenceArray( 1, aArray, false );
 | 
				
			||||||
 | 
					     if ( aArray.empty() || nGlobalError != FormulaError::NONE )
 | 
				
			||||||
 | 
					     {
 | 
				
			||||||
 | 
					-        SetError( FormulaError::NoValue );
 | 
				
			||||||
 | 
					+        PushNoValue();
 | 
				
			||||||
 | 
					         return;
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					     if ( bInclusive )
 | 
				
			||||||
 | 
					@@ -3497,7 +3497,7 @@ void ScInterpreter::ScQuartile( bool bInclusive )
 | 
				
			||||||
 | 
					     GetNumberSequenceArray( 1, aArray, false );
 | 
				
			||||||
 | 
					     if ( aArray.empty() || nGlobalError != FormulaError::NONE )
 | 
				
			||||||
 | 
					     {
 | 
				
			||||||
 | 
					-        SetError( FormulaError::NoValue );
 | 
				
			||||||
 | 
					+        PushNoValue();
 | 
				
			||||||
 | 
					         return;
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					     if ( bInclusive )
 | 
				
			||||||
 | 
					-- 
 | 
				
			||||||
 | 
					2.41.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -54,7 +54,7 @@ Summary:        Free Software Productivity Suite
 | 
				
			|||||||
Name:           libreoffice
 | 
					Name:           libreoffice
 | 
				
			||||||
Epoch:          1
 | 
					Epoch:          1
 | 
				
			||||||
Version:        %{libo_version}.2
 | 
					Version:        %{libo_version}.2
 | 
				
			||||||
Release:        14%{?libo_prerelease}%{?dist}
 | 
					Release:        15%{?libo_prerelease}%{?dist}
 | 
				
			||||||
License:        (MPLv1.1 or LGPLv3+) and LGPLv3 and LGPLv2+ and BSD and (MPLv1.1 or GPLv2 or LGPLv2 or Netscape) and Public Domain and ASL 2.0 and MPLv2.0 and CC0
 | 
					License:        (MPLv1.1 or LGPLv3+) and LGPLv3 and LGPLv2+ and BSD and (MPLv1.1 or GPLv2 or LGPLv2 or Netscape) and Public Domain and ASL 2.0 and MPLv2.0 and CC0
 | 
				
			||||||
URL:            http://www.libreoffice.org/
 | 
					URL:            http://www.libreoffice.org/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -286,6 +286,9 @@ Patch42: 0003-CVE-2022-26306-add-Initialization-Vectors-to-passwor.patch
 | 
				
			|||||||
Patch43: 0004-CVE-2022-2630-6-7-add-infobar-to-prompt-to-refresh-t.patch
 | 
					Patch43: 0004-CVE-2022-2630-6-7-add-infobar-to-prompt-to-refresh-t.patch
 | 
				
			||||||
Patch44: 0001-CVE-2022-3140.patch
 | 
					Patch44: 0001-CVE-2022-3140.patch
 | 
				
			||||||
Patch45: 0001-CVE-2022-38745.patch
 | 
					Patch45: 0001-CVE-2022-38745.patch
 | 
				
			||||||
 | 
					Patch46: 0001-Obtain-actual-0-parameter-count-for-OR-AND-and-1-par.patch
 | 
				
			||||||
 | 
					Patch47: 0002-Stack-check-safety-belt-before-fishing-in-muddy-wate.patch
 | 
				
			||||||
 | 
					Patch48: 0003-Always-push-a-result-even-if-it-s-only-an-error.patch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%if 0%{?rhel}
 | 
					%if 0%{?rhel}
 | 
				
			||||||
# not upstreamed
 | 
					# not upstreamed
 | 
				
			||||||
@ -2288,6 +2291,10 @@ done
 | 
				
			|||||||
%{_includedir}/LibreOfficeKit
 | 
					%{_includedir}/LibreOfficeKit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%changelog
 | 
					%changelog
 | 
				
			||||||
 | 
					* Mon Jun 19 2023 Stephan Bergmann <sbergman@redhat.com> - 1:6.4.7.2-15 UNBUILT
 | 
				
			||||||
 | 
					- Resolves: rhbz#2210191 CVE-2023-0950 Array Index UnderFlow in Calc Formula
 | 
				
			||||||
 | 
					  Parsing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Wed Apr 12 2023 Caolán McNamara <caolanm@redhat.com> - 1:6.4.7.2-14
 | 
					* Wed Apr 12 2023 Caolán McNamara <caolanm@redhat.com> - 1:6.4.7.2-14
 | 
				
			||||||
- Resolves: rhbz#2182390 CVE-2022-38745 Empty entry in Java class path
 | 
					- Resolves: rhbz#2182390 CVE-2022-38745 Empty entry in Java class path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user