Skip to content

Commit f76ca8a

Browse files
ZakariaTalbiMiguelCompany
authored andcommitted
Fix CVEs in Access Control parser
This fixes CVE-2026-45094, CVE-2026-45095, and CVE-2026-45096 by properly checking for `nullptr` before dereferencing pointers. This is a squashed commit of a privately reviewed branch. Signed-off-by: Zakaria Talbi Lalmi <zakariatalbi@eprosima.com> Reviewed-by: Miguel Company <miguelcompany@eprosima.com>
1 parent d96f0eb commit f76ca8a

9 files changed

Lines changed: 297 additions & 15 deletions

src/cpp/security/accesscontrol/GovernanceParser.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,16 @@ bool GovernanceParser::parse_topic_rule(
530530
{
531531
if (strcmp(node->Name(), TopicExpression_str) == 0)
532532
{
533-
rule.topic_expression = node->GetText();
533+
if (node->GetText() != nullptr)
534+
{
535+
rule.topic_expression = node->GetText();
536+
}
537+
else
538+
{
539+
EPROSIMA_LOG_ERROR(XMLPARSER, "Expected topic name in " << TopicExpression_str
540+
<< " tag. Line " << PRINTLINE(node));
541+
return false;
542+
}
534543
}
535544
else
536545
{

src/cpp/security/accesscontrol/PermissionsParser.cpp

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,24 @@ bool PermissionsParser::parse_stream(
7777
if (strcmp(root->Name(), Root_str) == 0)
7878
{
7979
tinyxml2::XMLElement* permission_node = root->FirstChildElement();
80-
if (strcmp(permission_node->Name(), Permission_str) == 0)
80+
if (permission_node != nullptr)
8181
{
82-
returned_value = parse_permissions(permission_node);
82+
if (strcmp(permission_node->Name(), Permission_str) == 0)
83+
{
84+
returned_value = parse_permissions(permission_node);
85+
}
86+
else
87+
{
88+
EPROSIMA_LOG_ERROR(XMLPARSER,
89+
"Invalid tag. Expected " << Permission_str << " tag. Line " << PRINTLINE(
90+
permission_node));
91+
}
8392
}
8493
else
8594
{
8695
EPROSIMA_LOG_ERROR(XMLPARSER, "Invalid tag. Expected " << Permission_str << " tag. Line " << PRINTLINE(
8796
permission_node));
97+
8898
}
8999
}
90100
else
@@ -339,23 +349,32 @@ bool PermissionsParser::parse_validity(
339349
{
340350
if (strcmp(node->Name(), NotAfter_str) == 0)
341351
{
342-
#if _MSC_VER != 1800
343-
memset(&time, 0, sizeof(struct tm));
344-
stream.str(node->GetText());
345-
stream.clear();
346-
stream >> std::get_time(&time, "%Y-%m-%dT%T");
347-
348-
if (!stream.fail())
352+
if (node->GetText() != nullptr)
349353
{
350-
validity.not_after = std::mktime(&time);
354+
#if _MSC_VER != 1800
355+
memset(&time, 0, sizeof(struct tm));
356+
stream.str(node->GetText());
357+
stream.clear();
358+
stream >> std::get_time(&time, "%Y-%m-%dT%T");
359+
360+
if (!stream.fail())
361+
{
362+
validity.not_after = std::mktime(&time);
351363
#endif // if _MSC_VER != 1800
352-
returned_value = true;
364+
returned_value = true;
365+
}
366+
else
367+
{
368+
EPROSIMA_LOG_ERROR(XMLPARSER,
369+
"Fail parsing datetime value in " << NotAfter_str << " tag. Line "
370+
<< PRINTLINE(
371+
node));
372+
}
353373
}
354374
else
355375
{
356-
EPROSIMA_LOG_ERROR(XMLPARSER, "Fail parsing datetime value in " << NotAfter_str << " tag. Line " <<
357-
PRINTLINE(
358-
node));
376+
EPROSIMA_LOG_ERROR(XMLPARSER, "Expected " << NotAfter_str << " tag. Line "
377+
<< PRINTLINE(node));
359378
}
360379
#if _MSC_VER != 1800
361380
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
MIME-Version: 1.0
2+
Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----FAD38CC2FC09E3814DC9BD8D7FBE156D"
3+
4+
This is an S/MIME signed message
5+
6+
------FAD38CC2FC09E3814DC9BD8D7FBE156D
7+
Content-Type: text/plain
8+
9+
<?xml version="1.0" encoding="utf-8"?>
10+
<dds>
11+
<domain_access_rules>
12+
<domain_rule>
13+
<domains><id>0</id></domains>
14+
<allow_unauthenticated_participants>false</allow_unauthenticated_participants>
15+
<enable_join_access_control>true</enable_join_access_control>
16+
<discovery_protection_kind>ENCRYPT</discovery_protection_kind>
17+
<liveliness_protection_kind>ENCRYPT</liveliness_protection_kind>
18+
<rtps_protection_kind>ENCRYPT</rtps_protection_kind>
19+
<topic_access_rules>
20+
<topic_rule>
21+
<topic_expression></topic_expression>
22+
<enable_discovery_protection>true</enable_discovery_protection>
23+
<enable_liveliness_protection>true</enable_liveliness_protection>
24+
<enable_read_access_control>true</enable_read_access_control>
25+
<enable_write_access_control>true</enable_write_access_control>
26+
<metadata_protection_kind>ENCRYPT</metadata_protection_kind>
27+
<data_protection_kind>ENCRYPT</data_protection_kind>
28+
</topic_rule>
29+
</topic_access_rules>
30+
</domain_rule>
31+
</domain_access_rules>
32+
</dds>
33+
------FAD38CC2FC09E3814DC9BD8D7FBE156D
34+
Content-Type: application/x-pkcs7-signature; name="smime.p7s"
35+
Content-Transfer-Encoding: base64
36+
Content-Disposition: attachment; filename="smime.p7s"
37+
38+
MIIEeQYJKoZIhvcNAQcCoIIEajCCBGYCAQExDzANBglghkgBZQMEAgEFADALBgkq
39+
hkiG9w0BBwGgggJAMIICPDCCAeOgAwIBAgIJALZwpgo2sxthMAoGCCqGSM49BAMC
40+
MIGaMQswCQYDVQQGEwJFUzELMAkGA1UECAwCTUExFDASBgNVBAcMC1RyZXMgQ2Fu
41+
dG9zMREwDwYDVQQKDAhlUHJvc2ltYTERMA8GA1UECwwIZVByb3NpbWExHjAcBgNV
42+
BAMMFWVQcm9zaW1hIE1haW4gVGVzdCBDQTEiMCAGCSqGSIb3DQEJARYTbWFpbmNh
43+
QGVwcm9zaW1hLmNvbTAeFw0xNzA5MDYwOTAzMDNaFw0yNzA5MDQwOTAzMDNaMIGa
44+
MQswCQYDVQQGEwJFUzELMAkGA1UECAwCTUExFDASBgNVBAcMC1RyZXMgQ2FudG9z
45+
MREwDwYDVQQKDAhlUHJvc2ltYTERMA8GA1UECwwIZVByb3NpbWExHjAcBgNVBAMM
46+
FWVQcm9zaW1hIE1haW4gVGVzdCBDQTEiMCAGCSqGSIb3DQEJARYTbWFpbmNhQGVw
47+
cm9zaW1hLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGLlhB3WQ8l1fpUE
48+
3DfOoulA/de38Zfj7hmpKtOnxiH2q6RJbwhxvJeA7R7mkmAKaJKmzx695BjyiXVS
49+
7bE7vgejEDAOMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgVTY1BEvT
50+
4pw3GyBMzaUqmp69wi0kBkyOgq04OhyJ13UCICR125vvt0fUhXsXaxOAx28E4Ac9
51+
SVxpI+3UYs2kV5n0MYIB/TCCAfkCAQEwgagwgZoxCzAJBgNVBAYTAkVTMQswCQYD
52+
VQQIDAJNQTEUMBIGA1UEBwwLVHJlcyBDYW50b3MxETAPBgNVBAoMCGVQcm9zaW1h
53+
MREwDwYDVQQLDAhlUHJvc2ltYTEeMBwGA1UEAwwVZVByb3NpbWEgTWFpbiBUZXN0
54+
IENBMSIwIAYJKoZIhvcNAQkBFhNtYWluY2FAZXByb3NpbWEuY29tAgkAtnCmCjaz
55+
G2EwDQYJYIZIAWUDBAIBBQCggeQwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAc
56+
BgkqhkiG9w0BCQUxDxcNMjYwNDMwMTQzNDM4WjAvBgkqhkiG9w0BCQQxIgQg7J5R
57+
Rt5uv/Pte/C7Out8JlPrkAApQpEhkXmmBNR+AUUweQYJKoZIhvcNAQkPMWwwajAL
58+
BglghkgBZQMEASowCwYJYIZIAWUDBAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0D
59+
BzAOBggqhkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZI
60+
hvcNAwICASgwCgYIKoZIzj0EAwIERzBFAiBpPBlkLhsCq9M8DRvfIIO+2qJZjfF+
61+
Cv5oLt8AIn+StAIhAIoe3kIzSu4aK07FAI7+MDaokFwDpj7Z7IfxJXtXwdOg
62+
63+
------FAD38CC2FC09E3814DC9BD8D7FBE156D--
64+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<dds>
3+
<domain_access_rules>
4+
<domain_rule>
5+
<domains><id>0</id></domains>
6+
<allow_unauthenticated_participants>false</allow_unauthenticated_participants>
7+
<enable_join_access_control>true</enable_join_access_control>
8+
<discovery_protection_kind>ENCRYPT</discovery_protection_kind>
9+
<liveliness_protection_kind>ENCRYPT</liveliness_protection_kind>
10+
<rtps_protection_kind>ENCRYPT</rtps_protection_kind>
11+
<topic_access_rules>
12+
<topic_rule>
13+
<topic_expression></topic_expression>
14+
<enable_discovery_protection>true</enable_discovery_protection>
15+
<enable_liveliness_protection>true</enable_liveliness_protection>
16+
<enable_read_access_control>true</enable_read_access_control>
17+
<enable_write_access_control>true</enable_write_access_control>
18+
<metadata_protection_kind>ENCRYPT</metadata_protection_kind>
19+
<data_protection_kind>ENCRYPT</data_protection_kind>
20+
</topic_rule>
21+
</topic_access_rules>
22+
</domain_rule>
23+
</domain_access_rules>
24+
</dds>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
MIME-Version: 1.0
2+
Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----8E2E4BD3027D97C6C2B82D6CC5F14AEB"
3+
4+
This is an S/MIME signed message
5+
6+
------8E2E4BD3027D97C6C2B82D6CC5F14AEB
7+
Content-Type: text/plain
8+
9+
<?xml version="1.0" encoding="utf-8"?>
10+
<dds></dds>
11+
------8E2E4BD3027D97C6C2B82D6CC5F14AEB
12+
Content-Type: application/x-pkcs7-signature; name="smime.p7s"
13+
Content-Transfer-Encoding: base64
14+
Content-Disposition: attachment; filename="smime.p7s"
15+
16+
MIIEeQYJKoZIhvcNAQcCoIIEajCCBGYCAQExDzANBglghkgBZQMEAgEFADALBgkq
17+
hkiG9w0BBwGgggJAMIICPDCCAeOgAwIBAgIJALZwpgo2sxthMAoGCCqGSM49BAMC
18+
MIGaMQswCQYDVQQGEwJFUzELMAkGA1UECAwCTUExFDASBgNVBAcMC1RyZXMgQ2Fu
19+
dG9zMREwDwYDVQQKDAhlUHJvc2ltYTERMA8GA1UECwwIZVByb3NpbWExHjAcBgNV
20+
BAMMFWVQcm9zaW1hIE1haW4gVGVzdCBDQTEiMCAGCSqGSIb3DQEJARYTbWFpbmNh
21+
QGVwcm9zaW1hLmNvbTAeFw0xNzA5MDYwOTAzMDNaFw0yNzA5MDQwOTAzMDNaMIGa
22+
MQswCQYDVQQGEwJFUzELMAkGA1UECAwCTUExFDASBgNVBAcMC1RyZXMgQ2FudG9z
23+
MREwDwYDVQQKDAhlUHJvc2ltYTERMA8GA1UECwwIZVByb3NpbWExHjAcBgNVBAMM
24+
FWVQcm9zaW1hIE1haW4gVGVzdCBDQTEiMCAGCSqGSIb3DQEJARYTbWFpbmNhQGVw
25+
cm9zaW1hLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGLlhB3WQ8l1fpUE
26+
3DfOoulA/de38Zfj7hmpKtOnxiH2q6RJbwhxvJeA7R7mkmAKaJKmzx695BjyiXVS
27+
7bE7vgejEDAOMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgVTY1BEvT
28+
4pw3GyBMzaUqmp69wi0kBkyOgq04OhyJ13UCICR125vvt0fUhXsXaxOAx28E4Ac9
29+
SVxpI+3UYs2kV5n0MYIB/TCCAfkCAQEwgagwgZoxCzAJBgNVBAYTAkVTMQswCQYD
30+
VQQIDAJNQTEUMBIGA1UEBwwLVHJlcyBDYW50b3MxETAPBgNVBAoMCGVQcm9zaW1h
31+
MREwDwYDVQQLDAhlUHJvc2ltYTEeMBwGA1UEAwwVZVByb3NpbWEgTWFpbiBUZXN0
32+
IENBMSIwIAYJKoZIhvcNAQkBFhNtYWluY2FAZXByb3NpbWEuY29tAgkAtnCmCjaz
33+
G2EwDQYJYIZIAWUDBAIBBQCggeQwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAc
34+
BgkqhkiG9w0BCQUxDxcNMjYwNDMwMTQzNzAxWjAvBgkqhkiG9w0BCQQxIgQgVZWH
35+
a2kxlbGs9atTglvMe5UvX2S4x+hgL8UHvBWwZEgweQYJKoZIhvcNAQkPMWwwajAL
36+
BglghkgBZQMEASowCwYJYIZIAWUDBAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0D
37+
BzAOBggqhkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZI
38+
hvcNAwICASgwCgYIKoZIzj0EAwIERzBFAiBaVTxo6RJRBJvw+rFuXkgQxGls+cvW
39+
ij0jVfOEAdjLawIhAPMKxGf6oArmB1YX5+t9Cu1iF7gn0hPJ6mhrfJRwYu/u
40+
41+
------8E2E4BD3027D97C6C2B82D6CC5F14AEB--
42+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<dds></dds>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
MIME-Version: 1.0
2+
Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----DC5E28412075E6D900DF81B7A954F358"
3+
4+
This is an S/MIME signed message
5+
6+
------DC5E28412075E6D900DF81B7A954F358
7+
Content-Type: text/plain
8+
9+
<?xml version="1.0" encoding="utf-8"?>
10+
<dds>
11+
<permissions>
12+
<grant name="TestGrant">
13+
<subject_name>emailAddress=test@test.com, CN=Test</subject_name>
14+
<validity>
15+
<not_before>2013-06-01T13:00:00</not_before>
16+
<not_after></not_after>
17+
</validity>
18+
<allow_rule>
19+
<domains><id>0</id></domains>
20+
<publish><topics><topic>*</topic></topics></publish>
21+
</allow_rule>
22+
<default>DENY</default>
23+
</grant>
24+
</permissions>
25+
</dds>
26+
------DC5E28412075E6D900DF81B7A954F358
27+
Content-Type: application/x-pkcs7-signature; name="smime.p7s"
28+
Content-Transfer-Encoding: base64
29+
Content-Disposition: attachment; filename="smime.p7s"
30+
31+
MIIEeQYJKoZIhvcNAQcCoIIEajCCBGYCAQExDzANBglghkgBZQMEAgEFADALBgkq
32+
hkiG9w0BBwGgggJAMIICPDCCAeOgAwIBAgIJALZwpgo2sxthMAoGCCqGSM49BAMC
33+
MIGaMQswCQYDVQQGEwJFUzELMAkGA1UECAwCTUExFDASBgNVBAcMC1RyZXMgQ2Fu
34+
dG9zMREwDwYDVQQKDAhlUHJvc2ltYTERMA8GA1UECwwIZVByb3NpbWExHjAcBgNV
35+
BAMMFWVQcm9zaW1hIE1haW4gVGVzdCBDQTEiMCAGCSqGSIb3DQEJARYTbWFpbmNh
36+
QGVwcm9zaW1hLmNvbTAeFw0xNzA5MDYwOTAzMDNaFw0yNzA5MDQwOTAzMDNaMIGa
37+
MQswCQYDVQQGEwJFUzELMAkGA1UECAwCTUExFDASBgNVBAcMC1RyZXMgQ2FudG9z
38+
MREwDwYDVQQKDAhlUHJvc2ltYTERMA8GA1UECwwIZVByb3NpbWExHjAcBgNVBAMM
39+
FWVQcm9zaW1hIE1haW4gVGVzdCBDQTEiMCAGCSqGSIb3DQEJARYTbWFpbmNhQGVw
40+
cm9zaW1hLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGLlhB3WQ8l1fpUE
41+
3DfOoulA/de38Zfj7hmpKtOnxiH2q6RJbwhxvJeA7R7mkmAKaJKmzx695BjyiXVS
42+
7bE7vgejEDAOMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgVTY1BEvT
43+
4pw3GyBMzaUqmp69wi0kBkyOgq04OhyJ13UCICR125vvt0fUhXsXaxOAx28E4Ac9
44+
SVxpI+3UYs2kV5n0MYIB/TCCAfkCAQEwgagwgZoxCzAJBgNVBAYTAkVTMQswCQYD
45+
VQQIDAJNQTEUMBIGA1UEBwwLVHJlcyBDYW50b3MxETAPBgNVBAoMCGVQcm9zaW1h
46+
MREwDwYDVQQLDAhlUHJvc2ltYTEeMBwGA1UEAwwVZVByb3NpbWEgTWFpbiBUZXN0
47+
IENBMSIwIAYJKoZIhvcNAQkBFhNtYWluY2FAZXByb3NpbWEuY29tAgkAtnCmCjaz
48+
G2EwDQYJYIZIAWUDBAIBBQCggeQwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAc
49+
BgkqhkiG9w0BCQUxDxcNMjYwNDMwMTQzNzQ4WjAvBgkqhkiG9w0BCQQxIgQgJrJV
50+
o9tPy2L+KJ5tkb6WtZWcPy2wbmkV1huZld9AFZMweQYJKoZIhvcNAQkPMWwwajAL
51+
BglghkgBZQMEASowCwYJYIZIAWUDBAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0D
52+
BzAOBggqhkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZI
53+
hvcNAwICASgwCgYIKoZIzj0EAwIERzBFAiAJ8txqX584t1CLI3pdN7w6dpF/N6ZJ
54+
nFFRqybPfFLnOwIhAK7xMa+AVk0McUOJZ1gvUv8TwCfkJtHheHqZmJBtb4uO
55+
56+
------DC5E28412075E6D900DF81B7A954F358--
57+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<dds>
3+
<permissions>
4+
<grant name="TestGrant">
5+
<subject_name>emailAddress=test@test.com, CN=Test</subject_name>
6+
<validity>
7+
<not_before>2013-06-01T13:00:00</not_before>
8+
<not_after></not_after>
9+
</validity>
10+
<allow_rule>
11+
<domains><id>0</id></domains>
12+
<publish><topics><topic>*</topic></topics></publish>
13+
</allow_rule>
14+
<default>DENY</default>
15+
</grant>
16+
</permissions>
17+
</dds>

test/unittest/security/accesscontrol/AccessControlTests.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,54 @@ TEST_F(AccessControlTest, validation_ok_on_chained_ca)
511511
check_remote_datawriter(publisher_participant_attr, true);
512512
}
513513

514+
/* Regression test for advisories GHSA-j2w9-582m-j57r/
515+
*
516+
* GHSA-rg6h-2jch-hwjx/GHSA-r4gh-qh7w-jxqf
517+
*
518+
* NULL Pointer Dereferences in Permissions and Governance Parsers
519+
*/
520+
TEST_F(AccessControlTest, participant_creation_fail_with_empty_no_after_xml_field)
521+
{
522+
permissions_ca = "maincacert.pem";
523+
permissions_file = "permissions_blank_not_after.smime";
524+
governance_file = "governance_helloworld_all_enable.smime";
525+
526+
RTPSParticipantAttributes subscriber_participant_attr;
527+
fill_subscriber_participant_security_attributes(subscriber_participant_attr);
528+
529+
PermissionsHandle* access_handle;
530+
get_access_handle(subscriber_participant_attr, &access_handle, false);
531+
532+
}
533+
534+
TEST_F(AccessControlTest, participant_creation_fail_with_empty_dds_xml_field)
535+
{
536+
permissions_ca = "maincacert.pem";
537+
permissions_file = "permissions_blank_dds.smime";
538+
governance_file = "governance_helloworld_all_enable.smime";
539+
540+
RTPSParticipantAttributes subscriber_participant_attr;
541+
fill_subscriber_participant_security_attributes(subscriber_participant_attr);
542+
543+
PermissionsHandle* access_handle;
544+
get_access_handle(subscriber_participant_attr, &access_handle, false);
545+
546+
}
547+
548+
TEST_F(AccessControlTest, participant_creation_fail_with_empty_topic_expression_xml_field)
549+
{
550+
permissions_ca = "maincacert.pem";
551+
permissions_file = "permissions_access_control_tests.smime";
552+
governance_file = "governance_blank_topic_expression.smime";
553+
554+
RTPSParticipantAttributes subscriber_participant_attr;
555+
fill_subscriber_participant_security_attributes(subscriber_participant_attr);
556+
557+
PermissionsHandle* access_handle;
558+
get_access_handle(subscriber_participant_attr, &access_handle, false);
559+
560+
}
561+
514562
int main(
515563
int argc,
516564
char** argv)

0 commit comments

Comments
 (0)