@@ -235,6 +235,10 @@ struct seccomp_notif_addfd {
235
235
};
236
236
#endif
237
237
238
+ #ifndef SECCOMP_ADDFD_FLAG_SEND
239
+ #define SECCOMP_ADDFD_FLAG_SEND (1UL << 1) /* Addfd and return it, atomically */
240
+ #endif
241
+
238
242
struct seccomp_notif_addfd_small {
239
243
__u64 id ;
240
244
char weird [4 ];
@@ -3976,8 +3980,14 @@ TEST(user_notification_addfd)
3976
3980
ASSERT_GE (pid , 0 );
3977
3981
3978
3982
if (pid == 0 ) {
3983
+ /* fds will be added and this value is expected */
3979
3984
if (syscall (__NR_getppid ) != USER_NOTIF_MAGIC )
3980
3985
exit (1 );
3986
+
3987
+ /* Atomic addfd+send is received here. Check it is a valid fd */
3988
+ if (fcntl (syscall (__NR_getppid ), F_GETFD ) == -1 )
3989
+ exit (1 );
3990
+
3981
3991
exit (syscall (__NR_getppid ) != USER_NOTIF_MAGIC );
3982
3992
}
3983
3993
@@ -4056,6 +4066,30 @@ TEST(user_notification_addfd)
4056
4066
ASSERT_EQ (ioctl (listener , SECCOMP_IOCTL_NOTIF_RECV , & req ), 0 );
4057
4067
ASSERT_EQ (addfd .id , req .id );
4058
4068
4069
+ /* Verify we can do an atomic addfd and send */
4070
+ addfd .newfd = 0 ;
4071
+ addfd .flags = SECCOMP_ADDFD_FLAG_SEND ;
4072
+ fd = ioctl (listener , SECCOMP_IOCTL_NOTIF_ADDFD , & addfd );
4073
+
4074
+ /* Child has fds 0-6 and 42 used, we expect the lower fd available: 7 */
4075
+ EXPECT_EQ (fd , 7 );
4076
+ EXPECT_EQ (filecmp (getpid (), pid , memfd , fd ), 0 );
4077
+
4078
+ /*
4079
+ * This sets the ID of the ADD FD to the last request plus 1. The
4080
+ * notification ID increments 1 per notification.
4081
+ */
4082
+ addfd .id = req .id + 1 ;
4083
+
4084
+ /* This spins until the underlying notification is generated */
4085
+ while (ioctl (listener , SECCOMP_IOCTL_NOTIF_ADDFD , & addfd ) != -1 &&
4086
+ errno != - EINPROGRESS )
4087
+ nanosleep (& delay , NULL );
4088
+
4089
+ memset (& req , 0 , sizeof (req ));
4090
+ ASSERT_EQ (ioctl (listener , SECCOMP_IOCTL_NOTIF_RECV , & req ), 0 );
4091
+ ASSERT_EQ (addfd .id , req .id );
4092
+
4059
4093
resp .id = req .id ;
4060
4094
resp .error = 0 ;
4061
4095
resp .val = USER_NOTIF_MAGIC ;
@@ -4116,6 +4150,10 @@ TEST(user_notification_addfd_rlimit)
4116
4150
EXPECT_EQ (ioctl (listener , SECCOMP_IOCTL_NOTIF_ADDFD , & addfd ), -1 );
4117
4151
EXPECT_EQ (errno , EMFILE );
4118
4152
4153
+ addfd .flags = SECCOMP_ADDFD_FLAG_SEND ;
4154
+ EXPECT_EQ (ioctl (listener , SECCOMP_IOCTL_NOTIF_ADDFD , & addfd ), -1 );
4155
+ EXPECT_EQ (errno , EMFILE );
4156
+
4119
4157
addfd .newfd = 100 ;
4120
4158
addfd .flags = SECCOMP_ADDFD_FLAG_SETFD ;
4121
4159
EXPECT_EQ (ioctl (listener , SECCOMP_IOCTL_NOTIF_ADDFD , & addfd ), -1 );
0 commit comments