@@ -803,6 +803,198 @@ libcrun_configure_handler (struct container_entrypoint_s *args, libcrun_error_t
803803 return crun_make_error (err , EINVAL , "invalid handler specified `%s`" , annotation );
804804}
805805
806+ static int
807+ get_yajl_result (yajl_gen gen , char * * out , size_t * out_len )
808+ {
809+ const unsigned char * buf = NULL ;
810+ size_t buf_len = 0 ;
811+ int r ;
812+
813+ r = yajl_gen_get_buf (gen , & buf , & buf_len );
814+ if (UNLIKELY (r != yajl_gen_status_ok ))
815+ return r ;
816+
817+ * out_len = buf_len ;
818+
819+ * out = malloc (buf_len + 1 );
820+ if (* out == NULL )
821+ OOM ();
822+ memcpy (* out , buf , buf_len );
823+ (* out )[buf_len ] = '\0' ;
824+
825+ return yajl_gen_status_ok ;
826+ }
827+
828+ static int
829+ get_seccomp_receiver_fd_payload (libcrun_container_t * container , const char * status , pid_t own_pid ,
830+ char * * seccomp_fd_payload , size_t * seccomp_fd_payload_len , libcrun_error_t * err )
831+ {
832+ int r ;
833+ yajl_gen gen = NULL ;
834+ runtime_spec_schema_config_schema * def = container -> container_def ;
835+ const char * const OCI_VERSION = "0.2.0" ;
836+
837+ gen = yajl_gen_alloc (NULL );
838+ if (gen == NULL )
839+ return crun_make_error (err , 0 , "yajl_gen_alloc failed" );
840+
841+ yajl_gen_config (gen , yajl_gen_beautify , 1 );
842+ yajl_gen_config (gen , yajl_gen_validate_utf8 , 1 );
843+
844+ r = yajl_gen_map_open (gen );
845+ if (UNLIKELY (r != yajl_gen_status_ok ))
846+ goto exit ;
847+
848+ r = yajl_gen_string (gen , YAJL_STR ("ociVersion" ), strlen ("ociVersion" ));
849+ if (UNLIKELY (r != yajl_gen_status_ok ))
850+ goto exit ;
851+
852+ r = yajl_gen_string (gen , YAJL_STR (OCI_VERSION ), strlen (OCI_VERSION ));
853+ if (UNLIKELY (r != yajl_gen_status_ok ))
854+ goto exit ;
855+
856+ r = yajl_gen_string (gen , YAJL_STR ("fds" ), strlen ("fds" ));
857+ if (UNLIKELY (r != yajl_gen_status_ok ))
858+ goto exit ;
859+
860+ r = yajl_gen_array_open (gen );
861+ if (UNLIKELY (r != yajl_gen_status_ok ))
862+ goto exit ;
863+
864+ r = yajl_gen_string (gen , YAJL_STR ("seccompFd" ), strlen ("seccompFd" ));
865+ if (UNLIKELY (r != yajl_gen_status_ok ))
866+ goto exit ;
867+
868+ r = yajl_gen_array_close (gen );
869+ if (UNLIKELY (r != yajl_gen_status_ok ))
870+ goto exit ;
871+
872+ r = yajl_gen_string (gen , YAJL_STR ("pid" ), strlen ("pid" ));
873+ if (UNLIKELY (r != yajl_gen_status_ok ))
874+ goto exit ;
875+
876+ r = yajl_gen_integer (gen , own_pid );
877+ if (UNLIKELY (r != yajl_gen_status_ok ))
878+ goto exit ;
879+
880+ if (def && def -> linux && def -> linux -> seccomp )
881+ {
882+ const char * metadata = def -> linux -> seccomp -> listener_metadata ;
883+
884+ if (metadata )
885+ {
886+ r = yajl_gen_string (gen , YAJL_STR ("metadata" ), strlen ("metadata" ));
887+ if (UNLIKELY (r != yajl_gen_status_ok ))
888+ goto exit ;
889+
890+ r = yajl_gen_string (gen , YAJL_STR (metadata ), strlen (metadata ));
891+ if (UNLIKELY (r != yajl_gen_status_ok ))
892+ goto exit ;
893+ }
894+ }
895+
896+ /* State. */
897+ r = yajl_gen_string (gen , YAJL_STR ("state" ), strlen ("state" ));
898+ if (UNLIKELY (r != yajl_gen_status_ok ))
899+ goto exit ;
900+
901+ r = yajl_gen_map_open (gen );
902+ if (UNLIKELY (r != yajl_gen_status_ok ))
903+ goto exit ;
904+
905+ r = yajl_gen_string (gen , YAJL_STR ("ociVersion" ), strlen ("ociVersion" ));
906+ if (UNLIKELY (r != yajl_gen_status_ok ))
907+ goto exit ;
908+
909+ r = yajl_gen_string (gen , YAJL_STR (OCI_VERSION ), strlen (OCI_VERSION ));
910+ if (UNLIKELY (r != yajl_gen_status_ok ))
911+ goto exit ;
912+
913+ if (container -> context && container -> context -> id )
914+ {
915+ r = yajl_gen_string (gen , YAJL_STR ("id" ), strlen ("id" ));
916+ if (UNLIKELY (r != yajl_gen_status_ok ))
917+ goto exit ;
918+
919+ r = yajl_gen_string (gen , YAJL_STR (container -> context -> id ), strlen (container -> context -> id ));
920+ if (UNLIKELY (r != yajl_gen_status_ok ))
921+ goto exit ;
922+ }
923+
924+ r = yajl_gen_string (gen , YAJL_STR ("status" ), strlen ("status" ));
925+ if (UNLIKELY (r != yajl_gen_status_ok ))
926+ goto exit ;
927+
928+ r = yajl_gen_string (gen , YAJL_STR (status ), strlen (status ));
929+ if (UNLIKELY (r != yajl_gen_status_ok ))
930+ goto exit ;
931+
932+ r = yajl_gen_string (gen , YAJL_STR ("pid" ), strlen ("pid" ));
933+ if (UNLIKELY (r != yajl_gen_status_ok ))
934+ goto exit ;
935+
936+ r = yajl_gen_integer (gen , own_pid );
937+ if (UNLIKELY (r != yajl_gen_status_ok ))
938+ goto exit ;
939+
940+ if (container -> context && container -> context -> bundle )
941+ {
942+ r = yajl_gen_string (gen , YAJL_STR ("bundle" ), strlen ("bundle" ));
943+ if (UNLIKELY (r != yajl_gen_status_ok ))
944+ goto exit ;
945+
946+ r = yajl_gen_string (gen , YAJL_STR (container -> context -> bundle ), strlen (container -> context -> bundle ));
947+ if (UNLIKELY (r != yajl_gen_status_ok ))
948+ goto exit ;
949+ }
950+
951+ if (def -> annotations && def -> annotations -> len )
952+ {
953+ size_t i ;
954+
955+ r = yajl_gen_string (gen , YAJL_STR ("annotations" ), strlen ("annotations" ));
956+ if (UNLIKELY (r != yajl_gen_status_ok ))
957+ goto exit ;
958+
959+ r = yajl_gen_map_open (gen );
960+ if (UNLIKELY (r != yajl_gen_status_ok ))
961+ goto exit ;
962+
963+ for (i = 0 ; i < def -> annotations -> len ; i ++ )
964+ {
965+ const char * key = def -> annotations -> keys [i ];
966+ const char * val = def -> annotations -> values [i ];
967+
968+ r = yajl_gen_string (gen , YAJL_STR (key ), strlen (key ));
969+ if (UNLIKELY (r != yajl_gen_status_ok ))
970+ goto exit ;
971+
972+ r = yajl_gen_string (gen , YAJL_STR (val ), strlen (val ));
973+ if (UNLIKELY (r != yajl_gen_status_ok ))
974+ goto exit ;
975+ }
976+ r = yajl_gen_map_close (gen );
977+ if (UNLIKELY (r != yajl_gen_status_ok ))
978+ goto exit ;
979+ }
980+
981+ r = yajl_gen_map_close (gen );
982+ if (UNLIKELY (r != yajl_gen_status_ok ))
983+ goto exit ;
984+ /* End state. */
985+
986+ r = yajl_gen_map_close (gen );
987+ if (UNLIKELY (r != yajl_gen_status_ok ))
988+ goto exit ;
989+
990+ r = get_yajl_result (gen , seccomp_fd_payload , seccomp_fd_payload_len );
991+
992+ exit :
993+ yajl_gen_free (gen );
994+
995+ return yajl_error_to_crun_error (r , err );
996+ }
997+
806998/* Initialize the environment where the container process runs.
807999 It is used by the container init process. */
8081000static int
@@ -996,15 +1188,24 @@ container_init_setup (void *args, pid_t own_pid, char *notify_socket, int sync_s
9961188 {
9971189 char * * seccomp_flags = NULL ;
9981190 size_t seccomp_flags_len = 0 ;
1191+ cleanup_free char * seccomp_fd_payload = NULL ;
1192+ size_t seccomp_fd_payload_len = 0 ;
9991193
10001194 if (def -> linux && def -> linux -> seccomp )
10011195 {
10021196 seccomp_flags = def -> linux -> seccomp -> flags ;
10031197 seccomp_flags_len = def -> linux -> seccomp -> flags_len ;
10041198 }
10051199
1006- ret = libcrun_apply_seccomp (entrypoint_args -> seccomp_fd , entrypoint_args -> seccomp_receiver_fd , seccomp_flags ,
1007- seccomp_flags_len , err );
1200+ if (entrypoint_args -> seccomp_receiver_fd >= 0 )
1201+ {
1202+ ret = get_seccomp_receiver_fd_payload (container , "creating" , own_pid , & seccomp_fd_payload , & seccomp_fd_payload_len , err );
1203+ if (UNLIKELY (ret < 0 ))
1204+ return ret ;
1205+ }
1206+
1207+ ret = libcrun_apply_seccomp (entrypoint_args -> seccomp_fd , entrypoint_args -> seccomp_receiver_fd ,
1208+ seccomp_fd_payload , seccomp_fd_payload_len , seccomp_flags , seccomp_flags_len , err );
10081209 if (UNLIKELY (ret < 0 ))
10091210 return ret ;
10101211
@@ -1138,14 +1339,24 @@ container_init (void *args, char *notify_socket, int sync_socket, libcrun_error_
11381339 {
11391340 char * * seccomp_flags = NULL ;
11401341 size_t seccomp_flags_len = 0 ;
1342+ cleanup_free char * seccomp_fd_payload = NULL ;
1343+ size_t seccomp_fd_payload_len = 0 ;
11411344
11421345 if (def -> linux && def -> linux -> seccomp )
11431346 {
11441347 seccomp_flags = def -> linux -> seccomp -> flags ;
11451348 seccomp_flags_len = def -> linux -> seccomp -> flags_len ;
11461349 }
11471350
1148- ret = libcrun_apply_seccomp (entrypoint_args -> seccomp_fd , entrypoint_args -> seccomp_receiver_fd , seccomp_flags ,
1351+ if (entrypoint_args -> seccomp_receiver_fd >= 0 )
1352+ {
1353+ ret = get_seccomp_receiver_fd_payload (entrypoint_args -> container , "creating" , own_pid , & seccomp_fd_payload , & seccomp_fd_payload_len , err );
1354+ if (UNLIKELY (ret < 0 ))
1355+ return ret ;
1356+ }
1357+
1358+ ret = libcrun_apply_seccomp (entrypoint_args -> seccomp_fd , entrypoint_args -> seccomp_receiver_fd ,
1359+ seccomp_fd_payload , seccomp_fd_payload_len , seccomp_flags ,
11491360 seccomp_flags_len , err );
11501361 if (UNLIKELY (ret < 0 ))
11511362 return ret ;
@@ -1812,6 +2023,7 @@ get_seccomp_receiver_fd (libcrun_container_t *container, int *fd, int *self_rece
18122023 libcrun_error_t * err )
18132024{
18142025 const char * tmp ;
2026+ runtime_spec_schema_config_schema * def = container -> container_def ;
18152027
18162028 * fd = -1 ;
18172029 * self_receiver_fd = -1 ;
@@ -1831,7 +2043,10 @@ get_seccomp_receiver_fd (libcrun_container_t *container, int *fd, int *self_rece
18312043 * plugins = tmp ;
18322044 }
18332045
1834- tmp = find_annotation (container , "run.oci.seccomp.receiver" );
2046+ if (def && def -> linux && def -> linux -> seccomp && def -> linux -> seccomp -> listener_path )
2047+ tmp = def -> linux -> seccomp -> listener_path ;
2048+ else
2049+ tmp = find_annotation (container , "run.oci.seccomp.receiver" );
18352050 if (tmp == NULL )
18362051 tmp = getenv ("RUN_OCI_SECCOMP_RECEIVER" );
18372052 if (tmp )
@@ -2873,7 +3088,18 @@ libcrun_container_exec (libcrun_context_t *context, const char *id, runtime_spec
28733088
28743089 if (! process -> no_new_privileges )
28753090 {
2876- ret = libcrun_apply_seccomp (seccomp_fd , seccomp_receiver_fd , seccomp_flags , seccomp_flags_len , err );
3091+ cleanup_free char * seccomp_fd_payload = NULL ;
3092+ size_t seccomp_fd_payload_len = 0 ;
3093+
3094+ if (seccomp_receiver_fd >= 0 )
3095+ {
3096+ ret = get_seccomp_receiver_fd_payload (container , "running" , own_pid , & seccomp_fd_payload , & seccomp_fd_payload_len , err );
3097+ if (UNLIKELY (ret < 0 ))
3098+ return ret ;
3099+ }
3100+
3101+ ret = libcrun_apply_seccomp (seccomp_fd , seccomp_receiver_fd , seccomp_fd_payload ,
3102+ seccomp_fd_payload_len , seccomp_flags , seccomp_flags_len , err );
28773103 if (UNLIKELY (ret < 0 ))
28783104 return ret ;
28793105 close_and_reset (& seccomp_fd );
@@ -2898,9 +3124,20 @@ libcrun_container_exec (libcrun_context_t *context, const char *id, runtime_spec
28983124
28993125 if (process -> no_new_privileges )
29003126 {
2901- ret = libcrun_apply_seccomp (seccomp_fd , seccomp_receiver_fd , seccomp_flags , seccomp_flags_len , err );
3127+ cleanup_free char * seccomp_fd_payload = NULL ;
3128+ size_t seccomp_fd_payload_len = 0 ;
3129+
3130+ if (seccomp_receiver_fd >= 0 )
3131+ {
3132+ ret = get_seccomp_receiver_fd_payload (container , "running" , own_pid , & seccomp_fd_payload , & seccomp_fd_payload_len , err );
3133+ if (UNLIKELY (ret < 0 ))
3134+ return ret ;
3135+ }
3136+ ret = libcrun_apply_seccomp (seccomp_fd , seccomp_receiver_fd , seccomp_fd_payload ,
3137+ seccomp_fd_payload_len , seccomp_flags , seccomp_flags_len , err );
29023138 if (UNLIKELY (ret < 0 ))
29033139 return ret ;
3140+
29043141 close_and_reset (& seccomp_fd );
29053142 close_and_reset (& seccomp_receiver_fd );
29063143 }
0 commit comments