Skip to content

Value scan leaking arbitrary memory when combined with easyjson.RawMessage #1420

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

Closed
niallnsec opened this issue Dec 7, 2022 · 3 comments
Closed
Labels

Comments

@niallnsec
Copy link

Describe the bug
When scanning into a field of type easyjson.RawMessage, random binary data from memory is sometimes added to the start of the buffer.

The underlying type of easyjson.RawMessage is a []byte. I have multiple queries which return JSONB data that I then marshal into a struct field of type easyjson.RawMessage. This worked fine in v4 of the package.

Expected behavior
After upgrading to v5, the code would still work.

Actual behavior
After upgrading to v5, marshalling into a field of type easyjson.RawMessage results in random bytes from memory being appended to the start of the buffer most of the time. If I define a temporary variable of type []byte, scan into that and then assign that variable to the struct field the data is marshalled correctly.

Version

  • Go: go version go1.19.3 darwin/arm64
  • PostgreSQL: PostgreSQL 14.4 on aarch64-unknown-linux-musl, compiled by gcc (Alpine 11.2.1_git20220219) 11.2.1 20220219, 64-bit
  • pgx: v5.2.0
@niallnsec niallnsec added the bug label Dec 7, 2022
@niallnsec
Copy link
Author

Interestingly, it also works as expected if I cast the variable before passing it into rows.Scan(), eg:

var rawMsg easyjson.RawMessage
rows.Scan(..., (*[]byte)(&rawMsg), ...)

@jackc
Copy link
Owner

jackc commented Dec 8, 2022

I've never used easyjson but a quick glance at https://github.com/mailru/easyjson/blob/master/raw.go makes me suspect this is the problem.

func (v *RawMessage) UnmarshalJSON(data []byte) error {
	*v = data
	return nil
}

This is a bug. See https://pkg.go.dev/encoding/json#Unmarshaler.

UnmarshalJSON must copy the JSON data if it wishes to retain the data after returning.

I've posted a bug to their issue tracker. mailru/easyjson#380

@jackc jackc closed this as completed Dec 8, 2022
@niallnsec
Copy link
Author

Thanks for the insight, I had assumed that pgx was treating the data as just raw bytes, I didn't realise it was calling the UnmarshalJSON function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants