File CVE-2025-68156-limit-recursion-depth.patch of Package coredns-for-k8s1.33

From 2a07330648d2f827f92a95b4c9976d0c4f971ee6 Mon Sep 17 00:00:00 2001
From: Ville Vesilehto <ville@vesilehto.fi>
Date: Wed, 3 Dec 2025 14:29:38 +0200
Subject: [PATCH] fix(builtin): limit recursion depth

Add builtin.MaxDepth (default 10k) to prevent stack overflows when
processing deeply nested or cyclic structures in builtin functions.
The functions flatten, min, max, mean, and median now return a
"recursion depth exceeded" error instead of crashing the runtime.

Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
---
 builtin/builtin.go      | 18 +++++---
 builtin/builtin_test.go | 97 +++++++++++++++++++++++++++++++++++++++++
 builtin/lib.go          | 33 ++++++++++----
 3 files changed, 134 insertions(+), 14 deletions(-)

Index: coredns-1.12.0/vendor/github.com/expr-lang/expr/builtin/lib.go
===================================================================
--- coredns-1.12.0.orig/vendor/github.com/expr-lang/expr/builtin/lib.go
+++ coredns-1.12.0/vendor/github.com/expr-lang/expr/builtin/lib.go
@@ -258,7 +258,10 @@ func String(arg any) any {
 	return fmt.Sprintf("%v", arg)
 }
 
-func minMax(name string, fn func(any, any) bool, args ...any) (any, error) {
+func minMax(name string, fn func(any, any) bool, depth int, args ...any) (any, error) {
+	if depth > MaxDepth {
+		return nil, ErrorMaxDepth
+	}
 	var val any
 	for _, arg := range args {
 		rv := reflect.ValueOf(deref.Deref(arg))
@@ -266,7 +269,7 @@ func minMax(name string, fn func(any, an
 		case reflect.Array, reflect.Slice:
 			size := rv.Len()
 			for i := 0; i < size; i++ {
-				elemVal, err := minMax(name, fn, rv.Index(i).Interface())
+				elemVal, err := minMax(name, fn, depth+1, rv.Index(i).Interface())
 				if err != nil {
 					return nil, err
 				}
@@ -299,7 +302,10 @@ func minMax(name string, fn func(any, an
 	return val, nil
 }
 
-func mean(args ...any) (int, float64, error) {
+func mean(depth int, args ...any) (int, float64, error) {
+	if depth > MaxDepth {
+		return 0, 0, ErrorMaxDepth
+	}
 	var total float64
 	var count int
 
@@ -309,7 +315,7 @@ func mean(args ...any) (int, float64, er
 		case reflect.Array, reflect.Slice:
 			size := rv.Len()
 			for i := 0; i < size; i++ {
-				elemCount, elemSum, err := mean(rv.Index(i).Interface())
+				elemCount, elemSum, err := mean(depth+1, rv.Index(i).Interface())
 				if err != nil {
 					return 0, 0, err
 				}
@@ -332,7 +338,10 @@ func mean(args ...any) (int, float64, er
 	return count, total, nil
 }
 
-func median(args ...any) ([]float64, error) {
+func median(depth int, args ...any) ([]float64, error) {
+	if depth > MaxDepth {
+		return nil, ErrorMaxDepth
+	}
 	var values []float64
 
 	for _, arg := range args {
@@ -341,7 +350,7 @@ func median(args ...any) ([]float64, err
 		case reflect.Array, reflect.Slice:
 			size := rv.Len()
 			for i := 0; i < size; i++ {
-				elems, err := median(rv.Index(i).Interface())
+				elems, err := median(depth+1, rv.Index(i).Interface())
 				if err != nil {
 					return nil, err
 				}
Index: coredns-1.12.0/vendor/github.com/expr-lang/expr/builtin/builtin.go
===================================================================
--- coredns-1.12.0.orig/vendor/github.com/expr-lang/expr/builtin/builtin.go
+++ coredns-1.12.0/vendor/github.com/expr-lang/expr/builtin/builtin.go
@@ -3,6 +3,7 @@ package builtin
 import (
 	"encoding/base64"
 	"encoding/json"
+	"errors"
 	"fmt"
 	"reflect"
 	"sort"
@@ -16,6 +17,10 @@ import (
 var (
 	Index map[string]int
 	Names []string
+
+	// MaxDepth limits the recursion depth for nested structures.
+	MaxDepth      = 10000
+	ErrorMaxDepth = errors.New("recursion depth exceeded")
 )
 
 func init() {
@@ -377,7 +382,7 @@ var Builtins = []*Function{
 	{
 		Name: "max",
 		Func: func(args ...any) (any, error) {
-			return minMax("max", runtime.Less, args...)
+			return minMax("max", runtime.Less, 0, args...)
 		},
 		Validate: func(args []reflect.Type) (reflect.Type, error) {
 			return validateAggregateFunc("max", args)
@@ -386,7 +391,7 @@ var Builtins = []*Function{
 	{
 		Name: "min",
 		Func: func(args ...any) (any, error) {
-			return minMax("min", runtime.More, args...)
+			return minMax("min", runtime.More, 0, args...)
 		},
 		Validate: func(args []reflect.Type) (reflect.Type, error) {
 			return validateAggregateFunc("min", args)
@@ -395,7 +400,7 @@ var Builtins = []*Function{
 	{
 		Name: "mean",
 		Func: func(args ...any) (any, error) {
-			count, sum, err := mean(args...)
+			count, sum, err := mean(0, args...)
 			if err != nil {
 				return nil, err
 			}
@@ -411,7 +416,7 @@ var Builtins = []*Function{
 	{
 		Name: "median",
 		Func: func(args ...any) (any, error) {
-			values, err := median(args...)
+			values, err := median(0, args...)
 			if err != nil {
 				return nil, err
 			}
openSUSE Build Service is sponsored by