From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754469AbdBUR5z (ORCPT ); Tue, 21 Feb 2017 12:57:55 -0500 Received: from smtp.lesbg.com ([178.62.242.175]:40900 "EHLO smtp.lesbg.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754441AbdBUR5r (ORCPT ); Tue, 21 Feb 2017 12:57:47 -0500 From: Jonathan Dieter To: linux-kernel@vger.kernel.org Cc: Jonathan Dieter , Valentina Manea , Shuah Khan , Peter Senna Tschudin , Krzysztof Opasiak , Greg Kroah-Hartman , linux-usb@vger.kernel.org (open list:USB OVER IP DRIVER) Subject: [PATCH v2 1/2] usbip: Fix-format-overflow Date: Tue, 21 Feb 2017 19:57:08 +0200 Message-Id: <20170221175713.18707-1-jdieter@lesbg.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <1487699421.13719.2.camel@lesbg.com> References: <1487699421.13719.2.camel@lesbg.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The usbip userspace tools call sprintf()/snprintf() and don't check for the return value which can lead the paths to overflow, truncating the final file in the path. More urgently, GCC 7 now warns that these aren't checked with -Wformat-overflow, and with -Werror enabled in configure.ac, that makes these tools unbuildable. This patch fixes these problems by replacing sprintf() with snprintf() in one place and adding checks for the return value of snprintf(). Reviewed-by: Peter Senna Tschudin Signed-off-by: Jonathan Dieter --- tools/usb/usbip/libsrc/usbip_common.c | 8 +++++++- tools/usb/usbip/libsrc/usbip_host_common.c | 25 ++++++++++++++++++++----- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/tools/usb/usbip/libsrc/usbip_common.c b/tools/usb/usbip/libsrc/usbip_common.c index ac73710..01dd4b2 100644 --- a/tools/usb/usbip/libsrc/usbip_common.c +++ b/tools/usb/usbip/libsrc/usbip_common.c @@ -215,9 +215,15 @@ int read_usb_interface(struct usbip_usb_device *udev, int i, struct usbip_usb_interface *uinf) { char busid[SYSFS_BUS_ID_SIZE]; + unsigned int size; struct udev_device *sif; - sprintf(busid, "%s:%d.%d", udev->busid, udev->bConfigurationValue, i); + size = snprintf(busid, sizeof(busid), "%s:%d.%d", + udev->busid, udev->bConfigurationValue, i); + if (size >= sizeof(busid)) { + err("busid length %u >= %lu", size, sizeof(busid)); + return -1; + } sif = udev_device_new_from_subsystem_sysname(udev_context, "usb", busid); if (!sif) { diff --git a/tools/usb/usbip/libsrc/usbip_host_common.c b/tools/usb/usbip/libsrc/usbip_host_common.c index 9d41522..398c1fa 100644 --- a/tools/usb/usbip/libsrc/usbip_host_common.c +++ b/tools/usb/usbip/libsrc/usbip_host_common.c @@ -40,13 +40,19 @@ struct udev *udev_context; static int32_t read_attr_usbip_status(struct usbip_usb_device *udev) { char status_attr_path[SYSFS_PATH_MAX]; + unsigned int size; int fd; int length; char status; int value = 0; - snprintf(status_attr_path, SYSFS_PATH_MAX, "%s/usbip_status", - udev->path); + size = snprintf(status_attr_path, sizeof(status_attr_path), "%s/usbip_status", + udev->path); + if (size >= sizeof(status_attr_path)) { + err("usbip_status path length %u >= %lu", size, sizeof(status_attr_path)); + return -1; + } + fd = open(status_attr_path, O_RDONLY); if (fd < 0) { @@ -218,6 +224,7 @@ int usbip_export_device(struct usbip_exported_device *edev, int sockfd) { char attr_name[] = "usbip_sockfd"; char sockfd_attr_path[SYSFS_PATH_MAX]; + unsigned int size; char sockfd_buff[30]; int ret; @@ -237,10 +244,18 @@ int usbip_export_device(struct usbip_exported_device *edev, int sockfd) } /* only the first interface is true */ - snprintf(sockfd_attr_path, sizeof(sockfd_attr_path), "%s/%s", - edev->udev.path, attr_name); + size = snprintf(sockfd_attr_path, sizeof(sockfd_attr_path), "%s/%s", + edev->udev.path, attr_name); + if (size >= sizeof(sockfd_attr_path)) { + err("exported device path length %u >= %lu", size, sizeof(sockfd_attr_path)); + return -1; + } - snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd); + size = snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd); + if (size >= sizeof(sockfd_buff)) { + err("socket length %u >= %lu", size, sizeof(sockfd_buff)); + return -1; + } ret = write_sysfs_attribute(sockfd_attr_path, sockfd_buff, strlen(sockfd_buff)); -- 2.9.3