diff --git a/pkg/sentry/socket/netfilter/extensions.go b/pkg/sentry/socket/netfilter/extensions.go index 7dc6379ad..a99ba3797 100644 --- a/pkg/sentry/socket/netfilter/extensions.go +++ b/pkg/sentry/socket/netfilter/extensions.go @@ -153,24 +153,31 @@ type target interface { // marshals and unmarshals it. It is immutable after package initialization. var targetMakers = map[targetID]targetMaker{} +// targetRevision returns the maximum supported version of the matcher with +// name `name` up to rev, and whether any such matcher with that name exists. func targetRevision(name string, netProto tcpip.NetworkProtocolNumber, rev uint8) (uint8, bool) { tid := targetID{ name: name, networkProtocol: netProto, revision: rev, } - if _, ok := targetMakers[tid]; !ok { - return 0, false + if _, ok := targetMakers[tid]; ok { + return rev, true } - // Return the highest supported revision unless rev is higher. - for _, other := range targetMakers { - otherID := other.id() - if name == otherID.name && netProto == otherID.networkProtocol && otherID.revision > rev { - rev = uint8(otherID.revision) + // Return the highest supported revision. + var found bool + var ret uint8 + for _, cur := range targetMakers { + curID := cur.id() + if name == curID.name && netProto == curID.networkProtocol { + found = true + if curID.revision > ret { + ret = uint8(curID.revision) + } } } - return rev, true + return ret, found } // registerTargetMaker should be called by target extensions to register them diff --git a/pkg/sentry/socket/netfilter/netfilter.go b/pkg/sentry/socket/netfilter/netfilter.go index 1d20350c0..05c8b3ebf 100644 --- a/pkg/sentry/socket/netfilter/netfilter.go +++ b/pkg/sentry/socket/netfilter/netfilter.go @@ -392,9 +392,13 @@ func TargetRevision(t *kernel.Task, revPtr hostarch.Addr, netProto tcpip.Network } maxSupported, ok := targetRevision(rev.Name.String(), netProto, rev.Revision) if !ok { + // Return ENOENT if there's no target with that name. + return linux.XTGetRevision{}, syserr.ErrNoFileOrDir + } + if maxSupported < rev.Revision { + // Return EPROTONOSUPPORT if we have an insufficient revision. return linux.XTGetRevision{}, syserr.ErrProtocolNotSupported } - rev.Revision = maxSupported return rev, nil }