Download raw body.
Avoid implicit sign extension in vctrap()
Hi,
found by coverty:
port is uint16_t. Shifting promotes to signed 32bit integer.
When assigning to uint64_t sw_exitinfo1 the value gets sign extended.
Thus when "port << 16" is greater than 0x7fffffff the upper bits
of sw_exitinfo1 will be all 1. Therefore cast to uint64_t before
shifting.
ok?
HJ.
-----------------------------------------------------------------------
commit 0bdf00d115852dabeb9078497d91e19d8667898f
Author: Hans-Joerg Hoexer <hshoexer@genua.de>
Date: Sat Aug 2 23:04:22 2025 +0200
Avoid implicit sign extension in vctrap()
port is uint16_t. Shifting promotes to signed 32bit integer. When
assigning to uint64_t sw_exitinfo1 the value gets sign extended.
Thus when "port << 16" is greater than 0x7fffffff the upper bits
of sw_exitinfo1 will be all 1. Therefore apply cast to uint64_t
before shifting.
Coverity CID 1648416.
diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c
index cb152600dca..dcdfd98c909 100644
--- a/sys/arch/amd64/amd64/trap.c
+++ b/sys/arch/amd64/amd64/trap.c
@@ -367,14 +367,14 @@ vctrap(struct trapframe *frame, int user)
case 0xef: /* out %ax,(%dx) */
ghcb_sync_val(GHCB_RAX, GHCB_SZ16, &syncout);
port = (uint16_t)frame->tf_rdx;
- sw_exitinfo1 = (port << 16) |
+ sw_exitinfo1 = ((uint64_t)port << 16) |
(1ULL << 5);
frame->tf_rip += 2;
break;
case 0xed: /* in (%dx),%ax */
ghcb_sync_val(GHCB_RAX, GHCB_SZ16, &syncin);
port = (uint16_t)frame->tf_rdx;
- sw_exitinfo1 = (port << 16) |
+ sw_exitinfo1 = ((uint64_t)port << 16) |
(1ULL << 5) | (1ULL << 0);
frame->tf_rip += 2;
break;
@@ -386,40 +386,40 @@ vctrap(struct trapframe *frame, int user)
case 0xe4: /* in $port,%al */
ghcb_sync_val(GHCB_RAX, GHCB_SZ8, &syncin);
port = *(rip + 1);
- sw_exitinfo1 = (port << 16) | (1ULL << 4) |
+ sw_exitinfo1 = ((uint64_t)port << 16) | (1ULL << 4) |
(1ULL << 0);
frame->tf_rip += 2;
break;
case 0xe6: /* outb %al,$port */
ghcb_sync_val(GHCB_RAX, GHCB_SZ8, &syncout);
port = *(rip + 1);
- sw_exitinfo1 = (port << 16) | (1ULL << 4);
+ sw_exitinfo1 = ((uint64_t)port << 16) | (1ULL << 4);
frame->tf_rip += 2;
break;
case 0xec: /* in (%dx),%al */
ghcb_sync_val(GHCB_RAX, GHCB_SZ8, &syncin);
port = (uint16_t)frame->tf_rdx;
- sw_exitinfo1 = (port << 16) | (1ULL << 4) |
+ sw_exitinfo1 = ((uint64_t)port << 16) | (1ULL << 4) |
(1ULL << 0);
frame->tf_rip += 1;
break;
case 0xed: /* in (%dx),%eax */
ghcb_sync_val(GHCB_RAX, GHCB_SZ32, &syncin);
port = (uint16_t)frame->tf_rdx;
- sw_exitinfo1 = (port << 16) | (1ULL << 6) |
+ sw_exitinfo1 = ((uint64_t)port << 16) | (1ULL << 6) |
(1ULL << 0);
frame->tf_rip += 1;
break;
case 0xee: /* out %al,(%dx) */
ghcb_sync_val(GHCB_RAX, GHCB_SZ8, &syncout);
port = (uint16_t)frame->tf_rdx;
- sw_exitinfo1 = (port << 16) | (1ULL << 4);
+ sw_exitinfo1 = ((uint64_t)port << 16) | (1ULL << 4);
frame->tf_rip += 1;
break;
case 0xef: /* out %eax,(%dx) */
ghcb_sync_val(GHCB_RAX, GHCB_SZ32, &syncout);
port = (uint16_t)frame->tf_rdx;
- sw_exitinfo1 = (port << 16) | (1ULL << 6);
+ sw_exitinfo1 = ((uint64_t)port << 16) | (1ULL << 6);
frame->tf_rip += 1;
break;
default:
Avoid implicit sign extension in vctrap()