tbio: fix cmd_len handling
sizeof(rq->cmd) does not return the size of cmd buffer in rq,
it will return the size of the pointer, i.e. 4 - on 32-bit systems,
and 8 - on 64-bit systems. This happens, because cmd is a pointer to
__cmd[BLK_MAX_CDB] in struct request in the kernel (see linux/blkdev.h):
unsigned char __cmd[BLK_MAX_CDB];
unsigned char *cmd;
unsigned short cmd_len;
and is not a static buffer by itself.
Therefore on 32-bit systems 'sizeof(rq->cmd) - inter->cmd_len)' will be
'4 - 6', and this is not what we want.
Corrected this, so now we rely on inter->cmd containing a null-terminated string,
and inter->cmd_len containing the exact number of bytes to store this string.
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
Acked-by: Cyril Hrubis <chrubis@suse.cz>
diff --git a/testcases/kernel/device-drivers/tbio/tbio_kernel/ltp_tbio.c b/testcases/kernel/device-drivers/tbio/tbio_kernel/ltp_tbio.c
index 4e38fe7..48cc588 100644
--- a/testcases/kernel/device-drivers/tbio/tbio_kernel/ltp_tbio.c
+++ b/testcases/kernel/device-drivers/tbio/tbio_kernel/ltp_tbio.c
@@ -85,14 +85,19 @@
return -EFAULT;
}
+ if ((!inter->cmd_len) || (inter->cmd_len > rq->cmd_len)) {
+ prk_err("invalid inter->cmd_len");
+ return -EFAULT;
+ }
+
rq->cmd_len = inter->cmd_len;
if (copy_from_user(rq->cmd, inter->cmd, inter->cmd_len))
goto out_request;
- if (sizeof(rq->cmd) != inter->cmd_len) {
- memset(rq->cmd + inter->cmd_len, 0,
- sizeof(rq->cmd) - inter->cmd_len);
+ if (*(rq->cmd + rq->cmd_len - 1)) {
+ prk_err("rq->cmd is not null-terminated");
+ return -EFAULT;
}
rq->__sector = bio->bi_sector;
diff --git a/testcases/kernel/device-drivers/tbio/tbio_kernel/tbio.h b/testcases/kernel/device-drivers/tbio/tbio_kernel/tbio.h
index cf6df73..4cf0f46 100644
--- a/testcases/kernel/device-drivers/tbio/tbio_kernel/tbio.h
+++ b/testcases/kernel/device-drivers/tbio/tbio_kernel/tbio.h
@@ -66,6 +66,6 @@
int data_len; /* input data length */
int direction; /* read or write form DEV */
char *cmd; /* read or write */
- int cmd_len; /* length of cmd */
+ unsigned short cmd_len; /* length of cmd */
};
typedef struct tbio_interface tbio_interface_t;
diff --git a/testcases/kernel/device-drivers/tbio/tbio_user/tbio.c b/testcases/kernel/device-drivers/tbio/tbio_user/tbio.c
index 81085a3..31c384b 100644
--- a/testcases/kernel/device-drivers/tbio/tbio_user/tbio.c
+++ b/testcases/kernel/device-drivers/tbio/tbio_user/tbio.c
@@ -202,14 +202,14 @@
bif.data_len = 1024;
bif.direction = TBIO_FROM_DEV;
- bif.cmd = SAFE_MALLOC(cleanup, 6);
+ bif.cmd = SAFE_MALLOC(cleanup, 5);
if (bif.cmd == NULL) {
tst_resm(TINFO, "malloc cmd space failed");
free(bif.data);
return -1;
}
strcpy(bif.cmd, "READ");
- bif.cmd_len = 6;
+ bif.cmd_len = 5;
rc = ioctl(fd, flag, &bif);
if (rc) {