microsoft / microsoft/hcsshim

Panic: assignment to entry in nil map in NewRegoPolicyInterpreter (copyObject)

Open
#2,596 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
694
Forks
304
Avg merge
1d 19h
Merged PRs (30d)
28

Description

https://github.com/microsoft/hcsshim/blob/18193a4688fa4025f32a04576b593f2e0b853521/internal/regopolicyinterpreter/regopolicyinterpreter.go#L85

Bug Description

Invoking NewRegoPolicyInterpreter with an empty map as initial data can panic with assignment to entry in nil map due to how the internal copyObject function handles empty input.

Steps to Reproduce

  • Call NewRegoPolicyInterpreter and pass make(map[string]interface{}) (an empty map) for the data parameter.
  • The function panics when attempting data["metadata"] = ... inside the constructor.

Root Cause

  • In copyObject, unmarshaling JSON into a nil map returns a nil map, not an initialized map.
  • Later code assumes the map is always initialized and safe to assign fields to.

Impact

  • Triggers a runtime panic with valid (but empty) input.

Recommendation

  • Modify copyObject to add check for nil or empty input:
func copyObject(data map[string]interface{}) (map[string]interface{}, error) {
	// Handle nil or empty input
	if data == nil {
		return make(map[string]interface{}), nil
	}
	
	objJSON, err := json.Marshal(data)
	if err != nil {
		return nil, err
	}

	objCopy := make(map[string]interface{})  // Initialize before unmarshaling!
	err = json.Unmarshal(objJSON, &objCopy)
	if err != nil {
		return nil, err
	}

	return objCopy, nil
}

Fuzzer Identification

  • I discovered this issue while fuzzing the regopolicyinterpreter. Here's the test case:
package regopolicyinterpreter

import (
	"testing"
)

func FuzzInterpreterLogic(f *testing.F) {
	// Seed with a basic Rego package and a query
	f.Add("package test\nallow = true", "data.test.allow")

	f.Fuzz(func(t *testing.T, moduleCode string, queryStr string) {
		// 1. Initialize the interpreter with fuzzed code
		rpi, err := NewRegoPolicyInterpreter(moduleCode, nil)
		if err != nil {
			t.Skip() // Ignore invalid Rego syntax
		}

		// 2. Try to add a fuzzed module (AddModule returns nothing)
		rpi.AddModule("fuzzed.rego", &RegoModule{
			Namespace: "fuzzed",
			Code:      moduleCode,
		})

		// 3. Attempt a raw query with an empty input map
		// want (string, map[string]interface{})
		input := make(map[string]interface{})
		_, _ = rpi.RawQuery(queryStr, input)
	})
}
  • Running with: go test -fuzz=FuzzInterpreterLogic -fuzztime=15m

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in internal/regopolicyinterpreter/regopolicyinterpreter.go at the copyObject implementation and the NewRegoPolicyInterpreter path around line 85. Reproduce the empty-map case described in the issue, then run go test -fuzz=FuzzInterpreterLogic -fuzztime=15m; done means empty input no longer causes an assignment-to-nil-map panic.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.