@@ -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+
19102012static 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 ;
0 commit comments