Greybus currently uses strncpy() coupled with a check for '\0' on the
last byte of various buffers. strncpy() is passed size parameter equal
to the size of the buffer in all instances. If the source string is
larger than the destination buffer the check catches this and, after
logging the error, returns an error value. In one instance the
immediate return is not required. Using strncpy() with the manual check
adds code that could be removed by the use of strlcpy(), although truncation
then needs to be checked.
Replace calls to strncpy() with calls to strlcpy(). Replace null
termination checks with checks for truncated string. Add log message
if string is truncated but do not return an error code.
Signed-off-by: Tobin C. Harding <me(a)tobin.cc>
---
drivers/staging/greybus/fw-management.c | 59 +++++++++++----------------------
1 file changed, 19 insertions(+), 40 deletions(-)
diff --git a/drivers/staging/greybus/fw-management.c b/drivers/staging/greybus/fw-management.c
index 3cd6cf0..1cd5a45 100644
--- a/drivers/staging/greybus/fw-management.c
+++ b/drivers/staging/greybus/fw-management.c
@@ -108,6 +108,7 @@ static int fw_mgmt_interface_fw_version_operation(struct fw_mgmt *fw_mgmt,
struct gb_connection *connection = fw_mgmt->connection;
struct gb_fw_mgmt_interface_fw_version_response response;
int ret;
+ size_t len;
ret = gb_operation_sync(connection,
GB_FW_MGMT_TYPE_INTERFACE_FW_VERSION, NULL, 0,
@@ -121,18 +122,11 @@ static int fw_mgmt_interface_fw_version_operation(struct fw_mgmt *fw_mgmt,
fw_info->major = le16_to_cpu(response.major);
fw_info->minor = le16_to_cpu(response.minor);
- strncpy(fw_info->firmware_tag, response.firmware_tag,
+ len = strlcpy(fw_info->firmware_tag, response.firmware_tag,
GB_FIRMWARE_TAG_MAX_SIZE);
-
- /*
- * The firmware-tag should be NULL terminated, otherwise throw error but
- * don't fail.
- */
- if (fw_info->firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
+ if (len >= GB_FIRMWARE_TAG_MAX_SIZE)
dev_err(fw_mgmt->parent,
- "fw-version: firmware-tag is not NULL terminated\n");
- fw_info->firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] = '\0';
- }
+ "fw-version: firmware-tag has been truncated\n");
return 0;
}
@@ -142,6 +136,7 @@ static int fw_mgmt_load_and_validate_operation(struct fw_mgmt *fw_mgmt,
{
struct gb_fw_mgmt_load_and_validate_fw_request request;
int ret;
+ size_t len;
if (load_method != GB_FW_LOAD_METHOD_UNIPRO &&
load_method != GB_FW_LOAD_METHOD_INTERNAL) {
@@ -151,16 +146,10 @@ static int fw_mgmt_load_and_validate_operation(struct fw_mgmt *fw_mgmt,
}
request.load_method = load_method;
- strncpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE);
-
- /*
- * The firmware-tag should be NULL terminated, otherwise throw error and
- * fail.
- */
- if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
- dev_err(fw_mgmt->parent, "load-and-validate: firmware-tag is not NULL terminated\n");
- return -EINVAL;
- }
+ len = strlcpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE);
+ if (len >= GB_FIRMWARE_TAG_MAX_SIZE)
+ dev_err(fw_mgmt->parent,
+ "load-and-validate: firmware-tag has been truncated\n");
/* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
ret = ida_simple_get(&fw_mgmt->id_map, 1, 256, GFP_KERNEL);
@@ -247,18 +236,13 @@ static int fw_mgmt_backend_fw_version_operation(struct fw_mgmt *fw_mgmt,
struct gb_fw_mgmt_backend_fw_version_request request;
struct gb_fw_mgmt_backend_fw_version_response response;
int ret;
+ size_t len;
- strncpy(request.firmware_tag, fw_info->firmware_tag,
+ len = strlcpy(request.firmware_tag, fw_info->firmware_tag,
GB_FIRMWARE_TAG_MAX_SIZE);
-
- /*
- * The firmware-tag should be NULL terminated, otherwise throw error and
- * fail.
- */
- if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
- dev_err(fw_mgmt->parent, "backend-version: firmware-tag is not NULL terminated\n");
- return -EINVAL;
- }
+ if (len >= GB_FIRMWARE_TAG_MAX_SIZE)
+ dev_err(fw_mgmt->parent,
+ "backend-version: firmware-tag has been truncated\n");
ret = gb_operation_sync(connection,
GB_FW_MGMT_TYPE_BACKEND_FW_VERSION, &request,
@@ -301,17 +285,12 @@ static int fw_mgmt_backend_fw_update_operation(struct fw_mgmt *fw_mgmt,
{
struct gb_fw_mgmt_backend_fw_update_request request;
int ret;
+ size_t len;
- strncpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE);
-
- /*
- * The firmware-tag should be NULL terminated, otherwise throw error and
- * fail.
- */
- if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
- dev_err(fw_mgmt->parent, "backend-update: firmware-tag is not NULL terminated\n");
- return -EINVAL;
- }
+ len = strlcpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE);
+ if (len >= GB_FIRMWARE_TAG_MAX_SIZE)
+ dev_err(fw_mgmt->parent,
+ "backend-update: firmware-tag has been truncated\n");
/* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
ret = ida_simple_get(&fw_mgmt->id_map, 1, 256, GFP_KERNEL);
--
2.7.4
Change array index from the loop bound variable to loop index.
If a poll file fails to open for any intermediate device, all poll files with
fds of devices from 0 upto that device must be closed in the open_poll_files()
function. The current code only closes the poll file with the most recent fd
allocated, and at times tries to close the same file multiple times.
Detected by coccinelle:
@@
expression arr,ex1,ex2;
@@
for(ex1 = 0; ex1 < ex2; ex1++) { <...
arr[
- ex2
+ ex1
]
...> }
Signed-off-by: sayli karnik <karniksayli1995(a)gmail.com>
---
v2:
Made the subject and changelog more concise
drivers/staging/greybus/tools/loopback_test.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/greybus/tools/loopback_test.c b/drivers/staging/greybus/tools/loopback_test.c
index 18d7a3d..2ee9a22 100644
--- a/drivers/staging/greybus/tools/loopback_test.c
+++ b/drivers/staging/greybus/tools/loopback_test.c
@@ -674,7 +674,7 @@ static int open_poll_files(struct loopback_test *t)
err:
for (i = 0; i < fds_idx; i++)
- close(t->fds[fds_idx].fd);
+ close(t->fds[i].fd);
return -1;
}
--
2.7.4
[+CC: greybus and staging lists]
On Sat, Feb 18, 2017 at 01:47:38PM +0530, sayli karnik wrote:
> Change array index from the loop bound variable to loop index.
> The open_poll_files() functions attempts to open poll files of devices
> numbered from 0 to device_count. If the open() function inside it is
> unsuccessful for any intermediate device, all files with fds of devices from 0
> upto that device must be closed and open_poll_files() should return -1.
> The current code only closes the poll file with the most recent fd allocated,
> and in most cases tries to close the same file multiple times.
Nice catch!
You forgot to CC the relevant mailings lists however (use
scripts/get_maintainer.pl).
Also your patch summary is a bit too detailed, something like
staging: greybus: loopback_test: fix open error path
would be better.
Care to resend as a v2 with a shorter summary and lists on CC?
> Detected by coccinelle:
>
> @@
> expression arr,ex1,ex2;
> @@
>
> for(ex1 = 0; ex1 < ex2; ex1++) { <...
> arr[
> - ex2
> + ex1
> ]
> ...> }
>
> Signed-off-by: sayli karnik <karniksayli1995(a)gmail.com>
> ---
> drivers/staging/greybus/tools/loopback_test.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/staging/greybus/tools/loopback_test.c b/drivers/staging/greybus/tools/loopback_test.c
> index 18d7a3d..2ee9a22 100644
> --- a/drivers/staging/greybus/tools/loopback_test.c
> +++ b/drivers/staging/greybus/tools/loopback_test.c
> @@ -674,7 +674,7 @@ static int open_poll_files(struct loopback_test *t)
>
> err:
> for (i = 0; i < fds_idx; i++)
> - close(t->fds[fds_idx].fd);
> + close(t->fds[i].fd);
>
> return -1;
> }
Thanks,
Johan
From: Colin Ian King <colin.king(a)canonical.com>
Currently newline.flow_control is uninitialized, so it can contain
any garbage from the stack. I believe it should be initialized with
GB_SERIAL_AUTO_RTSCTS_EN enabled if the termios c_cflag is CRTSCTS
enabled.
Signed-off-by: Colin Ian King <colin.king(a)canonical.com>
---
drivers/staging/greybus/uart.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index 248ad66..b542f67 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -506,6 +506,8 @@ static void gb_tty_set_termios(struct tty_struct *tty,
newline.parity = termios->c_cflag & PARENB ?
(termios->c_cflag & PARODD ? 1 : 2) +
(termios->c_cflag & CMSPAR ? 2 : 0) : 0;
+ newline.flow_control = termios->c_cflag & CRTSCTS ?
+ GB_SERIAL_AUTO_RTSCTS_EN : 0;
switch (termios->c_cflag & CSIZE) {
case CS5:
--
2.10.2