[PATCH] nvme-tcp: fix signedness bug in nvme_tcp_init_connection()

Dan Carpenter posted 1 patch 9 months, 3 weeks ago
There is a newer version of this series
drivers/nvme/host/tcp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH] nvme-tcp: fix signedness bug in nvme_tcp_init_connection()
Posted by Dan Carpenter 9 months, 3 weeks ago
The kernel_recvmsg() function returns an int which could be either
negative error codes or the number of bytes received.  The problem is
that the condition:

	if (ret < sizeof(*icresp)) {

is type promoted to type unsigned long and negative values are treated
as high positive values which is success, when they should be treated as
failure.  Add a cast so to avoid the type promotion.

Fixes: 578539e09690 ("nvme-tcp: fix connect failure on receiving partial ICResp PDU")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
---
 drivers/nvme/host/tcp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index 8a9131c95a3d..361b04ec5b5d 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -1495,7 +1495,7 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
 	msg.msg_flags = MSG_WAITALL;
 	ret = kernel_recvmsg(queue->sock, &msg, &iov, 1,
 			iov.iov_len, msg.msg_flags);
-	if (ret < sizeof(*icresp)) {
+	if (ret < (int)sizeof(*icresp)) {
 		pr_warn("queue %d: failed to receive icresp, error %d\n",
 			nvme_tcp_queue_id(queue), ret);
 		if (ret >= 0)
-- 
2.47.2
Re: [PATCH] nvme-tcp: fix signedness bug in nvme_tcp_init_connection()
Posted by Christoph Hellwig 9 months, 2 weeks ago
On Fri, Feb 28, 2025 at 12:39:41PM +0300, Dan Carpenter wrote:
> index 8a9131c95a3d..361b04ec5b5d 100644
> --- a/drivers/nvme/host/tcp.c
> +++ b/drivers/nvme/host/tcp.c
> @@ -1495,7 +1495,7 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
>  	msg.msg_flags = MSG_WAITALL;
>  	ret = kernel_recvmsg(queue->sock, &msg, &iov, 1,
>  			iov.iov_len, msg.msg_flags);
> -	if (ret < sizeof(*icresp)) {
> +	if (ret < (int)sizeof(*icresp)) {
>  		pr_warn("queue %d: failed to receive icresp, error %d\n",
>  			nvme_tcp_queue_id(queue), ret);
>  		if (ret >= 0)

I hate these magic casts.  What about something like:

	if (ret >= 0 && ret < sizeof(*icresp))
		ret = -ECONNRESET;
	if (ret < 0) {
		...
Re: [PATCH] nvme-tcp: fix signedness bug in nvme_tcp_init_connection()
Posted by Dan Carpenter 9 months, 2 weeks ago
On Wed, Mar 05, 2025 at 03:25:54PM +0100, Christoph Hellwig wrote:
> On Fri, Feb 28, 2025 at 12:39:41PM +0300, Dan Carpenter wrote:
> > index 8a9131c95a3d..361b04ec5b5d 100644
> > --- a/drivers/nvme/host/tcp.c
> > +++ b/drivers/nvme/host/tcp.c
> > @@ -1495,7 +1495,7 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
> >  	msg.msg_flags = MSG_WAITALL;
> >  	ret = kernel_recvmsg(queue->sock, &msg, &iov, 1,
> >  			iov.iov_len, msg.msg_flags);
> > -	if (ret < sizeof(*icresp)) {
> > +	if (ret < (int)sizeof(*icresp)) {
> >  		pr_warn("queue %d: failed to receive icresp, error %d\n",
> >  			nvme_tcp_queue_id(queue), ret);
> >  		if (ret >= 0)
> 
> I hate these magic casts.  What about something like:
> 
> 	if (ret >= 0 && ret < sizeof(*icresp))
> 		ret = -ECONNRESET;
> 	if (ret < 0) {
> 		...

Sure, I can do that.

I don't love casts either.  I normally have tried to write these as
"if (ret < 0 || ret < sizeof(*icresp)) {" and people don't love that.

regards,
dan carpenter
Re: [PATCH] nvme-tcp: fix signedness bug in nvme_tcp_init_connection()
Posted by Christoph Hellwig 9 months, 2 weeks ago
On Wed, Mar 05, 2025 at 05:37:15PM +0300, Dan Carpenter wrote:
> > 	if (ret >= 0 && ret < sizeof(*icresp))
> > 		ret = -ECONNRESET;
> > 	if (ret < 0) {
> > 		...
> 
> Sure, I can do that.
> 
> I don't love casts either.  I normally have tried to write these as
> "if (ret < 0 || ret < sizeof(*icresp)) {" and people don't love that.

I can see why people don't like it as it's really counterintuitive.
These kinds of interfaces just suck given the type promotion rules
unfortunately.
Re: [PATCH] nvme-tcp: fix signedness bug in nvme_tcp_init_connection()
Posted by Chaitanya Kulkarni 9 months, 2 weeks ago
On 2/28/25 01:39, Dan Carpenter wrote:
> The kernel_recvmsg() function returns an int which could be either
> negative error codes or the number of bytes received.  The problem is
> that the condition:
>
> 	if (ret < sizeof(*icresp)) {
>
> is type promoted to type unsigned long and negative values are treated
> as high positive values which is success, when they should be treated as
> failure.  Add a cast so to avoid the type promotion.
>
> Fixes: 578539e09690 ("nvme-tcp: fix connect failure on receiving partial ICResp PDU")
> Signed-off-by: Dan Carpenter<dan.carpenter@linaro.org>

Thanks for the fix, looks good.

Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>

-ck


Re: [PATCH] nvme-tcp: fix signedness bug in nvme_tcp_init_connection()
Posted by Sagi Grimberg 9 months, 2 weeks ago
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Re: [PATCH] nvme-tcp: fix signedness bug in nvme_tcp_init_connection()
Posted by Caleb Sander Mateos 9 months, 2 weeks ago
On Fri, Feb 28, 2025 at 1:39 AM Dan Carpenter <dan.carpenter@linaro.org> wrote:
>
> The kernel_recvmsg() function returns an int which could be either
> negative error codes or the number of bytes received.  The problem is
> that the condition:
>
>         if (ret < sizeof(*icresp)) {
>
> is type promoted to type unsigned long and negative values are treated
> as high positive values which is success, when they should be treated as
> failure.  Add a cast so to avoid the type promotion.

"so as to"?

>
> Fixes: 578539e09690 ("nvme-tcp: fix connect failure on receiving partial ICResp PDU")
> Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>

Good catch, thanks for fixing this.

Reviewed-by: Caleb Sander Mateos <csander@purestorage.com>

> ---
>  drivers/nvme/host/tcp.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
> index 8a9131c95a3d..361b04ec5b5d 100644
> --- a/drivers/nvme/host/tcp.c
> +++ b/drivers/nvme/host/tcp.c
> @@ -1495,7 +1495,7 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
>         msg.msg_flags = MSG_WAITALL;
>         ret = kernel_recvmsg(queue->sock, &msg, &iov, 1,
>                         iov.iov_len, msg.msg_flags);
> -       if (ret < sizeof(*icresp)) {
> +       if (ret < (int)sizeof(*icresp)) {
>                 pr_warn("queue %d: failed to receive icresp, error %d\n",
>                         nvme_tcp_queue_id(queue), ret);
>                 if (ret >= 0)
> --
> 2.47.2
>