From f35ea94893c7c4b2adbe47fbf480c97d03e91063 Mon Sep 17 00:00:00 2001 From: Gabriel Date: Wed, 29 Dec 2021 20:52:26 +0200 Subject: [PATCH] Ignore ERROR_ACCESS_DENIED on Kill (#1252) When calling HcsTerminateProcess on a process that has exited, but we still have open handles to, an ERROR_ACCESS_DENIED may be returned. https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminateprocess#remarks Signed-off-by: Gabriel Adrian Samfira (cherry picked from commit 58caeedaebd9cd721a74fafd2bdcbc274d8d21b9) Signed-off-by: Daniel Canter --- internal/hcs/process.go | 14 ++++++++++++++ .../Microsoft/hcsshim/internal/hcs/process.go | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/internal/hcs/process.go b/internal/hcs/process.go index 8f20346688..3f97bb5e8c 100644 --- a/internal/hcs/process.go +++ b/internal/hcs/process.go @@ -3,7 +3,9 @@ package hcs import ( "context" "encoding/json" + "errors" "io" + "os" "sync" "syscall" "time" @@ -150,6 +152,18 @@ func (process *Process) Kill(ctx context.Context) (bool, error) { } resultJSON, err := vmcompute.HcsTerminateProcess(ctx, process.handle) + if err != nil && errors.Is(err, os.ErrPermission) { + // HcsTerminateProcess ends up calling TerminateProcess in the context + // of a container. According to the TerminateProcess documentation: + // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminateprocess#remarks + // After a process has terminated, call to TerminateProcess with open + // handles to the process fails with ERROR_ACCESS_DENIED (5) error code. + // It's safe to ignore this error here. HCS should always have permissions + // to kill processes inside any container. So an ERROR_ACCESS_DENIED + // is unlikely to be anything else than what the ending remarks in the + // documentation states. + return true, nil + } events := processHcsResult(ctx, resultJSON) delivered, err := process.processSignalResult(ctx, err) if err != nil { diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go b/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go index 8f20346688..3f97bb5e8c 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go @@ -3,7 +3,9 @@ package hcs import ( "context" "encoding/json" + "errors" "io" + "os" "sync" "syscall" "time" @@ -150,6 +152,18 @@ func (process *Process) Kill(ctx context.Context) (bool, error) { } resultJSON, err := vmcompute.HcsTerminateProcess(ctx, process.handle) + if err != nil && errors.Is(err, os.ErrPermission) { + // HcsTerminateProcess ends up calling TerminateProcess in the context + // of a container. According to the TerminateProcess documentation: + // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminateprocess#remarks + // After a process has terminated, call to TerminateProcess with open + // handles to the process fails with ERROR_ACCESS_DENIED (5) error code. + // It's safe to ignore this error here. HCS should always have permissions + // to kill processes inside any container. So an ERROR_ACCESS_DENIED + // is unlikely to be anything else than what the ending remarks in the + // documentation states. + return true, nil + } events := processHcsResult(ctx, resultJSON) delivered, err := process.processSignalResult(ctx, err) if err != nil {