[PATCH v2 5/6] selftests/landlock: Repurpose scoped_abstract_unix_test.c for pathname sockets too.

Tingmao Wang m at maowtm.org
Mon Feb 2 00:06:02 UTC 2026


On 1/29/26 21:28, Mickaël Salaün wrote:
> [...]
> On Tue, Dec 30, 2025 at 05:20:23PM +0000, Tingmao Wang wrote:
>> [...]
>> @@ -308,6 +413,12 @@ TEST_F(scoped_audit, connect_to_child)
>>  	char buf;
>>  	int dgram_client;
>>  	struct audit_records records;
>> +	struct service_fixture *const dgram_address =
>> +		variant->abstract_socket ? &self->dgram_address_abstract :
>> +					   &self->dgram_address_pathname;
>> +	size_t log_match_remaining = 500;
> 
> const
> 
> Why this number?  Could you please follow the same logic as in
> matches_log_fs_extra()?

It's not a const since we decrement it below as we fill log_match with
stpncpy().

matches_log_fs_extra() uses 2*PATH_MAX + length of various fixed strings.
I guess since the path is a resolved absolute path which can vary based on
where this test is ran, it is safest to use a value based on PATH_MAX.  I
will update.

> 
>> +	char log_match[log_match_remaining];
>> +	char *log_match_cursor = log_match;
>>  
>>  	/* Makes sure there is no superfluous logged records. */
>>  	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
>> @@ -330,8 +441,8 @@ TEST_F(scoped_audit, connect_to_child)
>>  
>>  		dgram_server = socket(AF_UNIX, SOCK_DGRAM, 0);
>>  		ASSERT_LE(0, dgram_server);
>> -		ASSERT_EQ(0, bind(dgram_server, &self->dgram_address.unix_addr,
>> -				  self->dgram_address.unix_addr_len));
>> +		ASSERT_EQ(0, bind(dgram_server, &dgram_address->unix_addr,
>> +				  dgram_address->unix_addr_len));
>>  
>>  		/* Signals to the parent that child is listening. */
>>  		ASSERT_EQ(1, write(pipe_child[1], ".", 1));
>> @@ -345,7 +456,9 @@ TEST_F(scoped_audit, connect_to_child)
>>  	EXPECT_EQ(0, close(pipe_child[1]));
>>  	EXPECT_EQ(0, close(pipe_parent[0]));
>>  
>> -	create_scoped_domain(_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
>> +	create_scoped_domain(_metadata,
>> +			     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
>> +				     LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET);
>>  
>>  	/* Signals that the parent is in a domain, if any. */
>>  	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
>> @@ -355,19 +468,62 @@ TEST_F(scoped_audit, connect_to_child)
>>  
>>  	/* Waits for the child to listen */
>>  	ASSERT_EQ(1, read(pipe_child[0], &buf, 1));
>> -	err_dgram = connect(dgram_client, &self->dgram_address.unix_addr,
>> -			    self->dgram_address.unix_addr_len);
>> +	err_dgram = connect(dgram_client, &dgram_address->unix_addr,
>> +			    dgram_address->unix_addr_len);
>>  	EXPECT_EQ(-1, err_dgram);
>>  	EXPECT_EQ(EPERM, errno);
>>  
>> -	EXPECT_EQ(
>> -		0,
>> -		audit_match_record(
>> -			self->audit_fd, AUDIT_LANDLOCK_ACCESS,
>> +	if (variant->abstract_socket) {
>> +		log_match_cursor = stpncpy(
>> +			log_match,
>>  			REGEX_LANDLOCK_PREFIX
>>  			" blockers=scope\\.abstract_unix_socket path=" ABSTRACT_SOCKET_PATH_PREFIX
>>  			"[0-9A-F]\\+$",
>> -			NULL));
>> +			log_match_remaining);
>> +		log_match_remaining =
>> +			sizeof(log_match) - (log_match_cursor - log_match);
>> +		ASSERT_NE(0, log_match_remaining);
>> +	} else {
>> +		/*
>> +		 * It is assumed that absolute_path does not contain control
>> +		 * characters nor spaces, see audit_string_contains_control().
>> +		 */
>> +		char *absolute_path =
> 
> const char *absolute_path

Can't use const char * here since we free() it later:

scoped_unix_test.c:513:22: warning: passing argument 1 of ‘free’ discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
  513 |                 free(absolute_path);
      |                      ^~~~~~~~~~~~~

But I guess we can char *const.  Will update to:

		char *const absolute_path =
			realpath(dgram_address->unix_addr.sun_path, NULL);

> 
>> +			realpath(dgram_address->unix_addr.sun_path, NULL);
>> +
>> +		EXPECT_NE(NULL, absolute_path)
>> +		{
>> +			TH_LOG("realpath() failed: %s", strerror(errno));
>> +			return;
>> +		}
>> +
>> +		log_match_cursor =
>> +			stpncpy(log_match,
>> +				REGEX_LANDLOCK_PREFIX
>> +				" blockers=scope\\.pathname_unix_socket path=\"",
>> +				log_match_remaining);
>> +		log_match_remaining =
>> +			sizeof(log_match) - (log_match_cursor - log_match);
>> +		ASSERT_NE(0, log_match_remaining);
>> +		log_match_cursor = regex_escape(absolute_path, log_match_cursor,
>> +						log_match_remaining);
>> +		free(absolute_path);
>> +		if (log_match_cursor < 0) {
>> +			TH_LOG("regex_escape() failed (buffer too small)");
>> +			return;
>> +		}
>> +		log_match_remaining =
>> +			sizeof(log_match) - (log_match_cursor - log_match);
>> +		ASSERT_NE(0, log_match_remaining);
>> +		log_match_cursor =
>> +			stpncpy(log_match_cursor, "\"$", log_match_remaining);
>> +		log_match_remaining =
>> +			sizeof(log_match) - (log_match_cursor - log_match);
>> +		ASSERT_NE(0, log_match_remaining);
>> +	}
>> +
>> +	EXPECT_EQ(0, audit_match_record(self->audit_fd, AUDIT_LANDLOCK_ACCESS,
>> +					log_match, NULL));
>>  
>>  	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
>>  	EXPECT_EQ(0, close(dgram_client));
>> -- 
>> 2.52.0
>>
>>



More information about the Linux-security-module-archive mailing list