@@ -1799,6 +1799,228 @@ smb3_free_transform_rq(struct smb_rqst *rqst)
17991799 kfree (rqst -> rq_iov );
18001800}
18011801
1802+ static int
1803+ smb3_is_transform_hdr (void * buf )
1804+ {
1805+ struct smb2_transform_hdr * trhdr = buf ;
1806+
1807+ return trhdr -> ProtocolId == SMB2_TRANSFORM_PROTO_NUM ;
1808+ }
1809+
1810+ static int
1811+ decrypt_raw_data (struct TCP_Server_Info * server , char * buf ,
1812+ unsigned int buf_data_size , struct page * * pages ,
1813+ unsigned int npages , unsigned int page_data_size )
1814+ {
1815+ struct kvec iov [2 ];
1816+ struct smb_rqst rqst = {NULL };
1817+ struct smb2_hdr * hdr ;
1818+ int rc ;
1819+
1820+ iov [0 ].iov_base = buf ;
1821+ iov [0 ].iov_len = sizeof (struct smb2_transform_hdr );
1822+ iov [1 ].iov_base = buf + sizeof (struct smb2_transform_hdr );
1823+ iov [1 ].iov_len = buf_data_size ;
1824+
1825+ rqst .rq_iov = iov ;
1826+ rqst .rq_nvec = 2 ;
1827+ rqst .rq_pages = pages ;
1828+ rqst .rq_npages = npages ;
1829+ rqst .rq_pagesz = PAGE_SIZE ;
1830+ rqst .rq_tailsz = (page_data_size % PAGE_SIZE ) ? : PAGE_SIZE ;
1831+
1832+ rc = crypt_message (server , & rqst , 0 );
1833+ cifs_dbg (FYI , "decrypt message returned %d\n" , rc );
1834+
1835+ if (rc )
1836+ return rc ;
1837+
1838+ memmove (buf + 4 , iov [1 ].iov_base , buf_data_size );
1839+ hdr = (struct smb2_hdr * )buf ;
1840+ hdr -> smb2_buf_length = cpu_to_be32 (buf_data_size + page_data_size );
1841+ server -> total_read = buf_data_size + page_data_size + 4 ;
1842+
1843+ return rc ;
1844+ }
1845+
1846+ static int
1847+ handle_read_data (struct TCP_Server_Info * server , struct mid_q_entry * mid ,
1848+ char * buf , unsigned int buf_len , struct page * * pages ,
1849+ unsigned int npages , unsigned int page_data_size )
1850+ {
1851+ unsigned int data_offset ;
1852+ unsigned int data_len ;
1853+ struct cifs_readdata * rdata = mid -> callback_data ;
1854+ struct smb2_sync_hdr * shdr = get_sync_hdr (buf );
1855+ struct bio_vec * bvec = NULL ;
1856+ struct iov_iter iter ;
1857+ struct kvec iov ;
1858+ int length ;
1859+
1860+ if (shdr -> Command != SMB2_READ ) {
1861+ cifs_dbg (VFS , "only big read responses are supported\n" );
1862+ return - ENOTSUPP ;
1863+ }
1864+
1865+ if (server -> ops -> is_status_pending &&
1866+ server -> ops -> is_status_pending (buf , server , 0 ))
1867+ return -1 ;
1868+
1869+ rdata -> result = server -> ops -> map_error (buf , false);
1870+ if (rdata -> result != 0 ) {
1871+ cifs_dbg (FYI , "%s: server returned error %d\n" ,
1872+ __func__ , rdata -> result );
1873+ dequeue_mid (mid , rdata -> result );
1874+ return 0 ;
1875+ }
1876+
1877+ data_offset = server -> ops -> read_data_offset (buf ) + 4 ;
1878+ data_len = server -> ops -> read_data_length (buf );
1879+
1880+ if (data_offset < server -> vals -> read_rsp_size ) {
1881+ /*
1882+ * win2k8 sometimes sends an offset of 0 when the read
1883+ * is beyond the EOF. Treat it as if the data starts just after
1884+ * the header.
1885+ */
1886+ cifs_dbg (FYI , "%s: data offset (%u) inside read response header\n" ,
1887+ __func__ , data_offset );
1888+ data_offset = server -> vals -> read_rsp_size ;
1889+ } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE ) {
1890+ /* data_offset is beyond the end of smallbuf */
1891+ cifs_dbg (FYI , "%s: data offset (%u) beyond end of smallbuf\n" ,
1892+ __func__ , data_offset );
1893+ rdata -> result = - EIO ;
1894+ dequeue_mid (mid , rdata -> result );
1895+ return 0 ;
1896+ }
1897+
1898+ if (buf_len <= data_offset ) {
1899+ /* read response payload is in pages */
1900+ /* BB add code to init iter with pages */
1901+ } else if (buf_len >= data_offset + data_len ) {
1902+ /* read response payload is in buf */
1903+ WARN_ONCE (npages > 0 , "read data can be either in buf or in pages" );
1904+ iov .iov_base = buf + data_offset ;
1905+ iov .iov_len = data_len ;
1906+ iov_iter_kvec (& iter , WRITE | ITER_KVEC , & iov , 1 , data_len );
1907+ } else {
1908+ /* read response payload cannot be in both buf and pages */
1909+ WARN_ONCE (1 , "buf can not contain only a part of read data" );
1910+ rdata -> result = - EIO ;
1911+ dequeue_mid (mid , rdata -> result );
1912+ return 0 ;
1913+ }
1914+
1915+ /* set up first iov for signature check */
1916+ rdata -> iov [0 ].iov_base = buf ;
1917+ rdata -> iov [0 ].iov_len = 4 ;
1918+ rdata -> iov [1 ].iov_base = buf + 4 ;
1919+ rdata -> iov [1 ].iov_len = server -> vals -> read_rsp_size - 4 ;
1920+ cifs_dbg (FYI , "0: iov_base=%p iov_len=%zu\n" ,
1921+ rdata -> iov [0 ].iov_base , server -> vals -> read_rsp_size );
1922+
1923+ length = rdata -> copy_into_pages (server , rdata , & iter );
1924+
1925+ kfree (bvec );
1926+
1927+ if (length < 0 )
1928+ return length ;
1929+
1930+ dequeue_mid (mid , false);
1931+ return length ;
1932+ }
1933+
1934+ static int
1935+ receive_encrypted_standard (struct TCP_Server_Info * server ,
1936+ struct mid_q_entry * * mid )
1937+ {
1938+ int length ;
1939+ char * buf = server -> smallbuf ;
1940+ unsigned int pdu_length = get_rfc1002_length (buf );
1941+ unsigned int buf_size ;
1942+ struct mid_q_entry * mid_entry ;
1943+
1944+ /* switch to large buffer if too big for a small one */
1945+ if (pdu_length + 4 > MAX_CIFS_SMALL_BUFFER_SIZE ) {
1946+ server -> large_buf = true;
1947+ memcpy (server -> bigbuf , buf , server -> total_read );
1948+ buf = server -> bigbuf ;
1949+ }
1950+
1951+ /* now read the rest */
1952+ length = cifs_read_from_socket (server , buf + HEADER_SIZE (server ) - 1 ,
1953+ pdu_length - HEADER_SIZE (server ) + 1 + 4 );
1954+ if (length < 0 )
1955+ return length ;
1956+ server -> total_read += length ;
1957+
1958+ buf_size = pdu_length + 4 - sizeof (struct smb2_transform_hdr );
1959+ length = decrypt_raw_data (server , buf , buf_size , NULL , 0 , 0 );
1960+ if (length )
1961+ return length ;
1962+
1963+ mid_entry = smb2_find_mid (server , buf );
1964+ if (mid_entry == NULL )
1965+ cifs_dbg (FYI , "mid not found\n" );
1966+ else {
1967+ cifs_dbg (FYI , "mid found\n" );
1968+ mid_entry -> decrypted = true;
1969+ }
1970+
1971+ * mid = mid_entry ;
1972+
1973+ if (mid_entry && mid_entry -> handle )
1974+ return mid_entry -> handle (server , mid_entry );
1975+
1976+ return cifs_handle_standard (server , mid_entry );
1977+ }
1978+
1979+ static int
1980+ smb3_receive_transform (struct TCP_Server_Info * server , struct mid_q_entry * * mid )
1981+ {
1982+ char * buf = server -> smallbuf ;
1983+ unsigned int pdu_length = get_rfc1002_length (buf );
1984+ struct smb2_transform_hdr * tr_hdr = (struct smb2_transform_hdr * )buf ;
1985+ unsigned int orig_len = le32_to_cpu (tr_hdr -> OriginalMessageSize );
1986+
1987+ if (pdu_length + 4 < sizeof (struct smb2_transform_hdr ) +
1988+ sizeof (struct smb2_sync_hdr )) {
1989+ cifs_dbg (VFS , "Transform message is too small (%u)\n" ,
1990+ pdu_length );
1991+ cifs_reconnect (server );
1992+ wake_up (& server -> response_q );
1993+ return - ECONNABORTED ;
1994+ }
1995+
1996+ if (pdu_length + 4 < orig_len + sizeof (struct smb2_transform_hdr )) {
1997+ cifs_dbg (VFS , "Transform message is broken\n" );
1998+ cifs_reconnect (server );
1999+ wake_up (& server -> response_q );
2000+ return - ECONNABORTED ;
2001+ }
2002+
2003+ if (pdu_length + 4 > CIFSMaxBufSize + MAX_HEADER_SIZE (server )) {
2004+ cifs_dbg (VFS , "Decoding responses of big size (%u) is not supported\n" ,
2005+ pdu_length );
2006+ /* BB add code to allocate and fill highmem pages here */
2007+ cifs_reconnect (server );
2008+ wake_up (& server -> response_q );
2009+ return - ECONNABORTED ;
2010+ }
2011+
2012+ return receive_encrypted_standard (server , mid );
2013+ }
2014+
2015+ int
2016+ smb3_handle_read_data (struct TCP_Server_Info * server , struct mid_q_entry * mid )
2017+ {
2018+ char * buf = server -> large_buf ? server -> bigbuf : server -> smallbuf ;
2019+
2020+ return handle_read_data (server , mid , buf , get_rfc1002_length (buf ) + 4 ,
2021+ NULL , 0 , 0 );
2022+ }
2023+
18022024struct smb_version_operations smb20_operations = {
18032025 .compare_fids = smb2_compare_fids ,
18042026 .setup_request = smb2_setup_request ,
@@ -2047,6 +2269,8 @@ struct smb_version_operations smb30_operations = {
20472269 .enum_snapshots = smb3_enum_snapshots ,
20482270 .init_transform_rq = smb3_init_transform_rq ,
20492271 .free_transform_rq = smb3_free_transform_rq ,
2272+ .is_transform_hdr = smb3_is_transform_hdr ,
2273+ .receive_transform = smb3_receive_transform ,
20502274};
20512275
20522276#ifdef CONFIG_CIFS_SMB311
@@ -2137,6 +2361,8 @@ struct smb_version_operations smb311_operations = {
21372361 .enum_snapshots = smb3_enum_snapshots ,
21382362 .init_transform_rq = smb3_init_transform_rq ,
21392363 .free_transform_rq = smb3_free_transform_rq ,
2364+ .is_transform_hdr = smb3_is_transform_hdr ,
2365+ .receive_transform = smb3_receive_transform ,
21402366};
21412367#endif /* CIFS_SMB311 */
21422368
0 commit comments