@@ -621,4 +621,254 @@ TEST_F(outside_socket, socket_with_different_domain)
621621 _metadata -> exit_code = KSFT_FAIL ;
622622}
623623
624+ static const char stream_path [] = TMP_DIR "/stream.sock" ;
625+ static const char dgram_path [] = TMP_DIR "/dgram.sock" ;
626+
627+ /* clang-format off */
628+ FIXTURE (various_address_sockets ) {};
629+ /* clang-format on */
630+
631+ FIXTURE_VARIANT (various_address_sockets )
632+ {
633+ const int domain ;
634+ };
635+
636+ /* clang-format off */
637+ FIXTURE_VARIANT_ADD (various_address_sockets , pathname_socket_scoped_domain ) {
638+ /* clang-format on */
639+ .domain = SCOPE_SANDBOX ,
640+ };
641+
642+ /* clang-format off */
643+ FIXTURE_VARIANT_ADD (various_address_sockets , pathname_socket_other_domain ) {
644+ /* clang-format on */
645+ .domain = OTHER_SANDBOX ,
646+ };
647+
648+ /* clang-format off */
649+ FIXTURE_VARIANT_ADD (various_address_sockets , pathname_socket_no_domain ) {
650+ /* clang-format on */
651+ .domain = NO_SANDBOX ,
652+ };
653+
654+ FIXTURE_SETUP (various_address_sockets )
655+ {
656+ drop_caps (_metadata );
657+
658+ umask (0077 );
659+ ASSERT_EQ (0 , mkdir (TMP_DIR , 0700 ));
660+ }
661+
662+ FIXTURE_TEARDOWN (various_address_sockets )
663+ {
664+ EXPECT_EQ (0 , unlink (stream_path ));
665+ EXPECT_EQ (0 , unlink (dgram_path ));
666+ EXPECT_EQ (0 , rmdir (TMP_DIR ));
667+ }
668+
669+ TEST_F (various_address_sockets , scoped_pathname_sockets )
670+ {
671+ socklen_t size_stream , size_dgram ;
672+ pid_t child ;
673+ int status ;
674+ char buf_child , buf_parent ;
675+ int pipe_parent [2 ];
676+ int unnamed_sockets [2 ];
677+ int stream_pathname_socket , dgram_pathname_socket ,
678+ stream_abstract_socket , dgram_abstract_socket , data_socket ;
679+ struct service_fixture stream_abstract_addr , dgram_abstract_addr ;
680+ struct sockaddr_un stream_pathname_addr = {
681+ .sun_family = AF_UNIX ,
682+ };
683+ struct sockaddr_un dgram_pathname_addr = {
684+ .sun_family = AF_UNIX ,
685+ };
686+
687+ /* Pathname address. */
688+ snprintf (stream_pathname_addr .sun_path ,
689+ sizeof (stream_pathname_addr .sun_path ), "%s" , stream_path );
690+ size_stream = offsetof(struct sockaddr_un , sun_path ) +
691+ strlen (stream_pathname_addr .sun_path );
692+ snprintf (dgram_pathname_addr .sun_path ,
693+ sizeof (dgram_pathname_addr .sun_path ), "%s" , dgram_path );
694+ size_dgram = offsetof(struct sockaddr_un , sun_path ) +
695+ strlen (dgram_pathname_addr .sun_path );
696+
697+ /* Abstract address. */
698+ memset (& stream_abstract_addr , 0 , sizeof (stream_abstract_addr ));
699+ set_unix_address (& stream_abstract_addr , 0 );
700+ memset (& dgram_abstract_addr , 0 , sizeof (dgram_abstract_addr ));
701+ set_unix_address (& dgram_abstract_addr , 1 );
702+
703+ /* Unnamed address for datagram socket. */
704+ ASSERT_EQ (0 , socketpair (AF_UNIX , SOCK_DGRAM , 0 , unnamed_sockets ));
705+
706+ ASSERT_EQ (0 , pipe2 (pipe_parent , O_CLOEXEC ));
707+
708+ child = fork ();
709+ ASSERT_LE (0 , child );
710+ if (child == 0 ) {
711+ int err ;
712+
713+ EXPECT_EQ (0 , close (pipe_parent [1 ]));
714+ EXPECT_EQ (0 , close (unnamed_sockets [1 ]));
715+
716+ if (variant -> domain == SCOPE_SANDBOX )
717+ create_scoped_domain (
718+ _metadata , LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET );
719+ else if (variant -> domain == OTHER_SANDBOX )
720+ create_fs_domain (_metadata );
721+
722+ /* Waits for parent to listen. */
723+ ASSERT_EQ (1 , read (pipe_parent [0 ], & buf_child , 1 ));
724+ EXPECT_EQ (0 , close (pipe_parent [0 ]));
725+
726+ /* Checks that we can send data through a datagram socket. */
727+ ASSERT_EQ (1 , write (unnamed_sockets [0 ], "a" , 1 ));
728+ EXPECT_EQ (0 , close (unnamed_sockets [0 ]));
729+
730+ /* Connects with pathname sockets. */
731+ stream_pathname_socket = socket (AF_UNIX , SOCK_STREAM , 0 );
732+ ASSERT_LE (0 , stream_pathname_socket );
733+ ASSERT_EQ (0 , connect (stream_pathname_socket ,
734+ & stream_pathname_addr , size_stream ));
735+ ASSERT_EQ (1 , write (stream_pathname_socket , "b" , 1 ));
736+ EXPECT_EQ (0 , close (stream_pathname_socket ));
737+
738+ /* Sends without connection. */
739+ dgram_pathname_socket = socket (AF_UNIX , SOCK_DGRAM , 0 );
740+ ASSERT_LE (0 , dgram_pathname_socket );
741+ err = sendto (dgram_pathname_socket , "c" , 1 , 0 ,
742+ & dgram_pathname_addr , size_dgram );
743+ EXPECT_EQ (1 , err );
744+
745+ /* Sends with connection. */
746+ ASSERT_EQ (0 , connect (dgram_pathname_socket ,
747+ & dgram_pathname_addr , size_dgram ));
748+ ASSERT_EQ (1 , write (dgram_pathname_socket , "d" , 1 ));
749+ EXPECT_EQ (0 , close (dgram_pathname_socket ));
750+
751+ /* Connects with abstract sockets. */
752+ stream_abstract_socket = socket (AF_UNIX , SOCK_STREAM , 0 );
753+ ASSERT_LE (0 , stream_abstract_socket );
754+ err = connect (stream_abstract_socket ,
755+ & stream_abstract_addr .unix_addr ,
756+ stream_abstract_addr .unix_addr_len );
757+ if (variant -> domain == SCOPE_SANDBOX ) {
758+ EXPECT_EQ (-1 , err );
759+ EXPECT_EQ (EPERM , errno );
760+ } else {
761+ EXPECT_EQ (0 , err );
762+ ASSERT_EQ (1 , write (stream_abstract_socket , "e" , 1 ));
763+ }
764+ EXPECT_EQ (0 , close (stream_abstract_socket ));
765+
766+ /* Sends without connection. */
767+ dgram_abstract_socket = socket (AF_UNIX , SOCK_DGRAM , 0 );
768+ ASSERT_LE (0 , dgram_abstract_socket );
769+ err = sendto (dgram_abstract_socket , "f" , 1 , 0 ,
770+ & dgram_abstract_addr .unix_addr ,
771+ dgram_abstract_addr .unix_addr_len );
772+ if (variant -> domain == SCOPE_SANDBOX ) {
773+ EXPECT_EQ (-1 , err );
774+ EXPECT_EQ (EPERM , errno );
775+ } else {
776+ EXPECT_EQ (1 , err );
777+ }
778+
779+ /* Sends with connection. */
780+ err = connect (dgram_abstract_socket ,
781+ & dgram_abstract_addr .unix_addr ,
782+ dgram_abstract_addr .unix_addr_len );
783+ if (variant -> domain == SCOPE_SANDBOX ) {
784+ EXPECT_EQ (-1 , err );
785+ EXPECT_EQ (EPERM , errno );
786+ } else {
787+ EXPECT_EQ (0 , err );
788+ ASSERT_EQ (1 , write (dgram_abstract_socket , "g" , 1 ));
789+ }
790+ EXPECT_EQ (0 , close (dgram_abstract_socket ));
791+
792+ _exit (_metadata -> exit_code );
793+ return ;
794+ }
795+ EXPECT_EQ (0 , close (pipe_parent [0 ]));
796+ EXPECT_EQ (0 , close (unnamed_sockets [0 ]));
797+
798+ /* Sets up pathname servers. */
799+ stream_pathname_socket = socket (AF_UNIX , SOCK_STREAM , 0 );
800+ ASSERT_LE (0 , stream_pathname_socket );
801+ ASSERT_EQ (0 , bind (stream_pathname_socket , & stream_pathname_addr ,
802+ size_stream ));
803+ ASSERT_EQ (0 , listen (stream_pathname_socket , backlog ));
804+
805+ dgram_pathname_socket = socket (AF_UNIX , SOCK_DGRAM , 0 );
806+ ASSERT_LE (0 , dgram_pathname_socket );
807+ ASSERT_EQ (0 , bind (dgram_pathname_socket , & dgram_pathname_addr ,
808+ size_dgram ));
809+
810+ /* Sets up abstract servers. */
811+ stream_abstract_socket = socket (AF_UNIX , SOCK_STREAM , 0 );
812+ ASSERT_LE (0 , stream_abstract_socket );
813+ ASSERT_EQ (0 ,
814+ bind (stream_abstract_socket , & stream_abstract_addr .unix_addr ,
815+ stream_abstract_addr .unix_addr_len ));
816+
817+ dgram_abstract_socket = socket (AF_UNIX , SOCK_DGRAM , 0 );
818+ ASSERT_LE (0 , dgram_abstract_socket );
819+ ASSERT_EQ (0 , bind (dgram_abstract_socket , & dgram_abstract_addr .unix_addr ,
820+ dgram_abstract_addr .unix_addr_len ));
821+ ASSERT_EQ (0 , listen (stream_abstract_socket , backlog ));
822+
823+ ASSERT_EQ (1 , write (pipe_parent [1 ], "." , 1 ));
824+ EXPECT_EQ (0 , close (pipe_parent [1 ]));
825+
826+ /* Reads from unnamed socket. */
827+ ASSERT_EQ (1 , read (unnamed_sockets [1 ], & buf_parent , sizeof (buf_parent )));
828+ ASSERT_EQ ('a' , buf_parent );
829+ EXPECT_LE (0 , close (unnamed_sockets [1 ]));
830+
831+ /* Reads from pathname sockets. */
832+ data_socket = accept (stream_pathname_socket , NULL , NULL );
833+ ASSERT_LE (0 , data_socket );
834+ ASSERT_EQ (1 , read (data_socket , & buf_parent , sizeof (buf_parent )));
835+ ASSERT_EQ ('b' , buf_parent );
836+ EXPECT_EQ (0 , close (data_socket ));
837+ EXPECT_EQ (0 , close (stream_pathname_socket ));
838+
839+ ASSERT_EQ (1 ,
840+ read (dgram_pathname_socket , & buf_parent , sizeof (buf_parent )));
841+ ASSERT_EQ ('c' , buf_parent );
842+ ASSERT_EQ (1 ,
843+ read (dgram_pathname_socket , & buf_parent , sizeof (buf_parent )));
844+ ASSERT_EQ ('d' , buf_parent );
845+ EXPECT_EQ (0 , close (dgram_pathname_socket ));
846+
847+ if (variant -> domain != SCOPE_SANDBOX ) {
848+ /* Reads from abstract sockets if allowed to send. */
849+ data_socket = accept (stream_abstract_socket , NULL , NULL );
850+ ASSERT_LE (0 , data_socket );
851+ ASSERT_EQ (1 ,
852+ read (data_socket , & buf_parent , sizeof (buf_parent )));
853+ ASSERT_EQ ('e' , buf_parent );
854+ EXPECT_EQ (0 , close (data_socket ));
855+
856+ ASSERT_EQ (1 , read (dgram_abstract_socket , & buf_parent ,
857+ sizeof (buf_parent )));
858+ ASSERT_EQ ('f' , buf_parent );
859+ ASSERT_EQ (1 , read (dgram_abstract_socket , & buf_parent ,
860+ sizeof (buf_parent )));
861+ ASSERT_EQ ('g' , buf_parent );
862+ }
863+
864+ /* Waits for all abstract socket tests. */
865+ ASSERT_EQ (child , waitpid (child , & status , 0 ));
866+ EXPECT_EQ (0 , close (stream_abstract_socket ));
867+ EXPECT_EQ (0 , close (dgram_abstract_socket ));
868+
869+ if (WIFSIGNALED (status ) || !WIFEXITED (status ) ||
870+ WEXITSTATUS (status ) != EXIT_SUCCESS )
871+ _metadata -> exit_code = KSFT_FAIL ;
872+ }
873+
624874TEST_HARNESS_MAIN
0 commit comments