Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent nil panic from derefeence nil context in authorization middleware #3829

Merged
merged 6 commits into from
Feb 7, 2023

Conversation

troydai
Copy link
Contributor

@troydai troydai commented Feb 7, 2023

Pull Request check list

  • Commit conforms to CONTRIBUTING.md?
  • Proper tests/regressions included?
  • Documentation updated?

Affected functionality

Prevent a nil panic when a database operation failure happens during retrieving entries.

Description of change

Nil panic happens in authorization middleware's Preprocess function when a nil context is passed down from a failed database operation while fetching entries in function WithCallerEntries. This change addresses this risk by introduce a new variable to hold the returned context so as to avoid dereferencing a potential nil ctx.

Extended explanation:

WithCallerEntries returns error when a database operation failure happens. The error itself is not fatal, however, it returns a nil context. Returns zero value when errors is correct behavior. However, the reconcileResult function and opaAuth function bubble up the nil context as if it is populated. In the authorization middleware's Preprocess function, it attempts to retrieve a logger from the context thus cased a nil panic.

Fix:

The fix is simple: Since the dereference happens for the purpose of fetching a logger, a new variable is introduced to store returned context and deferencing will happen on the original contexty. This is simplest fix of all the forms. Other alternative fix include introduce a separate variable to hold mutated context and I believe it overcomplicates the code.

Other changes:

This change also include a fix in the authorization_opa.go to explicitly returns nil context in when functions errored out. It doesn't change the logic because it is already returning nil.

Which issue this PR fixes

…leware

Nil panics happens authorization middleware's Preprocess function when a nil context is passed down from a failed database operation while fetching entries in function WithCallerEntries. This change addresses this risk by dereference the context and fetch the logger earlier before the ctx variable is mutated.

Extended explanation:

WithCallerEntries returns error when a database operation failure happens. The error itself is not fatal, however, it returns a nil context. Returns zero value when errors is correct behavior. However, the reconcileResult function and opaAuth function bubble up the nil context as if it is populated. In the authorization middleware's Preprocess function, it attempts to retrieve a logger from the context thus cased a nil panic.

Fix:

The fix is simple: since the dereference happens for the purpose of fetching a logger. The logger is prefetched before the context is mutated. This is simplest fix of all the forms. Other alternative fix include introduce a separate variable to hold mutated context and I believe it overcomplicates the code.

Other changes:

This change also include a fix in the authorization_opa.go to explicitly returns nil context in when functions errored out. It doesn't change the logic because it is already returning nil.

Signed-off-by: Troy Dai <[email protected]>
Signed-off-by: Troy Dai <[email protected]>
Copy link
Member

@azdagron azdagron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, @troydai. Excellent catch. Just one small suggestion...

@@ -55,12 +55,14 @@ func (m *authorizationMiddleware) Preprocess(ctx context.Context, methodName str
ctx = rpccontext.WithLogger(ctx, rpccontext.Logger(ctx).WithFields(fields))
}

logger := rpccontext.Logger(ctx)

var deniedDetails *types.PermissionDeniedDetails
ctx, allow, err := m.opaAuth(ctx, req, methodName)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also not alias the ctx variable? I think that would be a little more robust towards future refactors.

authedCtx, allow, err := m.opaAuth(ctx, req, methodName)
....
if allow {
    return authedCtx, nil
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. With the new variable name, it is not necessary to fetch the logger early because the ctx is now safe to dereference. This reduce the changes in this PR.

1. Use a different variable to hold the return context to avoid mutate
   the ctx variable;
2. Revert the previous change of fetching logger earilier. With the new
   variable, it is now safe to fetch logger from the ctx.

Signed-off-by: Troy Dai <[email protected]>
Copy link
Member

@azdagron azdagron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\o/

@troydai
Copy link
Contributor Author

troydai commented Feb 7, 2023

Thank you. Updated the PR description, will merge once all the checks pass.

@azdagron
Copy link
Member

azdagron commented Feb 7, 2023

will merge once all the checks pass

Only maintainers have permissions to merge. We'll take care of it :)

@troydai
Copy link
Contributor Author

troydai commented Feb 7, 2023

Got it. There is a race condition test failed. Glance at it, it doesn't seem to be related to this change. Shall I dig into it or there will be a retry?

@azdagron
Copy link
Member

azdagron commented Feb 7, 2023

It's a racy test. I'll retrigger it after the rest have finished.

@MarcosDY MarcosDY added this to the 1.6.0 milestone Feb 7, 2023
@rturner3 rturner3 merged commit 4d6de7b into spiffe:main Feb 7, 2023
@troydai troydai deleted the fix-nil-context branch February 8, 2023 03:50
stevend-uber pushed a commit to stevend-uber/spire that referenced this pull request Oct 16, 2023
…ware (spiffe#3829)

* Prevent nil panic from derefeence a nil context in authorization middleware

Nil panics happens authorization middleware's Preprocess function when a nil context is passed down from a failed database operation while fetching entries in function WithCallerEntries. This change addresses this risk by dereference the context and fetch the logger earlier before the ctx variable is mutated.

Extended explanation:

WithCallerEntries returns error when a database operation failure happens. The error itself is not fatal, however, it returns a nil context. Returns zero value when errors is correct behavior. However, the reconcileResult function and opaAuth function bubble up the nil context as if it is populated. In the authorization middleware's Preprocess function, it attempts to retrieve a logger from the context thus cased a nil panic.

Fix:

The fix is simple: since the dereference happens for the purpose of fetching a logger. The logger is prefetched before the context is mutated. This is simplest fix of all the forms. Other alternative fix include introduce a separate variable to hold mutated context and I believe it overcomplicates the code.

Other changes:

This change also include a fix in the authorization_opa.go to explicitly returns nil context in when functions errored out. It doesn't change the logic because it is already returning nil.

Signed-off-by: Troy Dai <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants