Skip to content

Commit

Permalink
Do not parse MySQL server packets (#9422)
Browse files Browse the repository at this point in the history
  • Loading branch information
r0mant authored Dec 15, 2021
1 parent f5829cf commit afce79e
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
20 changes: 20 additions & 0 deletions lib/srv/db/access_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,26 @@ func TestAccessMySQLChangeUser(t *testing.T) {
require.Error(t, err)
}

// TestAccessMySQLServerPacket verifies some edge-cases related to reading
// wire packets sent by the MySQL server.
func TestAccessMySQLServerPacket(t *testing.T) {
ctx := context.Background()
testCtx := setupTestContext(ctx, t, withSelfHostedMySQL("mysql"))
go testCtx.startHandlingConnections()

// Create user/role with access permissions.
testCtx.createUserAndRole(ctx, t, "alice", "admin", []string{"alice"}, []string{types.Wildcard})

// Connect to the database as this user.
mysqlConn, err := testCtx.mysqlClient("alice", "mysql", "alice")
require.NoError(t, err)

// Execute "show tables" command which will make the test server to reply
// in a way that previously would cause our packet parsing logic to fail.
_, err = mysqlConn.Execute("show tables")
require.NoError(t, err)
}

type testModules struct {
modules.Modules
}
Expand Down
4 changes: 2 additions & 2 deletions lib/srv/db/mysql/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ func (e *Engine) receiveFromServer(serverConn, clientConn net.Conn, serverErrCh
close(serverErrCh)
}()
for {
packet, err := protocol.ParsePacket(serverConn)
packet, _, err := protocol.ReadPacket(serverConn)
if err != nil {
if utils.IsOKNetworkError(err) {
log.Debug("Server connection closed.")
Expand All @@ -237,7 +237,7 @@ func (e *Engine) receiveFromServer(serverConn, clientConn net.Conn, serverErrCh
serverErrCh <- err
return
}
_, err = protocol.WritePacket(packet.Bytes(), clientConn)
_, err = protocol.WritePacket(packet, clientConn)
if err != nil {
log.WithError(err).Error("Failed to write client packet.")
serverErrCh <- err
Expand Down
18 changes: 18 additions & 0 deletions lib/srv/db/mysql/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,24 @@ type testHandler struct {
func (h *testHandler) HandleQuery(query string) (*mysql.Result, error) {
h.log.Debugf("Received query %q.", query)
atomic.AddUint32(&h.queryCount, 1)
// When getting a "show tables" query, construct the response in a way
// which previously caused server packets parsing logic to fail.
if query == "show tables" {
resultSet, err := mysql.BuildSimpleTextResultset(
[]string{"Tables_in_test"},
[][]interface{}{
// In raw bytes, this table name starts with 0x11 which used to
// cause server packet parsing issues since it clashed with
// COM_CHANGE_USER packet type.
{"metadata_md_table"},
})
if err != nil {
return nil, trace.Wrap(err)
}
return &mysql.Result{
Resultset: resultSet,
}, nil
}
return TestQueryResponse, nil
}

Expand Down

0 comments on commit afce79e

Please sign in to comment.