Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 25 additions & 21 deletions .github/workflows/check-binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@ jobs:
report_contents: ${{ steps.save-output.outputs.report_contents }}
steps:
- name: Setup python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
ref: main
- name: Download latest release
uses: robinraju/release-downloader@v1.10
with:
latest: true
fileName: 'aws-lambda-rie*'
out-file-path: "bin"
run: |
mkdir -p bin
gh release download --pattern 'aws-lambda-rie*' --dir bin
env:
GH_TOKEN: ${{ github.token }}
- name: Run check for vulnerabilities
id: check-binaries
run: |
Expand Down Expand Up @@ -61,25 +61,29 @@ jobs:
name: Save outputs for the check with the latest build
id: save-new-version
run: |
if [ "${{ steps.check-new-version.outcome }}" == "failure" ]; then
if [ "${CHECK_OUTCOME}" == "failure" ]; then
fixed="No"
else
fixed="Yes"
fi
echo "fixed=$fixed" >> "$GITHUB_OUTPUT"
env:
CHECK_OUTCOME: ${{ steps.check-new-version.outcome }}
- if: always() && steps.save-output.outputs.report_contents
name: Create GitHub Issue indicating vulnerabilities
id: create-issue
uses: dacbd/create-issue-action@main
with:
token: ${{ github.token }}
title: |
CVEs found in latest RIE release
body: |
### CVEs found in latest RIE release
```
${{ steps.save-output.outputs.report_contents }}
```

#### Are these resolved by building with the latest patch version of Go (${{ steps.check-new-version.outputs.latest_version }})?:
> **${{ steps.save-new-version.outputs.fixed }}**
run: |
gh issue create \
--title "CVEs found in latest RIE release" \
--body "### CVEs found in latest RIE release
\`\`\`
${REPORT_CONTENTS}
\`\`\`

#### Are these resolved by building with the latest patch version of Go (${LATEST_VERSION})?:
> **${FIXED}**"
env:
GH_TOKEN: ${{ github.token }}
REPORT_CONTENTS: ${{ steps.save-output.outputs.report_contents }}
LATEST_VERSION: ${{ steps.check-new-version.outputs.latest_version }}
FIXED: ${{ steps.save-new-version.outputs.fixed }}
22 changes: 7 additions & 15 deletions .github/workflows/integ-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,33 @@ permissions:
jobs:
go-tests:
runs-on: ubuntu-latest
environment:
name: integ-tests
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: run go tests
run: make tests-with-docker
integ-tests-x86:
runs-on: ubuntu-latest
environment:
name: integ-tests
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: run integration tests
run: make integ-tests-with-docker-x86-64
integ-tests-arm64:
runs-on: ubuntu-latest
environment:
name: integ-tests
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: run integration tests
run: make integ-tests-with-docker-arm64
integ-tests-old:
runs-on: ubuntu-latest
environment:
name: integ-tests
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: run integration tests
Expand Down
22 changes: 12 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ jobs:
environment: Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
ref: main
- name: Set up python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Build
Expand All @@ -33,12 +33,14 @@ jobs:
make tests-with-docker
make integ-tests
- name: Release
uses: softprops/action-gh-release@v2
with:
name: Release ${{ github.event.inputs.releaseVersion }}
tag_name: v${{ github.event.inputs.releaseVersion }}
body: ${{ github.event.inputs.releaseBody }}
files: |
bin/aws-lambda-rie
bin/aws-lambda-rie-arm64
run: |
gh release create "v${RELEASE_VERSION}" \
--title "Release ${RELEASE_VERSION}" \
--notes "${RELEASE_BODY}" \
bin/aws-lambda-rie \
bin/aws-lambda-rie-arm64 \
bin/aws-lambda-rie-x86_64
env:
GH_TOKEN: ${{ github.token }}
RELEASE_VERSION: ${{ github.event.inputs.releaseVersion }}
RELEASE_BODY: ${{ github.event.inputs.releaseBody }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ tags
.idea
.DS_Store
.venv
build.log
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type rieInvokeRequest struct {
cognitoIdentityPoolId string
clientContext string
responseMode string
internalInvocationID string

functionVersionID string
}
Expand Down Expand Up @@ -98,6 +99,7 @@ func NewRieInvokeRequest(request *http.Request, writer http.ResponseWriter) (*ri
cognitoIdentityPoolId: cognitoIdentityPoolId,
clientContext: clientContext,
responseMode: request.Header.Get(invoke.ResponseModeHeader),
internalInvocationID: uuid.New().String(),
}

return req, nil
Expand Down Expand Up @@ -184,3 +186,7 @@ func (r *rieInvokeRequest) UpdateFromInitData(initData interop.InitStaticDataPro
func (r *rieInvokeRequest) FunctionVersionID() string {
return r.functionVersionID
}

func (r *rieInvokeRequest) InternalInvocationID() string {
return r.internalInvocationID
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ func TestNewRieInvokeRequest(t *testing.T) {
if tt.want.invokeID == "" {
tt.want.invokeID = got.invokeID
}
tt.want.internalInvocationID = got.internalInvocationID

assert.Equal(t, tt.want, got)
})
Expand Down
17 changes: 17 additions & 0 deletions internal/lambda-managed-instances/interop/mock_invoke_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,23 @@ func (_m *MockInvokeRequest) FunctionVersionID() string {
return r0
}

func (_m *MockInvokeRequest) InternalInvocationID() string {
ret := _m.Called()

if len(ret) == 0 {
panic("no return value specified for InternalInvocationID")
}

var r0 string
if rf, ok := ret.Get(0).(func() string); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(string)
}

return r0
}

func (_m *MockInvokeRequest) InvokeID() string {
ret := _m.Called()

Expand Down
2 changes: 2 additions & 0 deletions internal/lambda-managed-instances/interop/sandbox_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,8 @@ type InvokeRequest interface {

UpdateFromInitData(InitStaticDataProvider) model.AppError
FunctionVersionID() string

InternalInvocationID() string
}

type InitStaticDataProvider interface {
Expand Down
2 changes: 2 additions & 0 deletions internal/lambda-managed-instances/invoke/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const (
FunctionErrorBodyTrailer = "lambda-runtime-function-error-body"
ResponseModeHeader = "invoke-response-mode"
TraceIdHeader = "x-amzn-trace-id"

RuntimeInvocationIdHeader = "lambda-runtime-invocation-id"
)

type InvokeBodyResponseStatus string
Expand Down
4 changes: 4 additions & 0 deletions internal/lambda-managed-instances/invoke/invoke_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type RuntimeResponseRequest interface {
BodyReader() io.Reader

TrailerError() ErrorForInvoker

InvocationID() string
}

type RuntimeErrorRequest interface {
Expand All @@ -47,6 +49,8 @@ type RuntimeErrorRequest interface {
ReturnCode() int
ErrorDetails() string
GetXrayErrorCause() json.RawMessage

InvocationID() string
}

type runningInvoke interface {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,23 @@ func (_m *MockRuntimeErrorRequest) ReturnCode() int {
return r0
}

func (_m *MockRuntimeErrorRequest) InvocationID() string {
ret := _m.Called()

if len(ret) == 0 {
panic("no return value specified for InvocationID")
}

var r0 string
if rf, ok := ret.Get(0).(func() string); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(string)
}

return r0
}

func NewMockRuntimeErrorRequest(t interface {
mock.TestingT
Cleanup(func())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,23 @@ func (_m *MockRuntimeResponseRequest) TrailerError() ErrorForInvoker {
return r0
}

func (_m *MockRuntimeResponseRequest) InvocationID() string {
ret := _m.Called()

if len(ret) == 0 {
panic("no return value specified for InvocationID")
}

var r0 string
if rf, ok := ret.Get(0).(func() string); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(string)
}

return r0
}

func NewMockRuntimeResponseRequest(t interface {
mock.TestingT
Cleanup(func())
Expand Down
21 changes: 21 additions & 0 deletions internal/lambda-managed-instances/invoke/running_invoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ type runningInvokeImpl struct {
invokeRespSender InvokeResponseSender
runtimeNext http.ResponseWriter

internalInvocationID string

responderFactoryFunc ResponderFactoryFunc
sendInvokeToRuntime func(context.Context, interop.InitStaticDataProvider, interop.InvokeRequest, http.ResponseWriter, string) (int64, time.Duration, time.Duration, model.AppError)
createTracingData func(traceId string, tracingMode intmodel.XrayTracingMode, segmentIDGenerator func() string) (downstreamTraceId string, tracingCtx *interop.TracingCtx)
Expand Down Expand Up @@ -99,6 +101,8 @@ func newRunningInvoke(
func (r *runningInvokeImpl) RunInvokeAndSendResult(ctx context.Context, initData interop.InitStaticDataProvider, invokeReq interop.InvokeRequest, metrics interop.InvokeMetrics) model.AppError {
downstreamTraceId, tracingCtx := r.createTracingData(invokeReq.TraceId(), initData.XRayTracingMode(), xray.GenerateSegmentID)

r.internalInvocationID = invokeReq.InternalInvocationID()

metrics.TriggerStartRequest()
if err := metrics.SendInvokeStartEvent(tracingCtx); err != nil {
logging.Error(ctx, "Failed to send InvokeStartEvent", "err", err)
Expand Down Expand Up @@ -290,11 +294,28 @@ func (r *runningInvokeImpl) RuntimeResponse(ctx context.Context, runtimeRespReq
return model.NewCustomerError(model.ErrorRuntimeInvokeResponseInProgress)
}

if echoedID := runtimeRespReq.InvocationID(); echoedID != "" && r.internalInvocationID != "" {
if echoedID != r.internalInvocationID {
logging.Warn(ctx, "Cross-wiring detected: invocation ID mismatch on response",
"expected", r.internalInvocationID, "received", echoedID)
r.responseState.CompareAndSwap(stateGotResponse, stateNoResponse)
return model.NewCustomerError(model.ErrorRuntimeInvokeTimeout)
}
}

r.runtimeResponseChan <- runtimeRespReq
return <-r.responseSentChan
}

func (r *runningInvokeImpl) RuntimeError(ctx context.Context, runtimeErrReq RuntimeErrorRequest) model.AppError {
if echoedID := runtimeErrReq.InvocationID(); echoedID != "" && r.internalInvocationID != "" {
if echoedID != r.internalInvocationID {
logging.Warn(ctx, "Cross-wiring detected: invocation ID mismatch on error",
"expected", r.internalInvocationID, "received", echoedID)
return model.NewCustomerError(model.ErrorRuntimeInvokeTimeout)
}
}

oldState := r.responseState.Swap(stateGotError)
if oldState == stateGotError {
logging.Warn(ctx, "Invalid invoke state : error in progress")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ func hijackRunningInvokeDeps(ri *runningInvokeImpl, mocks *runningInvokeMocks) {
func createMocksAndInitRunningInvoke(t *testing.T) (*runningInvokeMocks, *runningInvokeImpl) {
mocks := newRunningInvokeMocks(t)

mocks.eaInvokeRequest.On("InternalInvocationID").Return("").Maybe()
mocks.runtimeRespReq.On("InvocationID").Return("").Maybe()
mocks.runtimeErrorReq.On("InvocationID").Return("").Maybe()

ri := newRunningInvoke(
mocks.runtimeNextRequest,
func(ctx context.Context, ir interop.InvokeRequest) InvokeResponseSender {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type runtimeError struct {
invokeID interop.InvokeID
errorType model.ErrorType
errorCategory model.ErrorCategory
invocationID string

errorDetails string
xrayErrorCause json.RawMessage
Expand All @@ -42,6 +43,7 @@ func NewRuntimeError(ctx context.Context, request *http.Request, invokeID intero
invokeID: invokeID,
errorType: model.GetValidRuntimeOrFunctionErrorType(request.Header.Get(RuntimeErrorTypeHeader)),
errorCategory: RuntimeErrorCategory,
invocationID: request.Header.Get(RuntimeInvocationIdHeader),
errorDetails: errorDetails,
xrayErrorCause: getValidatedErrorCause(ctx, request.Header.Get(LambdaXRayErrorCauseHeader)),
}
Expand Down Expand Up @@ -89,6 +91,10 @@ func (r *runtimeError) GetXrayErrorCause() json.RawMessage {
return r.xrayErrorCause
}

func (r *runtimeError) InvocationID() string {
return r.invocationID
}

func (r *runtimeError) ReturnCode() int {
return http.StatusOK
}
Expand Down
Loading