Skip to content

Commit

Permalink
Never Ship. Hacked Dolt table file example
Browse files Browse the repository at this point in the history
  • Loading branch information
macneale4 committed Oct 22, 2024
1 parent efec5f3 commit 4410ae7
Show file tree
Hide file tree
Showing 3 changed files with 232 additions and 0 deletions.
24 changes: 24 additions & 0 deletions go/store/datas/mangle_commit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2024 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package datas

import (
"github.com/dolthub/dolt/go/gen/fb/serial"
"github.com/dolthub/dolt/go/store/hash"
)

func ExposeCommitFlatbuffer(vaddr hash.Hash, opts CommitOptions, heights []uint64, parentsClosureAddr hash.Hash) (serial.Message, uint64) {
return commit_flatbuffer(vaddr, opts, heights, parentsClosureAddr)
}
142 changes: 142 additions & 0 deletions go/store/nbs/mangle_hooks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// Copyright 2024 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package nbs

import (
"context"
"fmt"

"github.com/dolthub/dolt/go/gen/fb/serial"
"github.com/dolthub/dolt/go/store/chunks"
"github.com/dolthub/dolt/go/store/datas"
"github.com/dolthub/dolt/go/store/hash"
"github.com/dolthub/dolt/go/store/types"
)

func LoopOverTables(ctx context.Context, csgs *GenerationalNBS) error {
stats := Stats{}

// If the object is in a garbage collection file, we'll need to read it from the oldGen.
// gen := csgs.oldGen.tables.upstream
gen := csgs.newGen.tables.upstream

vs := types.NewValueStore(csgs)
for tableId, table := range gen {
if tableId.String() == chunks.JournalFileID {
fmt.Println("Skipping Journal File")
continue
}

idx, err := table.index()
if err != nil {
return err
}
sampleCount := idx.chunkCount()

objectToHack := hash.Parse("3pdd8aasraqh1tmuedjmcr5nr2fccud2")

hackedPersister, err := NewCmpChunkTableWriter("")
if err != nil {
return err
}

for i := uint32(0); i < sampleCount; i++ {
var h hash.Hash
_, err := idx.indexEntry(i, &h)
if err != nil {
return err
}
// We'll read Chunks, then recompress them into CompressedChunks
rawData, err := table.get(ctx, h, &stats)
if err != nil {
return err
}

chnk := chunks.NewChunkWithHash(h, rawData)

if h == objectToHack {
// Deserialize the chunk.
origVal, err := types.DecodeValue(chnk, vs)
if err != nil {
return err
}

hackedVal := origVal

if isCmt, _ := datas.IsCommit(origVal); isCmt {
commit, err := serial.TryGetRootAsCommit([]byte(origVal.(types.SerialMessage)), serial.MessagePrefixSz)
if err != nil {
return err
}

rootAddr := hash.New(commit.RootBytes())

parentCnt := commit.ParentAddrsLength() / hash.ByteLen
addrs := commit.ParentAddrsBytes()
parents := make([]hash.Hash, 0, parentCnt)
for i := 0; i < parentCnt; i++ {
addr := hash.New(addrs[:hash.ByteLen])
addrs = addrs[hash.ByteLen:]
parents = append(parents, addr)
}

opts := datas.CommitOptions{Meta: &datas.CommitMeta{
Name: string(commit.Name()),
Email: string(commit.Email()),
Timestamp: commit.TimestampMillis() - 300000, // Make it look like the commit was made 5 min before it actually was.
UserTimestamp: commit.UserTimestampMillis() - 300000,
Description: string(commit.Description()),
}, Parents: parents}

parentClosure := hash.New(commit.ParentClosureBytes())

heights := make([]uint64, 1)
heights[0] = commit.Height() - 1

altMsg, _ := datas.ExposeCommitFlatbuffer(rootAddr, opts, heights, parentClosure)
hackedVal = types.SerialMessage(altMsg)
chnk = chunks.NewChunkWithHash(objectToHack, []byte(hackedVal.(types.SerialMessage)))
} else {
return fmt.Errorf("object type is not a commit: %s", origVal.HumanReadableString())
}

fmt.Println("----------------------- MANGLE -----------------------------")
fmt.Println(fmt.Sprintf("Found object %s in Table File: %s", h.String(), tableId))
fmt.Println(origVal.HumanReadableString())
fmt.Println("ALTERED TO:")
fmt.Println(hackedVal.HumanReadableString())
fmt.Println("------------------------------------------------------------")
}

cmpChnk := ChunkToCompressedChunk(chnk)

err = hackedPersister.AddCmpChunk(cmpChnk)
if err != nil {
return err
}
}
_, err = hackedPersister.Finish()
if err != nil {
return err
}

err = hackedPersister.FlushToFile(fmt.Sprintf("%s.hacked", tableId))
if err != nil {
return err
}
}

return nil
}
66 changes: 66 additions & 0 deletions go/utils/mangle/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2024 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"context"
"fmt"
"os"

"github.com/dolthub/dolt/go/cmd/dolt/doltversion"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
"github.com/dolthub/dolt/go/libraries/utils/filesys"
"github.com/dolthub/dolt/go/store/datas"
"github.com/dolthub/dolt/go/store/nbs"
"github.com/fatih/color"
)

func main() {
ctx := context.Background()

var fs filesys.Filesys
fs = filesys.LocalFS

dataDirFS, err := fs.WithWorkingDir(".")
if err != nil {
fmt.Println(color.RedString("Failed to set the data directory. %v", err))
os.Exit(1)
}

dEnv := env.Load(ctx, env.GetCurrentUserHomeDir, dataDirFS, doltdb.LocalDirDoltDB, doltversion.Version)
if dEnv.CfgLoadErr != nil {
fmt.Println(color.RedString("Failed to load the dolt config. %v", dEnv.CfgLoadErr))
os.Exit(1)
}
if dEnv.DBLoadError != nil {
fmt.Println(color.RedString("Failed to load the database. %v", dEnv.DBLoadError))
os.Exit(1)
}

db := doltdb.HackDatasDatabaseFromDoltDB(dEnv.DoltDB)
cs := datas.ChunkStoreFromDatabase(db)

if gs, ok := cs.(*nbs.GenerationalNBS); ok {
err := nbs.LoopOverTables(ctx, gs)
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
} else {
fmt.Println("Not a generational chunk store")
os.Exit(1)
}
}

0 comments on commit 4410ae7

Please sign in to comment.