From d52216d43b7b58a7c98605702a7ad948d2952447 Mon Sep 17 00:00:00 2001 From: James Ribe Date: Tue, 30 Jul 2024 11:00:00 -0700 Subject: [PATCH] [aws_iid] tolerate network interfaces not being ordered by device index (#5300) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: James Ribe Co-authored-by: Agustín Martínez Fayó --- pkg/server/plugin/nodeattestor/awsiid/iid.go | 15 ++++++++---- .../plugin/nodeattestor/awsiid/iid_test.go | 23 ++++++++++++++++++- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/pkg/server/plugin/nodeattestor/awsiid/iid.go b/pkg/server/plugin/nodeattestor/awsiid/iid.go index 1f8405490b..f211808afa 100644 --- a/pkg/server/plugin/nodeattestor/awsiid/iid.go +++ b/pkg/server/plugin/nodeattestor/awsiid/iid.go @@ -14,6 +14,7 @@ import ( "math" "os" "regexp" + "slices" "sort" "strings" "sync" @@ -328,13 +329,17 @@ func (p *IIDAttestorPlugin) SetLogger(log hclog.Logger) { } func (p *IIDAttestorPlugin) checkBlockDevice(instance ec2types.Instance) error { - ifaceZeroDeviceIndex := *instance.NetworkInterfaces[0].Attachment.DeviceIndex - - if ifaceZeroDeviceIndex != 0 { - return fmt.Errorf("the EC2 instance network interface attachment device index must be zero (has %d)", ifaceZeroDeviceIndex) + ifaceZeroIndex := slices.IndexFunc( + instance.NetworkInterfaces, + func(net ec2types.InstanceNetworkInterface) bool { + return *net.Attachment.DeviceIndex == 0 + }, + ) + if ifaceZeroIndex == -1 { + return errors.New("the EC2 instance network interface with device index 0 is inaccessible") } - ifaceZeroAttachTime := instance.NetworkInterfaces[0].Attachment.AttachTime + ifaceZeroAttachTime := instance.NetworkInterfaces[ifaceZeroIndex].Attachment.AttachTime // skip anti-tampering mechanism when RootDeviceType is instance-store // specifically, if device type is persistent, and the device was attached past diff --git a/pkg/server/plugin/nodeattestor/awsiid/iid_test.go b/pkg/server/plugin/nodeattestor/awsiid/iid_test.go index 14c78e6898..6dc9fc6e9f 100644 --- a/pkg/server/plugin/nodeattestor/awsiid/iid_test.go +++ b/pkg/server/plugin/nodeattestor/awsiid/iid_test.go @@ -221,7 +221,28 @@ func TestAttest(t *testing.T) { output.Reservations[0].Instances[0].NetworkInterfaces[0].Attachment.DeviceIndex = &nonzeroDeviceIndex }, expectCode: codes.Internal, - expectMsgPrefix: "nodeattestor(aws_iid): failed aws ec2 attestation: the EC2 instance network interface attachment device index must be zero (has 1)", + expectMsgPrefix: "nodeattestor(aws_iid): failed aws ec2 attestation: the EC2 instance network interface with device index 0 is inaccessible", + }, + { + name: "block device anti-tampering check succeeds when network devices are not ordered by device index", + mutateDescribeInstancesOutput: func(output *ec2.DescribeInstancesOutput) { + output.Reservations[0].Instances[0].NetworkInterfaces[0].Attachment.DeviceIndex = &nonzeroDeviceIndex + output.Reservations[0].Instances[0].NetworkInterfaces = append( + output.Reservations[0].Instances[0].NetworkInterfaces, + ec2types.InstanceNetworkInterface{ + Attachment: &ec2types.InstanceNetworkInterfaceAttachment{ + DeviceIndex: &zeroDeviceIndex, + }, + }, + ) + }, + expectID: "spiffe://example.org/spire/agent/aws_iid/test-account/test-region/test-instance", + expectSelectors: []*common.Selector{ + {Type: caws.PluginName, Value: "az:test-az"}, + {Type: caws.PluginName, Value: "image:id:test-image-id"}, + {Type: caws.PluginName, Value: "instance:id:test-instance"}, + {Type: caws.PluginName, Value: "region:test-region"}, + }, }, { name: "block device anti-tampering check fails to locate root device",