]> granicus.if.org Git - strace/commitdiff
sockaddr: properly decode sockaddr_hci addresses without hci_channel
authorEugene Syromyatnikov <evgsyr@gmail.com>
Thu, 29 Aug 2019 17:03:51 +0000 (19:03 +0200)
committerEugene Syromyatnikov <evgsyr@gmail.com>
Thu, 29 Aug 2019 17:20:57 +0000 (19:20 +0200)
Before Linux commit v2.6.38-rc1~476^2~14^2~3^2~43^2~9,
struct sockaddr_hci did not contain hci_channel field.

* configure.ac (AC_CHECK_HEADERS([bluetooth/bluetooth.h])): Add check
for struct sockaddr_hci.hci_channel.
* sockaddr.c (print_sockaddr_data_bt): Decode struct sockaddr_hci
without hci_channel field.
* tests/net-sockaddr.c (check_hci): Add check for struct sockaddr_hci
decoding without hci_channel field; guard hci_channel with #ifdef
HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL.
(check_raw): Remove "len++", as 4-byte AF_BLUETOOTH socket addresses are
interpreted as struct sockaddr_hci without hci_channel field.

configure.ac
sockaddr.c
tests/net-sockaddr.c

index 0bd49b6b3953f216717dae9f7efa1ad1e170127e..a7938e5c264c247c621e7c9775c4c5d8ea668707 100644 (file)
@@ -479,6 +479,9 @@ AC_CHECK_HEADERS([linux/bpf.h], [
 ])
 
 AC_CHECK_HEADERS([bluetooth/bluetooth.h], [
+       AC_CHECK_MEMBERS([struct sockaddr_hci.hci_channel],,,
+                        [#include <bluetooth/bluetooth.h>
+                        #include <bluetooth/hci.h>])
        AC_CHECK_MEMBERS([struct sockaddr_l2.l2_bdaddr_type],,,
                         [#include <bluetooth/bluetooth.h>
                         #include <bluetooth/l2cap.h>])
index dbf3856c64b7a21e25fc1e246f2fbb485d49f900..c67d60e98ced22d1d8ea1caa6ee1eba64daa33e5 100644 (file)
@@ -599,11 +599,21 @@ print_sockaddr_data_bt(const void *const buf, const int addrlen)
        };
 
        switch (addrlen) {
+       case offsetofend(struct sockaddr_hci, hci_dev):
        case sizeof(struct sockaddr_hci): {
                const struct sockaddr_hci *const hci = buf;
-               tprintf("hci_dev=htobs(%hu), hci_channel=",
-                       btohs(hci->hci_dev));
-               printxval(hci_channels, hci->hci_channel, "HCI_CHANNEL_???");
+               tprintf("hci_dev=htobs(%hu)", btohs(hci->hci_dev));
+
+               /*
+                * hci_channel field has been introduced
+                * Linux commit in v2.6.38-rc1~476^2~14^2~3^2~43^2~9.
+                */
+               if (addrlen == sizeof(struct sockaddr_hci)) {
+                       tprints(", hci_channel=");
+                       printxval(hci_channels, hci->hci_channel,
+                                 "HCI_CHANNEL_???");
+               }
+
                break;
        }
        case sizeof(struct sockaddr_sco): {
index cd9739226314fd9ef6f405fe94a1a86b5465c421..8aa738d1a0a8997e73bc8ebe9524105093088e59 100644 (file)
@@ -543,11 +543,22 @@ check_hci(void)
        TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_hci, hci);
        hci->hci_family = AF_BLUETOOTH;
        hci->hci_dev = htobs(h_port);
+# ifdef HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL
        hci->hci_channel = HCI_CHANNEL_RAW;
+# endif
        unsigned int len = sizeof(*hci);
-       int ret = connect(-1, (void *) hci, len);
+
+       int ret = connect(-1, (void *) hci, 4);
+       printf("connect(-1, {sa_family=AF_BLUETOOTH, hci_dev=htobs(%hu)"
+              "}, 4) = %d EBADF (%m)\n",
+              h_port, ret);
+
+       ret = connect(-1, (void *) hci, len);
        printf("connect(-1, {sa_family=AF_BLUETOOTH, hci_dev=htobs(%hu)"
-              ", hci_channel=HCI_CHANNEL_RAW}, %u) = %d EBADF (%m)\n",
+# ifdef HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL
+              ", hci_channel=HCI_CHANNEL_RAW"
+# endif
+              "}, %u) = %d EBADF (%m)\n",
               h_port, len, ret);
 }
 
@@ -700,9 +711,8 @@ check_raw(void)
               " = %d EBADF (%m)\n", len, ret);
 
        u.sa->sa_family = AF_BLUETOOTH;
-       ++len;
        ret = connect(-1, (void *) u.st, len);
-       printf("connect(-1, {sa_family=AF_BLUETOOTH, sa_data=\"00\"}, %u)"
+       printf("connect(-1, {sa_family=AF_BLUETOOTH, sa_data=\"0\"}, %u)"
               " = %d EBADF (%m)\n", len, ret);
 }