Skip to content

Commit

Permalink
database/sql: clone data for named []byte types
Browse files Browse the repository at this point in the history
Previously named byte types like json.RawMessage could get dirty
database memory from a call to Scan. These types would activate a
code path that didn't clone the byte data coming from the database
before assigning it. Another thread could then overwrite the byte
array in src, which has unexpected consequences.

Originally reported by Jason Moiron; the patch and test are his
suggestions. Fixes #13905.

Change-Id: Iacfef61cbc9dd51c8fccef9b2b9d9544c77dd0e0
Reviewed-on: https://go-review.googlesource.com/22393
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
  • Loading branch information
kevinburke authored and bradfitz committed Apr 30, 2016
1 parent a20fd1f commit 4e0cd1e
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/database/sql/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,12 @@ func convertAssign(dest, src interface{}) error {

dv := reflect.Indirect(dpv)
if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) {
dv.Set(sv)
switch b := src.(type) {
case []byte:
dv.Set(reflect.ValueOf(cloneBytes(b)))
default:
dv.Set(sv)
}
return nil
}

Expand Down
12 changes: 12 additions & 0 deletions src/database/sql/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,3 +377,15 @@ func TestRawBytesAllocs(t *testing.T) {
t.Fatalf("allocs = %v; want max 1", n)
}
}

// https://github.com/golang/go/issues/13905
func TestUserDefinedBytes(t *testing.T) {
type userDefinedBytes []byte
var u userDefinedBytes
v := []byte("foo")

convertAssign(&u, v)
if &u[0] == &v[0] {
t.Fatal("userDefinedBytes got potentially dirty driver memory")
}
}

0 comments on commit 4e0cd1e

Please sign in to comment.