From 5a9b0f1ef83300f853e77ada03515c8542c1cfe0 Mon Sep 17 00:00:00 2001 From: Eugene Syromyatnikov Date: Thu, 29 Aug 2019 19:03:51 +0200 Subject: [PATCH] sockaddr: properly decode sockaddr_hci addresses without hci_channel 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 | 3 +++ sockaddr.c | 16 +++++++++++++--- tests/net-sockaddr.c | 18 ++++++++++++++---- 3 files changed, 30 insertions(+), 7 deletions(-) Index: strace-4.24/configure.ac =================================================================== --- strace-4.24.orig/configure.ac 2020-01-26 13:47:02.277446765 +0100 +++ strace-4.24/configure.ac 2020-01-26 13:47:08.976575337 +0100 @@ -458,6 +458,9 @@ ]) AC_CHECK_HEADERS([bluetooth/bluetooth.h], [ + AC_CHECK_MEMBERS([struct sockaddr_hci.hci_channel],,, + [#include + #include ]) AC_CHECK_MEMBERS([struct sockaddr_l2.l2_bdaddr_type],,, [#include #include ]) Index: strace-4.24/sockaddr.c =================================================================== --- strace-4.24.orig/sockaddr.c 2020-01-26 13:47:08.977575356 +0100 +++ strace-4.24/sockaddr.c 2020-01-27 16:26:32.975222449 +0100 @@ -355,12 +355,21 @@ }; 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_index(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_index(hci_channels, hci->hci_channel, + "HCI_CHANNEL_???"); + } + break; } case sizeof(struct sockaddr_sco): { Index: strace-4.24/tests/net-sockaddr.c =================================================================== --- strace-4.24.orig/tests/net-sockaddr.c 2020-01-26 13:47:02.279446803 +0100 +++ strace-4.24/tests/net-sockaddr.c 2020-01-26 13:47:08.979575395 +0100 @@ -364,11 +364,22 @@ 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); } @@ -521,9 +532,8 @@ " = %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); } Index: strace-4.24/tests-m32/net-sockaddr.c =================================================================== --- strace-4.24.orig/tests-m32/net-sockaddr.c 2020-01-26 13:47:02.282446861 +0100 +++ strace-4.24/tests-m32/net-sockaddr.c 2020-01-26 13:47:08.979575395 +0100 @@ -384,11 +384,22 @@ 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); } @@ -541,9 +552,8 @@ " = %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); } Index: strace-4.24/tests-mx32/net-sockaddr.c =================================================================== --- strace-4.24.orig/tests-mx32/net-sockaddr.c 2020-01-26 13:47:02.282446861 +0100 +++ strace-4.24/tests-mx32/net-sockaddr.c 2020-01-26 13:47:08.979575395 +0100 @@ -384,11 +384,22 @@ 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); } @@ -541,9 +552,8 @@ " = %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); } Index: strace-4.24/configure =================================================================== --- strace-4.24.orig/configure 2020-01-26 13:47:02.285446919 +0100 +++ strace-4.24/configure 2020-01-26 13:47:08.981575433 +0100 @@ -11240,6 +11240,18 @@ #define HAVE_BLUETOOTH_BLUETOOTH_H 1 _ACEOF + ac_fn_c_check_member "$LINENO" "struct sockaddr_hci" "hci_channel" "ac_cv_member_struct_sockaddr_hci_hci_channel" "#include + #include +" +if test "x$ac_cv_member_struct_sockaddr_hci_hci_channel" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL 1 +_ACEOF + + +fi + ac_fn_c_check_member "$LINENO" "struct sockaddr_l2" "l2_bdaddr_type" "ac_cv_member_struct_sockaddr_l2_l2_bdaddr_type" "#include #include " Index: strace-4.24/config.h.in =================================================================== --- strace-4.24.orig/config.h.in 2020-01-26 13:47:02.287446957 +0100 +++ strace-4.24/config.h.in 2020-01-26 13:47:08.982575452 +0100 @@ -1315,6 +1315,9 @@ /* Define to 1 if the system has the type `struct sigcontext'. */ #undef HAVE_STRUCT_SIGCONTEXT +/* Define to 1 if `hci_channel' is a member of `struct sockaddr_hci'. */ +#undef HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL + /* Define to 1 if `l2_bdaddr_type' is a member of `struct sockaddr_l2'. */ #undef HAVE_STRUCT_SOCKADDR_L2_L2_BDADDR_TYPE