@@ -803,6 +803,197 @@ 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+ 
836+   gen  =  yajl_gen_alloc  (NULL );
837+   if  (gen  ==  NULL )
838+     return  crun_make_error  (err , 0 , "yajl_gen_alloc failed" );
839+ 
840+   yajl_gen_config  (gen , yajl_gen_beautify , 1 );
841+   yajl_gen_config  (gen , yajl_gen_validate_utf8 , 1 );
842+ 
843+   r  =  yajl_gen_map_open  (gen );
844+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
845+     goto exit ;
846+ 
847+   r  =  yajl_gen_string  (gen , YAJL_STR  ("ociVersion" ), strlen  ("ociVersion" ));
848+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
849+     goto exit ;
850+ 
851+   r  =  yajl_gen_string  (gen , YAJL_STR  ("0.2.0" ), strlen  ("0.2.0" ));
852+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
853+     goto exit ;
854+ 
855+   r  =  yajl_gen_string  (gen , YAJL_STR  ("fds" ), strlen  ("fds" ));
856+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
857+     goto exit ;
858+ 
859+   r  =  yajl_gen_array_open  (gen );
860+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
861+     goto exit ;
862+ 
863+   r  =  yajl_gen_string  (gen , YAJL_STR  ("seccompFd" ), strlen  ("seccompFd" ));
864+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
865+     goto exit ;
866+ 
867+   r  =  yajl_gen_array_close  (gen );
868+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
869+     goto exit ;
870+ 
871+   r  =  yajl_gen_string  (gen , YAJL_STR  ("pid" ), strlen  ("pid" ));
872+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
873+     goto exit ;
874+ 
875+   r  =  yajl_gen_integer  (gen , own_pid );
876+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
877+     goto exit ;
878+ 
879+   if  (def  &&  def -> linux  &&  def -> linux -> seccomp )
880+     {
881+       const  char  * metadata  =  def -> linux -> seccomp -> listener_metadata ;
882+ 
883+       if  (metadata )
884+         {
885+           r  =  yajl_gen_string  (gen , YAJL_STR  ("metadata" ), strlen  ("metadata" ));
886+           if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
887+             goto exit ;
888+ 
889+           r  =  yajl_gen_string  (gen , YAJL_STR  (metadata ), strlen  (metadata ));
890+           if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
891+             goto exit ;
892+         }
893+     }
894+ 
895+   /* State.  */ 
896+   r  =  yajl_gen_string  (gen , YAJL_STR  ("state" ), strlen  ("state" ));
897+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
898+     goto exit ;
899+ 
900+   r  =  yajl_gen_map_open  (gen );
901+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
902+     goto exit ;
903+ 
904+   r  =  yajl_gen_string  (gen , YAJL_STR  ("ociVersion" ), strlen  ("ociVersion" ));
905+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
906+     goto exit ;
907+ 
908+   r  =  yajl_gen_string  (gen , YAJL_STR  ("0.2.0" ), strlen  ("0.2.0" ));
909+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
910+     goto exit ;
911+ 
912+   if  (container -> context  &&  container -> context -> id )
913+     {
914+       r  =  yajl_gen_string  (gen , YAJL_STR  ("id" ), strlen  ("id" ));
915+       if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
916+         goto exit ;
917+ 
918+       r  =  yajl_gen_string  (gen , YAJL_STR  (container -> context -> id ), strlen  (container -> context -> id ));
919+       if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
920+         goto exit ;
921+     }
922+ 
923+   r  =  yajl_gen_string  (gen , YAJL_STR  ("status" ), strlen  ("status" ));
924+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
925+     goto exit ;
926+ 
927+   r  =  yajl_gen_string  (gen , YAJL_STR  (status ), strlen  (status ));
928+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
929+     goto exit ;
930+ 
931+   r  =  yajl_gen_string  (gen , YAJL_STR  ("pid" ), strlen  ("pid" ));
932+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
933+     goto exit ;
934+ 
935+   r  =  yajl_gen_integer  (gen , own_pid );
936+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
937+     goto exit ;
938+ 
939+   if  (container -> context  &&  container -> context -> bundle )
940+     {
941+       r  =  yajl_gen_string  (gen , YAJL_STR  ("bundle" ), strlen  ("bundle" ));
942+       if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
943+         goto exit ;
944+ 
945+       r  =  yajl_gen_string  (gen , YAJL_STR  (container -> context -> bundle ), strlen  (container -> context -> bundle ));
946+       if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
947+         goto exit ;
948+     }
949+ 
950+   if  (def -> annotations  &&  def -> annotations -> len )
951+     {
952+       size_t  i ;
953+ 
954+       r  =  yajl_gen_string  (gen , YAJL_STR  ("annotations" ), strlen  ("annotations" ));
955+       if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
956+         goto exit ;
957+ 
958+       r  =  yajl_gen_map_open  (gen );
959+       if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
960+         goto exit ;
961+ 
962+       for  (i  =  0 ; i  <  def -> annotations -> len ; i ++ )
963+         {
964+           const  char  * key  =  def -> annotations -> keys [i ];
965+           const  char  * val  =  def -> annotations -> values [i ];
966+ 
967+           r  =  yajl_gen_string  (gen , YAJL_STR  (key ), strlen  (key ));
968+           if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
969+             goto exit ;
970+ 
971+           r  =  yajl_gen_string  (gen , YAJL_STR  (val ), strlen  (val ));
972+           if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
973+             goto exit ;
974+         }
975+       r  =  yajl_gen_map_close  (gen );
976+       if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
977+         goto exit ;
978+     }
979+ 
980+   r  =  yajl_gen_map_close  (gen );
981+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
982+     goto exit ;
983+   /* End state.  */ 
984+ 
985+   r  =  yajl_gen_map_close  (gen );
986+   if  (UNLIKELY  (r  !=  yajl_gen_status_ok ))
987+     goto exit ;
988+ 
989+   r  =  get_yajl_result  (gen , seccomp_fd_payload , seccomp_fd_payload_len );
990+ 
991+ exit :
992+   yajl_gen_free  (gen );
993+ 
994+   return  yajl_error_to_crun_error  (r , err );
995+ }
996+ 
806997/* Initialize the environment where the container process runs. 
807998   It is used by the container init process.  */ 
808999static  int 
@@ -996,15 +1187,24 @@ container_init_setup (void *args, pid_t own_pid, char *notify_socket, int sync_s
9961187    {
9971188      char  * * seccomp_flags  =  NULL ;
9981189      size_t  seccomp_flags_len  =  0 ;
1190+       cleanup_free  char  * seccomp_fd_payload  =  NULL ;
1191+       size_t  seccomp_fd_payload_len  =  0 ;
9991192
10001193      if  (def -> linux  &&  def -> linux -> seccomp )
10011194        {
10021195          seccomp_flags  =  def -> linux -> seccomp -> flags ;
10031196          seccomp_flags_len  =  def -> linux -> seccomp -> flags_len ;
10041197        }
10051198
1006-       ret  =  libcrun_apply_seccomp  (entrypoint_args -> seccomp_fd , entrypoint_args -> seccomp_receiver_fd , seccomp_flags ,
1007-                                    seccomp_flags_len , err );
1199+       if  (entrypoint_args -> seccomp_receiver_fd  >= 0 )
1200+         {
1201+           ret  =  get_seccomp_receiver_fd_payload  (container , "creating" , own_pid , & seccomp_fd_payload , & seccomp_fd_payload_len , err );
1202+           if  (UNLIKELY  (ret  <  0 ))
1203+             return  ret ;
1204+         }
1205+ 
1206+       ret  =  libcrun_apply_seccomp  (entrypoint_args -> seccomp_fd , entrypoint_args -> seccomp_receiver_fd ,
1207+                                    seccomp_fd_payload , seccomp_fd_payload_len , seccomp_flags , seccomp_flags_len , err );
10081208      if  (UNLIKELY  (ret  <  0 ))
10091209        return  ret ;
10101210
@@ -1138,14 +1338,24 @@ container_init (void *args, char *notify_socket, int sync_socket, libcrun_error_
11381338    {
11391339      char  * * seccomp_flags  =  NULL ;
11401340      size_t  seccomp_flags_len  =  0 ;
1341+       cleanup_free  char  * seccomp_fd_payload  =  NULL ;
1342+       size_t  seccomp_fd_payload_len  =  0 ;
11411343
11421344      if  (def -> linux  &&  def -> linux -> seccomp )
11431345        {
11441346          seccomp_flags  =  def -> linux -> seccomp -> flags ;
11451347          seccomp_flags_len  =  def -> linux -> seccomp -> flags_len ;
11461348        }
11471349
1148-       ret  =  libcrun_apply_seccomp  (entrypoint_args -> seccomp_fd , entrypoint_args -> seccomp_receiver_fd , seccomp_flags ,
1350+       if  (entrypoint_args -> seccomp_receiver_fd  >= 0 )
1351+         {
1352+           ret  =  get_seccomp_receiver_fd_payload  (entrypoint_args -> container , "creating" , own_pid , & seccomp_fd_payload , & seccomp_fd_payload_len , err );
1353+           if  (UNLIKELY  (ret  <  0 ))
1354+             return  ret ;
1355+         }
1356+ 
1357+       ret  =  libcrun_apply_seccomp  (entrypoint_args -> seccomp_fd , entrypoint_args -> seccomp_receiver_fd ,
1358+                                    seccomp_fd_payload , seccomp_fd_payload_len , seccomp_flags ,
11491359                                   seccomp_flags_len , err );
11501360      if  (UNLIKELY  (ret  <  0 ))
11511361        return  ret ;
@@ -1812,6 +2022,7 @@ get_seccomp_receiver_fd (libcrun_container_t *container, int *fd, int *self_rece
18122022                         libcrun_error_t  * err )
18132023{
18142024  const  char  * tmp ;
2025+   runtime_spec_schema_config_schema  * def  =  container -> container_def ;
18152026
18162027  * fd  =  -1 ;
18172028  * self_receiver_fd  =  -1 ;
@@ -1831,7 +2042,10 @@ get_seccomp_receiver_fd (libcrun_container_t *container, int *fd, int *self_rece
18312042      * plugins  =  tmp ;
18322043    }
18332044
1834-   tmp  =  find_annotation  (container , "run.oci.seccomp.receiver" );
2045+   if  (def  &&  def -> linux  &&  def -> linux -> seccomp  &&  def -> linux -> seccomp -> listener_path )
2046+     tmp  =  def -> linux -> seccomp -> listener_path ;
2047+   else 
2048+     tmp  =  find_annotation  (container , "run.oci.seccomp.receiver" );
18352049  if  (tmp  ==  NULL )
18362050    tmp  =  getenv  ("RUN_OCI_SECCOMP_RECEIVER" );
18372051  if  (tmp )
@@ -2872,7 +3086,18 @@ libcrun_container_exec (libcrun_context_t *context, const char *id, runtime_spec
28723086
28733087      if  (! process -> no_new_privileges )
28743088        {
2875-           ret  =  libcrun_apply_seccomp  (seccomp_fd , seccomp_receiver_fd , seccomp_flags , seccomp_flags_len , err );
3089+           cleanup_free  char  * seccomp_fd_payload  =  NULL ;
3090+           size_t  seccomp_fd_payload_len  =  0 ;
3091+ 
3092+           if  (seccomp_receiver_fd  >= 0 )
3093+             {
3094+               ret  =  get_seccomp_receiver_fd_payload  (container , "running" , own_pid , & seccomp_fd_payload , & seccomp_fd_payload_len , err );
3095+               if  (UNLIKELY  (ret  <  0 ))
3096+                 return  ret ;
3097+             }
3098+ 
3099+           ret  =  libcrun_apply_seccomp  (seccomp_fd , seccomp_receiver_fd , seccomp_fd_payload ,
3100+                                        seccomp_fd_payload_len , seccomp_flags , seccomp_flags_len , err );
28763101          if  (UNLIKELY  (ret  <  0 ))
28773102            return  ret ;
28783103          close_and_reset  (& seccomp_fd );
@@ -2897,9 +3122,20 @@ libcrun_container_exec (libcrun_context_t *context, const char *id, runtime_spec
28973122
28983123      if  (process -> no_new_privileges )
28993124        {
2900-           ret  =  libcrun_apply_seccomp  (seccomp_fd , seccomp_receiver_fd , seccomp_flags , seccomp_flags_len , err );
3125+           cleanup_free  char  * seccomp_fd_payload  =  NULL ;
3126+           size_t  seccomp_fd_payload_len  =  0 ;
3127+ 
3128+           if  (seccomp_receiver_fd  >= 0 )
3129+             {
3130+               ret  =  get_seccomp_receiver_fd_payload  (container , "running" , own_pid , & seccomp_fd_payload , & seccomp_fd_payload_len , err );
3131+               if  (UNLIKELY  (ret  <  0 ))
3132+                 return  ret ;
3133+             }
3134+           ret  =  libcrun_apply_seccomp  (seccomp_fd , seccomp_receiver_fd , seccomp_fd_payload ,
3135+                                        seccomp_fd_payload_len , seccomp_flags , seccomp_flags_len , err );
29013136          if  (UNLIKELY  (ret  <  0 ))
29023137            return  ret ;
3138+ 
29033139          close_and_reset  (& seccomp_fd );
29043140          close_and_reset  (& seccomp_receiver_fd );
29053141        }
0 commit comments