fix(actions): prevent deleted records' UUID from colliding with new records (#3830)

This commit changes the code that deletes a runner so it updates the UUID before deleting the record. The new UUID is set to 8 0xff bytes followed by a little endian version of the record's numeric ID. Such UUIDs cannot be created from tokens when registering runners, as the first 16 bytes of the token are in the `[0-9a-f]` range. This should prevent deleted runners from colliding with new records if the tokens share the same first 16 characters.

It is a possible solution to issue #3828

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3830
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Emmanuel BENOÎT <tseeker@nocternity.net>
Co-committed-by: Emmanuel BENOÎT <tseeker@nocternity.net>
This commit is contained in:
Emmanuel BENOÎT 2024-05-19 10:46:15 +00:00 committed by Earl Warren
parent e4c3c039be
commit 0801518f5d
5 changed files with 99 additions and 2 deletions

View file

@ -5,6 +5,7 @@ package actions
import (
"context"
"encoding/binary"
"fmt"
"strings"
"time"
@ -253,11 +254,26 @@ func UpdateRunner(ctx context.Context, r *ActionRunner, cols ...string) error {
// DeleteRunner deletes a runner by given ID.
func DeleteRunner(ctx context.Context, id int64) error {
if _, err := GetRunnerByID(ctx, id); err != nil {
runner, err := GetRunnerByID(ctx, id)
if err != nil {
return err
}
_, err := db.DeleteByID[ActionRunner](ctx, id)
// Replace the UUID, which was either based on the secret's first 16 bytes or an UUIDv4,
// with a sequence of 8 0xff bytes followed by the little-endian version of the record's
// identifier. This will prevent the deleted record's identifier from colliding with any
// new record.
b := make([]byte, 8)
binary.LittleEndian.PutUint64(b, uint64(id))
runner.UUID = fmt.Sprintf("ffffffff-ffff-ffff-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x",
b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7])
err = UpdateRunner(ctx, runner, "UUID")
if err != nil {
return err
}
_, err = db.DeleteByID[ActionRunner](ctx, id)
return err
}