@@ -992,3 +992,126 @@ func PointSocketpair(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.Conte
992992 p .Exit = newExitMaybe (info )
993993 return p , pb .MessageType_MESSAGE_SYSCALL_SOCKETPAIR
994994}
995+
996+ // PointSelect converts select(2) syscall to proto.
997+ func PointSelect (t * kernel.Task , fields seccheck.FieldSet , cxtData * pb.ContextData , info kernel.SyscallInfo ) (proto.Message , pb.MessageType ) {
998+ nfds := int (info .Args [0 ].Int ())
999+ p := & pb.Select {
1000+ ContextData : cxtData ,
1001+ Sysno : uint64 (info .Sysno ),
1002+ Nfds : int64 (nfds ),
1003+ }
1004+
1005+ if nfds >= 0 && nfds <= fileCap {
1006+ nBytes := (nfds + 7 ) / 8
1007+ nBitsInLastPartialByte := nfds % 8
1008+
1009+ if r , err := CopyInFDSet (t , info .Args [1 ].Pointer (), nBytes , nBitsInLastPartialByte ); err == nil {
1010+ var fd int64
1011+ for i := 0 ; i < nBytes ; i ++ {
1012+ rV := r [i ]
1013+ m := byte (1 )
1014+ for j := 0 ; j < 8 ; j ++ {
1015+ if (rV & m ) != 0 {
1016+ p .ReadFds = append (p .ReadFds , fd )
1017+ }
1018+ fd ++
1019+ m <<= 1
1020+ }
1021+ }
1022+ }
1023+
1024+ if w , err := CopyInFDSet (t , info .Args [2 ].Pointer (), nBytes , nBitsInLastPartialByte ); err == nil {
1025+ for i := 0 ; i < nBytes ; i ++ {
1026+ wV := w [i ]
1027+ for wV != 0 {
1028+ wV &= (wV - 1 )
1029+ p .WriteNfds ++
1030+ }
1031+ }
1032+ }
1033+
1034+ if e , err := CopyInFDSet (t , info .Args [3 ].Pointer (), nBytes , nBitsInLastPartialByte ); err == nil {
1035+ for i := 0 ; i < nBytes ; i ++ {
1036+ eV := e [i ]
1037+ for eV != 0 {
1038+ eV &= (eV - 1 )
1039+ p .ExceptNfds ++
1040+ }
1041+ }
1042+ }
1043+ }
1044+
1045+ timeoutMs := int64 (- 1 )
1046+ if timevalAddr := info .Args [4 ].Pointer (); timevalAddr != 0 {
1047+ var timeval linux.Timeval
1048+ if _ , err := timeval .CopyIn (t , timevalAddr ); err == nil {
1049+ if timeval .Sec >= 0 && timeval .Usec >= 0 {
1050+ timeoutMs = timeval .ToNsecCapped () / 1e6
1051+ }
1052+ }
1053+ }
1054+ p .TimeoutMs = timeoutMs
1055+ p .Exit = newExitMaybe (info )
1056+ return p , pb .MessageType_MESSAGE_SYSCALL_SELECT
1057+ }
1058+
1059+ // PointPselect6 converts pselect6(2) syscall to proto.
1060+ func PointPselect6 (t * kernel.Task , fields seccheck.FieldSet , cxtData * pb.ContextData , info kernel.SyscallInfo ) (proto.Message , pb.MessageType ) {
1061+ nfds := int (info .Args [0 ].Int ())
1062+ p := & pb.Select {
1063+ ContextData : cxtData ,
1064+ Sysno : uint64 (info .Sysno ),
1065+ Nfds : int64 (nfds ),
1066+ }
1067+
1068+ if nfds >= 0 && nfds <= fileCap {
1069+ nBytes := (nfds + 7 ) / 8
1070+ nBitsInLastPartialByte := nfds % 8
1071+
1072+ if r , err := CopyInFDSet (t , info .Args [1 ].Pointer (), nBytes , nBitsInLastPartialByte ); err == nil {
1073+ var fd int64
1074+ for i := 0 ; i < nBytes ; i ++ {
1075+ rV := r [i ]
1076+ m := byte (1 )
1077+ for j := 0 ; j < 8 ; j ++ {
1078+ if (rV & m ) != 0 {
1079+ p .ReadFds = append (p .ReadFds , fd )
1080+ }
1081+ fd ++
1082+ m <<= 1
1083+ }
1084+ }
1085+ }
1086+
1087+ if w , err := CopyInFDSet (t , info .Args [2 ].Pointer (), nBytes , nBitsInLastPartialByte ); err == nil {
1088+ for i := 0 ; i < nBytes ; i ++ {
1089+ wV := w [i ]
1090+ for wV != 0 {
1091+ wV &= (wV - 1 )
1092+ p .WriteNfds ++
1093+ }
1094+ }
1095+ }
1096+
1097+ if e , err := CopyInFDSet (t , info .Args [3 ].Pointer (), nBytes , nBitsInLastPartialByte ); err == nil {
1098+ for i := 0 ; i < nBytes ; i ++ {
1099+ eV := e [i ]
1100+ for eV != 0 {
1101+ eV &= (eV - 1 )
1102+ p .ExceptNfds ++
1103+ }
1104+ }
1105+ }
1106+ }
1107+
1108+ timeoutMs := int64 (- 1 )
1109+ if timespecAddr := info .Args [4 ].Pointer (); timespecAddr != 0 {
1110+ if timeout , err := copyTimespecInToDuration (t , timespecAddr ); err == nil && timeout >= 0 {
1111+ timeoutMs = timeout .Milliseconds ()
1112+ }
1113+ }
1114+ p .TimeoutMs = timeoutMs
1115+ p .Exit = newExitMaybe (info )
1116+ return p , pb .MessageType_MESSAGE_SYSCALL_SELECT
1117+ }
0 commit comments