| From 9977909446cab70dd96f231987850bdc8bb1829e Mon Sep 17 00:00:00 2001 |
| From: Shuah Khan <skhan@linuxfoundation.org> |
| Date: Wed, 8 Jan 2020 18:24:16 -0700 |
| Subject: [PATCH] usbip: Fix unsafe unaligned pointer usage |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| commit 585c91f40d201bc564d4e76b83c05b3b5363fe7e upstream. |
| |
| Fix unsafe unaligned pointer usage in usbip network interfaces. usbip tool |
| build fails with new gcc -Werror=address-of-packed-member checks. |
| |
| usbip_network.c: In function ‘usbip_net_pack_usb_device’: |
| usbip_network.c:79:32: error: taking address of packed member of ‘struct usbip_usb_device’ may result in an unaligned pointer value [-Werror=address-of-packed-member] |
| 79 | usbip_net_pack_uint32_t(pack, &udev->busnum); |
| |
| Fix with minor changes to pass by value instead of by address. |
| |
| Signed-off-by: Shuah Khan <skhan@linuxfoundation.org> |
| Link: https://lore.kernel.org/r/20200109012416.2875-1-skhan@linuxfoundation.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/tools/usb/usbip/src/usbip_network.c b/tools/usb/usbip/src/usbip_network.c |
| index d595d72693fb..ed4dc8c14269 100644 |
| --- a/tools/usb/usbip/src/usbip_network.c |
| +++ b/tools/usb/usbip/src/usbip_network.c |
| @@ -50,39 +50,39 @@ void usbip_setup_port_number(char *arg) |
| info("using port %d (\"%s\")", usbip_port, usbip_port_string); |
| } |
| |
| -void usbip_net_pack_uint32_t(int pack, uint32_t *num) |
| +uint32_t usbip_net_pack_uint32_t(int pack, uint32_t num) |
| { |
| uint32_t i; |
| |
| if (pack) |
| - i = htonl(*num); |
| + i = htonl(num); |
| else |
| - i = ntohl(*num); |
| + i = ntohl(num); |
| |
| - *num = i; |
| + return i; |
| } |
| |
| -void usbip_net_pack_uint16_t(int pack, uint16_t *num) |
| +uint16_t usbip_net_pack_uint16_t(int pack, uint16_t num) |
| { |
| uint16_t i; |
| |
| if (pack) |
| - i = htons(*num); |
| + i = htons(num); |
| else |
| - i = ntohs(*num); |
| + i = ntohs(num); |
| |
| - *num = i; |
| + return i; |
| } |
| |
| void usbip_net_pack_usb_device(int pack, struct usbip_usb_device *udev) |
| { |
| - usbip_net_pack_uint32_t(pack, &udev->busnum); |
| - usbip_net_pack_uint32_t(pack, &udev->devnum); |
| - usbip_net_pack_uint32_t(pack, &udev->speed); |
| + udev->busnum = usbip_net_pack_uint32_t(pack, udev->busnum); |
| + udev->devnum = usbip_net_pack_uint32_t(pack, udev->devnum); |
| + udev->speed = usbip_net_pack_uint32_t(pack, udev->speed); |
| |
| - usbip_net_pack_uint16_t(pack, &udev->idVendor); |
| - usbip_net_pack_uint16_t(pack, &udev->idProduct); |
| - usbip_net_pack_uint16_t(pack, &udev->bcdDevice); |
| + udev->idVendor = usbip_net_pack_uint16_t(pack, udev->idVendor); |
| + udev->idProduct = usbip_net_pack_uint16_t(pack, udev->idProduct); |
| + udev->bcdDevice = usbip_net_pack_uint16_t(pack, udev->bcdDevice); |
| } |
| |
| void usbip_net_pack_usb_interface(int pack __attribute__((unused)), |
| @@ -129,6 +129,14 @@ ssize_t usbip_net_send(int sockfd, void *buff, size_t bufflen) |
| return usbip_net_xmit(sockfd, buff, bufflen, 1); |
| } |
| |
| +static inline void usbip_net_pack_op_common(int pack, |
| + struct op_common *op_common) |
| +{ |
| + op_common->version = usbip_net_pack_uint16_t(pack, op_common->version); |
| + op_common->code = usbip_net_pack_uint16_t(pack, op_common->code); |
| + op_common->status = usbip_net_pack_uint32_t(pack, op_common->status); |
| +} |
| + |
| int usbip_net_send_op_common(int sockfd, uint32_t code, uint32_t status) |
| { |
| struct op_common op_common; |
| @@ -140,7 +148,7 @@ int usbip_net_send_op_common(int sockfd, uint32_t code, uint32_t status) |
| op_common.code = code; |
| op_common.status = status; |
| |
| - PACK_OP_COMMON(1, &op_common); |
| + usbip_net_pack_op_common(1, &op_common); |
| |
| rc = usbip_net_send(sockfd, &op_common, sizeof(op_common)); |
| if (rc < 0) { |
| @@ -164,7 +172,7 @@ int usbip_net_recv_op_common(int sockfd, uint16_t *code, int *status) |
| goto err; |
| } |
| |
| - PACK_OP_COMMON(0, &op_common); |
| + usbip_net_pack_op_common(0, &op_common); |
| |
| if (op_common.version != USBIP_VERSION) { |
| err("USBIP Kernel and tool version mismatch: %d %d:", |
| diff --git a/tools/usb/usbip/src/usbip_network.h b/tools/usb/usbip/src/usbip_network.h |
| index 555215eae43e..83b4c5344f72 100644 |
| --- a/tools/usb/usbip/src/usbip_network.h |
| +++ b/tools/usb/usbip/src/usbip_network.h |
| @@ -32,12 +32,6 @@ struct op_common { |
| |
| } __attribute__((packed)); |
| |
| -#define PACK_OP_COMMON(pack, op_common) do {\ |
| - usbip_net_pack_uint16_t(pack, &(op_common)->version);\ |
| - usbip_net_pack_uint16_t(pack, &(op_common)->code);\ |
| - usbip_net_pack_uint32_t(pack, &(op_common)->status);\ |
| -} while (0) |
| - |
| /* ---------------------------------------------------------------------- */ |
| /* Dummy Code */ |
| #define OP_UNSPEC 0x00 |
| @@ -163,11 +157,11 @@ struct op_devlist_reply_extra { |
| } while (0) |
| |
| #define PACK_OP_DEVLIST_REPLY(pack, reply) do {\ |
| - usbip_net_pack_uint32_t(pack, &(reply)->ndev);\ |
| + (reply)->ndev = usbip_net_pack_uint32_t(pack, (reply)->ndev);\ |
| } while (0) |
| |
| -void usbip_net_pack_uint32_t(int pack, uint32_t *num); |
| -void usbip_net_pack_uint16_t(int pack, uint16_t *num); |
| +uint32_t usbip_net_pack_uint32_t(int pack, uint32_t num); |
| +uint16_t usbip_net_pack_uint16_t(int pack, uint16_t num); |
| void usbip_net_pack_usb_device(int pack, struct usbip_usb_device *udev); |
| void usbip_net_pack_usb_interface(int pack, struct usbip_usb_interface *uinf); |
| |
| -- |
| 2.7.4 |
| |