From 7f51210672031aee7a790455d51a17ce11a70559 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Mon, 11 Nov 2024 05:58:37 +0100 Subject: [PATCH] Harden runner updateTask and updateLog api (#32462) Per proposal https://github.com/go-gitea/gitea/issues/32461 (cherry picked from commit f888e45432ccb86b18e6709fbd25223e07f2c422) --- models/actions/task.go | 4 +++- routers/api/actions/runner/runner.go | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/models/actions/task.go b/models/actions/task.go index 8d41a631aa..8bd139a2d6 100644 --- a/models/actions/task.go +++ b/models/actions/task.go @@ -341,7 +341,7 @@ func UpdateTask(ctx context.Context, task *ActionTask, cols ...string) error { // UpdateTaskByState updates the task by the state. // It will always update the task if the state is not final, even there is no change. // So it will update ActionTask.Updated to avoid the task being judged as a zombie task. -func UpdateTaskByState(ctx context.Context, state *runnerv1.TaskState) (*ActionTask, error) { +func UpdateTaskByState(ctx context.Context, runnerID int64, state *runnerv1.TaskState) (*ActionTask, error) { stepStates := map[int64]*runnerv1.StepState{} for _, v := range state.Steps { stepStates[v.Id] = v @@ -360,6 +360,8 @@ func UpdateTaskByState(ctx context.Context, state *runnerv1.TaskState) (*ActionT return nil, err } else if !has { return nil, util.ErrNotExist + } else if runnerID != task.RunnerID { + return nil, fmt.Errorf("invalid runner for task") } if task.Status.IsDone() { diff --git a/routers/api/actions/runner/runner.go b/routers/api/actions/runner/runner.go index 017bdf6324..cb47074e98 100644 --- a/routers/api/actions/runner/runner.go +++ b/routers/api/actions/runner/runner.go @@ -177,7 +177,9 @@ func (s *Service) UpdateTask( ctx context.Context, req *connect.Request[runnerv1.UpdateTaskRequest], ) (*connect.Response[runnerv1.UpdateTaskResponse], error) { - task, err := actions_model.UpdateTaskByState(ctx, req.Msg.State) + runner := GetRunner(ctx) + + task, err := actions_model.UpdateTaskByState(ctx, runner.ID, req.Msg.State) if err != nil { return nil, status.Errorf(codes.Internal, "update task: %v", err) } @@ -239,11 +241,15 @@ func (s *Service) UpdateLog( ctx context.Context, req *connect.Request[runnerv1.UpdateLogRequest], ) (*connect.Response[runnerv1.UpdateLogResponse], error) { + runner := GetRunner(ctx) + res := connect.NewResponse(&runnerv1.UpdateLogResponse{}) task, err := actions_model.GetTaskByID(ctx, req.Msg.TaskId) if err != nil { return nil, status.Errorf(codes.Internal, "get task: %v", err) + } else if runner.ID != task.RunnerID { + return nil, status.Errorf(codes.Internal, "invalid runner for task") } ack := task.LogLength