]> www.infradead.org Git - users/borneoa/openocd-next.git/commitdiff
transport: validate the transport id's from the driver
authorAntonio Borneo <borneo.antonio@gmail.com>
Sun, 22 Dec 2024 22:59:19 +0000 (23:59 +0100)
committerAntonio Borneo <borneo.antonio@gmail.com>
Thu, 1 May 2025 15:26:45 +0000 (15:26 +0000)
Verify that it contains only valid transports.

While JTAG and SWD are the more permissive transports, the
respective 'dapdirect' versions are slightly limited, and the
respective 'hla' versions are even more limited.
A driver should not provide two version of the same transport.
Verify that only one JTAG and only one SWD transport is present.
Verify that the preferred transport is valid too.

Change-Id: Iace2f881dd65fc763e81b33e6a7113961a7008af
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8676
Tested-by: jenkins
Reviewed-by: zapb <dev@zapb.de>
Reviewed-by: Jan Matyas <jan.matyas@codasip.com>
src/transport/transport.c

index b7a3913cc4ce95d429581c6b38be3e91566952a7..59f76ad31dbdc5364e8e83fe789b0fb22fd9ae7d 100644 (file)
@@ -125,21 +125,37 @@ static int transport_select(struct command_context *ctx, const char *name)
 int allow_transports(struct command_context *ctx, unsigned int transport_ids,
        unsigned int transport_preferred_id)
 {
-       /* NOTE:  caller is required to provide only a list
-        * of *valid* transports
-        *
-        * REVISIT should we validate that?  and insist there's
-        * at least one valid element in that list?
-        *
-        * ... allow removals, e.g. external strapping prevents use
-        * of one transport; C code should be definitive about what
-        * can be used when all goes well.
-        */
        if (allowed_transports || session) {
                LOG_ERROR("Can't modify the set of allowed transports.");
                return ERROR_FAIL;
        }
 
+       /* validate the values in transport_ids and transport_preferred_id */
+       if (transport_ids == 0 || (transport_ids & ~TRANSPORT_VALID_MASK) != 0) {
+               LOG_ERROR("BUG: Unknown transport IDs %lu", transport_ids & ~TRANSPORT_VALID_MASK);
+               return ERROR_FAIL;
+       }
+
+       if ((transport_ids & transport_preferred_id) == 0
+               || !IS_PWR_OF_2(transport_preferred_id)) {
+               LOG_ERROR("BUG: Invalid adapter transport_preferred_id");
+               return ERROR_FAIL;
+       }
+
+       unsigned int mask = transport_ids &
+               (TRANSPORT_JTAG | TRANSPORT_HLA_JTAG | TRANSPORT_DAPDIRECT_JTAG);
+       if (mask && !IS_PWR_OF_2(mask)) {
+               LOG_ERROR("BUG: Multiple JTAG transports");
+               return ERROR_FAIL;
+       }
+
+       mask = transport_ids &
+               (TRANSPORT_SWD | TRANSPORT_HLA_SWD | TRANSPORT_DAPDIRECT_SWD);
+       if (mask && !IS_PWR_OF_2(mask)) {
+               LOG_ERROR("BUG: Multiple SWD transports");
+               return ERROR_FAIL;
+       }
+
        allowed_transports = transport_ids;
        preferred_transport = transport_preferred_id;