Skip to content

Commit f8c43e1

Browse files
ejohnstownaidangarske
authored andcommitted
Test DoChannelWindowAdjust overflow guard
- Add test_DoChannelWindowAdjust_overflow via new wolfSSH_TestDoChannelWindowAdjust wrapper. - Seed non-zero peer window, feed bytesToAdd = UINT32_MAX, assert WS_OVERFLOW_E with window unchanged. - Feed a fitting value, assert window advances. - Covers the guard so flipping or deleting it now fails. Issue: F-2874
1 parent 974f4fd commit f8c43e1

3 files changed

Lines changed: 115 additions & 0 deletions

File tree

src/internal.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19976,6 +19976,12 @@ int wolfSSH_TestDoChannelExtendedData(WOLFSSH* ssh, byte* buf, word32 len,
1997619976
return DoChannelExtendedData(ssh, buf, len, idx);
1997719977
}
1997819978

19979+
int wolfSSH_TestDoChannelWindowAdjust(WOLFSSH* ssh, byte* buf, word32 len,
19980+
word32* idx)
19981+
{
19982+
return DoChannelWindowAdjust(ssh, buf, len, idx);
19983+
}
19984+
1997919985
int wolfSSH_TestDoUserAuthRequest(WOLFSSH* ssh, byte* buf, word32 len,
1998019986
word32* idx)
1998119987
{

tests/unit.c

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1907,6 +1907,108 @@ static int test_DoChannelExtendedData_overflow(void)
19071907
return result;
19081908
}
19091909

1910+
/* DoChannelWindowAdjust adds the peer's advertised bytes to peerWindowSz.
1911+
* A crafted bytesToAdd that would wrap the word32 must be rejected with
1912+
* WS_OVERFLOW_E and leave the window untouched; a value that fits must be
1913+
* applied. No other test exercises this handler. */
1914+
static int test_DoChannelWindowAdjust_overflow(void)
1915+
{
1916+
WOLFSSH_CTX* ctx = NULL;
1917+
WOLFSSH* ssh = NULL;
1918+
WOLFSSH_CHANNEL* ch = NULL;
1919+
int result = 0;
1920+
int ret;
1921+
word32 idx;
1922+
1923+
/* channelId=0, bytesToAdd=0xFFFFFFFF (UINT32_MAX): wraps peerWindowSz. */
1924+
static const byte payOver[] = {
1925+
0x00, 0x00, 0x00, 0x00, /* channelId = 0 */
1926+
0xFF, 0xFF, 0xFF, 0xFF /* bytesToAdd = UINT32_MAX */
1927+
};
1928+
1929+
/* channelId=0, bytesToAdd=0x40 (64): fits, advances the window. */
1930+
static const byte payOk[] = {
1931+
0x00, 0x00, 0x00, 0x00, /* channelId = 0 */
1932+
0x00, 0x00, 0x00, 0x40 /* bytesToAdd = 64 */
1933+
};
1934+
1935+
/* channelId=0, bytesToAdd=UINT32_MAX-1024 (0xFFFFFBFF): the largest value
1936+
* a 1024-byte window accepts. Fills peerWindowSz to exactly UINT32_MAX and
1937+
* exercises the exact boundary of the > guard (a >= off-by-one rejects). */
1938+
static const byte payEdgeOk[] = {
1939+
0x00, 0x00, 0x00, 0x00, /* channelId = 0 */
1940+
0xFF, 0xFF, 0xFB, 0xFF /* bytesToAdd = UINT32_MAX - 1024 */
1941+
};
1942+
1943+
/* channelId=0, bytesToAdd=UINT32_MAX-1024+1 (0xFFFFFC00): one past the
1944+
* boundary, must overflow a 1024-byte window. */
1945+
static const byte payEdgeOver[] = {
1946+
0x00, 0x00, 0x00, 0x00, /* channelId = 0 */
1947+
0xFF, 0xFF, 0xFC, 0x00 /* bytesToAdd = UINT32_MAX - 1024 + 1 */
1948+
};
1949+
1950+
ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_SERVER, NULL);
1951+
if (ctx == NULL)
1952+
return -600;
1953+
1954+
ssh = wolfSSH_new(ctx);
1955+
if (ssh == NULL) { result = -601; goto done; }
1956+
1957+
ch = ChannelNew(ssh, ID_CHANTYPE_SESSION,
1958+
DEFAULT_WINDOW_SZ, DEFAULT_MAX_PACKET_SZ);
1959+
if (ch == NULL) { result = -602; goto done; }
1960+
if (ChannelAppend(ssh, ch) != WS_SUCCESS) {
1961+
ChannelDelete(ch, ssh->ctx->heap);
1962+
result = -603;
1963+
goto done;
1964+
}
1965+
1966+
/* Non-zero peer window so a UINT32_MAX adjustment would wrap it. */
1967+
ch->peerWindowSz = 1024;
1968+
1969+
/* bytesToAdd = UINT32_MAX -> WS_OVERFLOW_E, window left unchanged. */
1970+
idx = 0;
1971+
ret = wolfSSH_TestDoChannelWindowAdjust(ssh, (byte*)payOver,
1972+
(word32)sizeof(payOver), &idx);
1973+
if (ret != WS_OVERFLOW_E) { result = -610; goto done; }
1974+
if (ch->peerWindowSz != 1024) { result = -611; goto done; }
1975+
if (idx != 8) { result = -612; goto done; }
1976+
1977+
/* bytesToAdd = 64 fits -> WS_SUCCESS, window advances by 64. */
1978+
idx = 0;
1979+
ret = wolfSSH_TestDoChannelWindowAdjust(ssh, (byte*)payOk,
1980+
(word32)sizeof(payOk), &idx);
1981+
if (ret != WS_SUCCESS) { result = -613; goto done; }
1982+
if (ch->peerWindowSz != 1024 + 64) { result = -614; goto done; }
1983+
if (idx != 8) { result = -615; goto done; }
1984+
1985+
/* Boundary +1: bytesToAdd = UINT32_MAX - 1024 + 1 overflows a 1024-byte
1986+
* window -> WS_OVERFLOW_E, window left unchanged. */
1987+
ch->peerWindowSz = 1024;
1988+
idx = 0;
1989+
ret = wolfSSH_TestDoChannelWindowAdjust(ssh, (byte*)payEdgeOver,
1990+
(word32)sizeof(payEdgeOver), &idx);
1991+
if (ret != WS_OVERFLOW_E) { result = -616; goto done; }
1992+
if (ch->peerWindowSz != 1024) { result = -617; goto done; }
1993+
if (idx != 8) { result = -618; goto done; }
1994+
1995+
/* Boundary: bytesToAdd = UINT32_MAX - 1024 is the largest value that fits
1996+
* -> WS_SUCCESS, window filled to exactly UINT32_MAX. This is the case a
1997+
* >= off-by-one in the guard would wrongly reject. */
1998+
ch->peerWindowSz = 1024;
1999+
idx = 0;
2000+
ret = wolfSSH_TestDoChannelWindowAdjust(ssh, (byte*)payEdgeOk,
2001+
(word32)sizeof(payEdgeOk), &idx);
2002+
if (ret != WS_SUCCESS) { result = -619; goto done; }
2003+
if (ch->peerWindowSz != 0xFFFFFFFF) { result = -620; goto done; }
2004+
if (idx != 8) { result = -621; goto done; }
2005+
2006+
done:
2007+
wolfSSH_free(ssh);
2008+
wolfSSH_CTX_free(ctx);
2009+
return result;
2010+
}
2011+
19102012
static int test_SendChannelData_eofTxd(void)
19112013
{
19122014
WOLFSSH_CTX* ctx = NULL;
@@ -7679,6 +7781,11 @@ int wolfSSH_UnitTest(int argc, char** argv)
76797781
(unitResult == 0 ? "SUCCESS" : "FAILED"));
76807782
testResult = testResult || unitResult;
76817783

7784+
unitResult = test_DoChannelWindowAdjust_overflow();
7785+
printf("DoChannelWindowAdjust_overflow: %s\n",
7786+
(unitResult == 0 ? "SUCCESS" : "FAILED"));
7787+
testResult = testResult || unitResult;
7788+
76827789
unitResult = test_SendChannelData_eofTxd();
76837790
printf("SendChannelData_eofTxd: %s\n", (unitResult == 0 ? "SUCCESS" : "FAILED"));
76847791
testResult = testResult || unitResult;

wolfssh/internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,6 +1459,8 @@ enum WS_MessageIdLimits {
14591459
word32 len, word32* idx);
14601460
WOLFSSH_API int wolfSSH_TestDoChannelExtendedData(WOLFSSH* ssh, byte* buf,
14611461
word32 len, word32* idx);
1462+
WOLFSSH_API int wolfSSH_TestDoChannelWindowAdjust(WOLFSSH* ssh, byte* buf,
1463+
word32 len, word32* idx);
14621464
WOLFSSH_API int wolfSSH_TestDoKexInit(WOLFSSH* ssh, byte* buf,
14631465
word32 len, word32* idx);
14641466
WOLFSSH_API int wolfSSH_TestDoNewKeys(WOLFSSH* ssh, byte* buf,

0 commit comments

Comments
 (0)