Skip to content

Commit 3879420

Browse files
ratapcmoore
authored andcommitted
all: handle EINTR and ENOENT
The go runtime can interrupt the program quite frequently with SIGURG (this is exacerbated in go >= 1.14). For that reason, if these C function return code is not 0 and errno is set to EINTR, we run them again transparently for the user. Also, it is possible that errno is set to ENOENT by the ioctl() syscall done underneath, and what this means is that the notification is not valid anymore (the kernel sets that). For users of this library to know when this notification is not valid anymore, we return it in this case too. This was useful for us to properly react to different failures in our seccomp agent in golang. To do this we can't rely on the return code from libseccomp, and need to check the errno, because libseccomp returns fixed codes for errors. Like, for example here[1], but it does this for the other functions changed here too. These issues were reported to libseccomp here: seccomp/libseccomp#302. [1]: https://github.com/seccomp/libseccomp/blob/main/src/system.c#L501-L502 Signed-off-by: Rodrigo Campos <[email protected]> Acked-by: Tom Hromatka <[email protected]> Signed-off-by: Paul Moore <[email protected]>
1 parent e5df66e commit 3879420

File tree

1 file changed

+43
-3
lines changed

1 file changed

+43
-3
lines changed

seccomp_internal.go

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,20 @@ func notifReceive(fd ScmpFd) (*ScmpNotifReq, error) {
765765
C.seccomp_notify_free(req, resp)
766766
}()
767767

768-
if retCode := C.seccomp_notify_receive(C.int(fd), req); retCode != 0 {
768+
for {
769+
retCode, errno := C.seccomp_notify_receive(C.int(fd), req)
770+
if retCode == 0 {
771+
break
772+
}
773+
774+
if errno == syscall.EINTR {
775+
continue
776+
}
777+
778+
if errno == syscall.ENOENT {
779+
return nil, errno
780+
}
781+
769782
return nil, errRc(retCode)
770783
}
771784

@@ -793,7 +806,20 @@ func notifRespond(fd ScmpFd, scmpResp *ScmpNotifResp) error {
793806

794807
scmpResp.toNative(resp)
795808

796-
if retCode := C.seccomp_notify_respond(C.int(fd), resp); retCode != 0 {
809+
for {
810+
retCode, errno := C.seccomp_notify_respond(C.int(fd), resp)
811+
if retCode == 0 {
812+
break
813+
}
814+
815+
if errno == syscall.EINTR {
816+
continue
817+
}
818+
819+
if errno == syscall.ENOENT {
820+
return errno
821+
}
822+
797823
return errRc(retCode)
798824
}
799825

@@ -807,8 +833,22 @@ func notifIDValid(fd ScmpFd, id uint64) error {
807833
return fmt.Errorf("seccomp notification requires API level >= 6; current level = %d", apiLevel)
808834
}
809835

810-
if retCode := C.seccomp_notify_id_valid(C.int(fd), C.uint64_t(id)); retCode != 0 {
836+
for {
837+
retCode, errno := C.seccomp_notify_id_valid(C.int(fd), C.uint64_t(id))
838+
if retCode == 0 {
839+
break
840+
}
841+
842+
if errno == syscall.EINTR {
843+
continue
844+
}
845+
846+
if errno == syscall.ENOENT {
847+
return errno
848+
}
849+
811850
return errRc(retCode)
812851
}
852+
813853
return nil
814854
}

0 commit comments

Comments
 (0)