@@ -417,7 +417,19 @@ func (h *notifHandler) registerSocket(pid int, sockfd int, syscallName string) (
417417 sock .state = NotBypassable
418418 logger .Debugf ("failed to get socket args err=%q" , err )
419419 } else {
420- if sockDomain != syscall .AF_INET && sockDomain != syscall .AF_INET6 {
420+ // compare process's netns is same or not with container init process's netns
421+ isSameNetNS , err := util .SameNetNS (h .containerInitPid , pid )
422+ if err != nil {
423+ logger .Errorf ("failed to check NetNS: err=%q" , err )
424+ sock .state = NotBypassable
425+ }
426+
427+ // check the process is executed with container's netns.
428+ // processes with nested netns are not handled by bypass4netns
429+ if ! isSameNetNS {
430+ logger .Infof ("process seems to be executed in other netns. socket is NotBypassable and ignored" )
431+ sock .state = NotBypassable
432+ } else if sockDomain != syscall .AF_INET && sockDomain != syscall .AF_INET6 {
421433 // non IP sockets are not handled.
422434 sock .state = NotBypassable
423435 logger .Debugf ("socket domain=0x%x" , sockDomain )
@@ -629,6 +641,8 @@ type Handler struct {
629641
630642 // key is child port
631643 forwardingPorts map [int ]ForwardPortMapping
644+
645+ ContainerInitPid int
632646}
633647
634648// NewHandler creates new seccomp notif handler
@@ -640,6 +654,7 @@ func NewHandler(socketPath, comSocketPath, tracerAgentLogPath string) *Handler {
640654 ignoredSubnets : []net.IPNet {},
641655 forwardingPorts : map [int ]ForwardPortMapping {},
642656 readyFd : - 1 ,
657+ ContainerInitPid : - 1 ,
643658 }
644659
645660 return & handler
@@ -711,6 +726,10 @@ type notifHandler struct {
711726
712727 // cache pidfd to reduce latency. key is pid.
713728 pidInfos map [int ]pidInfo
729+
730+ // container init process's pid
731+ // used to check whether netns is container or not.
732+ containerInitPid int
714733}
715734
716735type containerInterface struct {
@@ -732,14 +751,15 @@ type pidInfo struct {
732751 tgid int
733752}
734753
735- func (h * Handler ) newNotifHandler (fd uintptr , state * specs.ContainerProcessState ) * notifHandler {
754+ func (h * Handler ) newNotifHandler (fd uintptr , state * specs.ContainerProcessState , containerInitPid int ) * notifHandler {
736755 notifHandler := notifHandler {
737- fd : libseccomp .ScmpFd (fd ),
738- state : state ,
739- forwardingPorts : map [int ]ForwardPortMapping {},
740- processes : map [int ]* processStatus {},
741- memfds : map [int ]int {},
742- pidInfos : map [int ]pidInfo {},
756+ fd : libseccomp .ScmpFd (fd ),
757+ state : state ,
758+ forwardingPorts : map [int ]ForwardPortMapping {},
759+ processes : map [int ]* processStatus {},
760+ memfds : map [int ]int {},
761+ pidInfos : map [int ]pidInfo {},
762+ containerInitPid : containerInitPid ,
743763 }
744764 notifHandler .nonBypassable = nonbypassable .New (h .ignoredSubnets )
745765 notifHandler .nonBypassableAutoUpdate = h .ignoredSubnetsAutoUpdate
@@ -793,8 +813,18 @@ func (h *Handler) StartHandle(c2cConfig *C2CConnectionHandleConfig, multinodeCon
793813 continue
794814 }
795815
816+ // this may not work correctly when executed process with 'ip netns exec'.
817+ // state.Pid can be the process in nested netns.
818+ // so, we cannot distinguish container netns and nested netns with simply comparing state.Pid and hooked process's pid
819+ // Instead of state.Pid, init process's pid should be used.
820+ // bypass4netns recognizes the first process as a init process.
821+ if h .ContainerInitPid < 0 {
822+ h .ContainerInitPid = state .Pid
823+ logrus .Infof ("ContainerInitPid is %d" , h .ContainerInitPid )
824+ }
825+
796826 logrus .Infof ("Received new seccomp fd: %v" , newFd )
797- notifHandler := h .newNotifHandler (newFd , state )
827+ notifHandler := h .newNotifHandler (newFd , state , h . ContainerInitPid )
798828 notifHandler .c2cConnections = c2cConfig
799829 notifHandler .multinode = multinodeConfig
800830 if notifHandler .multinode .Enable {
0 commit comments