@@ -1645,6 +1645,7 @@ smb2_ioctl_query_info(const unsigned int xid,
1645
1645
unsigned int size [2 ];
1646
1646
void * data [2 ];
1647
1647
int create_options = is_dir ? CREATE_NOT_FILE : CREATE_NOT_DIR ;
1648
+ void (* free_req1_func )(struct smb_rqst * r );
1648
1649
1649
1650
vars = kzalloc (sizeof (* vars ), GFP_ATOMIC );
1650
1651
if (vars == NULL )
@@ -1654,17 +1655,18 @@ smb2_ioctl_query_info(const unsigned int xid,
1654
1655
1655
1656
resp_buftype [0 ] = resp_buftype [1 ] = resp_buftype [2 ] = CIFS_NO_BUFFER ;
1656
1657
1657
- if (copy_from_user (& qi , arg , sizeof (struct smb_query_info )))
1658
- goto e_fault ;
1659
-
1658
+ if (copy_from_user (& qi , arg , sizeof (struct smb_query_info ))) {
1659
+ rc = - EFAULT ;
1660
+ goto free_vars ;
1661
+ }
1660
1662
if (qi .output_buffer_length > 1024 ) {
1661
- kfree ( vars ) ;
1662
- return - EINVAL ;
1663
+ rc = - EINVAL ;
1664
+ goto free_vars ;
1663
1665
}
1664
1666
1665
1667
if (!ses || !server ) {
1666
- kfree ( vars ) ;
1667
- return - EIO ;
1668
+ rc = - EIO ;
1669
+ goto free_vars ;
1668
1670
}
1669
1671
1670
1672
if (smb3_encryption_required (tcon ))
@@ -1673,8 +1675,8 @@ smb2_ioctl_query_info(const unsigned int xid,
1673
1675
if (qi .output_buffer_length ) {
1674
1676
buffer = memdup_user (arg + sizeof (struct smb_query_info ), qi .output_buffer_length );
1675
1677
if (IS_ERR (buffer )) {
1676
- kfree ( vars );
1677
- return PTR_ERR ( buffer ) ;
1678
+ rc = PTR_ERR ( buffer );
1679
+ goto free_vars ;
1678
1680
}
1679
1681
}
1680
1682
@@ -1713,48 +1715,45 @@ smb2_ioctl_query_info(const unsigned int xid,
1713
1715
rc = SMB2_open_init (tcon , server ,
1714
1716
& rqst [0 ], & oplock , & oparms , path );
1715
1717
if (rc )
1716
- goto iqinf_exit ;
1718
+ goto free_output_buffer ;
1717
1719
smb2_set_next_command (tcon , & rqst [0 ]);
1718
1720
1719
1721
/* Query */
1720
1722
if (qi .flags & PASSTHRU_FSCTL ) {
1721
1723
/* Can eventually relax perm check since server enforces too */
1722
- if (!capable (CAP_SYS_ADMIN ))
1724
+ if (!capable (CAP_SYS_ADMIN )) {
1723
1725
rc = - EPERM ;
1724
- else {
1725
- rqst [1 ].rq_iov = & vars -> io_iov [0 ];
1726
- rqst [1 ].rq_nvec = SMB2_IOCTL_IOV_SIZE ;
1727
-
1728
- rc = SMB2_ioctl_init (tcon , server ,
1729
- & rqst [1 ],
1730
- COMPOUND_FID , COMPOUND_FID ,
1731
- qi .info_type , true, buffer ,
1732
- qi .output_buffer_length ,
1733
- CIFSMaxBufSize -
1734
- MAX_SMB2_CREATE_RESPONSE_SIZE -
1735
- MAX_SMB2_CLOSE_RESPONSE_SIZE );
1726
+ goto free_open_req ;
1736
1727
}
1728
+ rqst [1 ].rq_iov = & vars -> io_iov [0 ];
1729
+ rqst [1 ].rq_nvec = SMB2_IOCTL_IOV_SIZE ;
1730
+
1731
+ rc = SMB2_ioctl_init (tcon , server , & rqst [1 ], COMPOUND_FID , COMPOUND_FID ,
1732
+ qi .info_type , true, buffer , qi .output_buffer_length ,
1733
+ CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE -
1734
+ MAX_SMB2_CLOSE_RESPONSE_SIZE );
1735
+ free_req1_func = SMB2_ioctl_free ;
1737
1736
} else if (qi .flags == PASSTHRU_SET_INFO ) {
1738
1737
/* Can eventually relax perm check since server enforces too */
1739
- if (!capable (CAP_SYS_ADMIN ))
1738
+ if (!capable (CAP_SYS_ADMIN )) {
1740
1739
rc = - EPERM ;
1741
- else if (qi .output_buffer_length < 8 )
1740
+ goto free_open_req ;
1741
+ }
1742
+ if (qi .output_buffer_length < 8 ) {
1742
1743
rc = - EINVAL ;
1743
- else {
1744
- rqst [1 ].rq_iov = & vars -> si_iov [0 ];
1745
- rqst [1 ].rq_nvec = 1 ;
1746
-
1747
- /* MS-FSCC 2.4.13 FileEndOfFileInformation */
1748
- size [0 ] = 8 ;
1749
- data [0 ] = buffer ;
1750
-
1751
- rc = SMB2_set_info_init (tcon , server ,
1752
- & rqst [1 ],
1753
- COMPOUND_FID , COMPOUND_FID ,
1754
- current -> tgid ,
1755
- FILE_END_OF_FILE_INFORMATION ,
1756
- SMB2_O_INFO_FILE , 0 , data , size );
1744
+ goto free_open_req ;
1757
1745
}
1746
+ rqst [1 ].rq_iov = & vars -> si_iov [0 ];
1747
+ rqst [1 ].rq_nvec = 1 ;
1748
+
1749
+ /* MS-FSCC 2.4.13 FileEndOfFileInformation */
1750
+ size [0 ] = 8 ;
1751
+ data [0 ] = buffer ;
1752
+
1753
+ rc = SMB2_set_info_init (tcon , server , & rqst [1 ], COMPOUND_FID , COMPOUND_FID ,
1754
+ current -> tgid , FILE_END_OF_FILE_INFORMATION ,
1755
+ SMB2_O_INFO_FILE , 0 , data , size );
1756
+ free_req1_func = SMB2_set_info_free ;
1758
1757
} else if (qi .flags == PASSTHRU_QUERY_INFO ) {
1759
1758
rqst [1 ].rq_iov = & vars -> qi_iov [0 ];
1760
1759
rqst [1 ].rq_nvec = 1 ;
@@ -1765,14 +1764,15 @@ smb2_ioctl_query_info(const unsigned int xid,
1765
1764
qi .info_type , qi .additional_information ,
1766
1765
qi .input_buffer_length ,
1767
1766
qi .output_buffer_length , buffer );
1767
+ free_req1_func = SMB2_query_info_free ;
1768
1768
} else { /* unknown flags */
1769
1769
cifs_tcon_dbg (VFS , "Invalid passthru query flags: 0x%x\n" ,
1770
1770
qi .flags );
1771
1771
rc = - EINVAL ;
1772
1772
}
1773
1773
1774
1774
if (rc )
1775
- goto iqinf_exit ;
1775
+ goto free_open_req ;
1776
1776
smb2_set_next_command (tcon , & rqst [1 ]);
1777
1777
smb2_set_related (& rqst [1 ]);
1778
1778
@@ -1783,14 +1783,14 @@ smb2_ioctl_query_info(const unsigned int xid,
1783
1783
rc = SMB2_close_init (tcon , server ,
1784
1784
& rqst [2 ], COMPOUND_FID , COMPOUND_FID , false);
1785
1785
if (rc )
1786
- goto iqinf_exit ;
1786
+ goto free_req_1 ;
1787
1787
smb2_set_related (& rqst [2 ]);
1788
1788
1789
1789
rc = compound_send_recv (xid , ses , server ,
1790
1790
flags , 3 , rqst ,
1791
1791
resp_buftype , rsp_iov );
1792
1792
if (rc )
1793
- goto iqinf_exit ;
1793
+ goto out ;
1794
1794
1795
1795
/* No need to bump num_remote_opens since handle immediately closed */
1796
1796
if (qi .flags & PASSTHRU_FSCTL ) {
@@ -1800,47 +1800,53 @@ smb2_ioctl_query_info(const unsigned int xid,
1800
1800
qi .input_buffer_length = le32_to_cpu (io_rsp -> OutputCount );
1801
1801
if (qi .input_buffer_length > 0 &&
1802
1802
le32_to_cpu (io_rsp -> OutputOffset ) + qi .input_buffer_length
1803
- > rsp_iov [1 ].iov_len )
1804
- goto e_fault ;
1803
+ > rsp_iov [1 ].iov_len ) {
1804
+ rc = - EFAULT ;
1805
+ goto out ;
1806
+ }
1805
1807
1806
1808
if (copy_to_user (& pqi -> input_buffer_length ,
1807
1809
& qi .input_buffer_length ,
1808
- sizeof (qi .input_buffer_length )))
1809
- goto e_fault ;
1810
+ sizeof (qi .input_buffer_length ))) {
1811
+ rc = - EFAULT ;
1812
+ goto out ;
1813
+ }
1810
1814
1811
1815
if (copy_to_user ((void __user * )pqi + sizeof (struct smb_query_info ),
1812
1816
(const void * )io_rsp + le32_to_cpu (io_rsp -> OutputOffset ),
1813
1817
qi .input_buffer_length ))
1814
- goto e_fault ;
1818
+ rc = - EFAULT ;
1815
1819
} else {
1816
1820
pqi = (struct smb_query_info __user * )arg ;
1817
1821
qi_rsp = (struct smb2_query_info_rsp * )rsp_iov [1 ].iov_base ;
1818
1822
if (le32_to_cpu (qi_rsp -> OutputBufferLength ) < qi .input_buffer_length )
1819
1823
qi .input_buffer_length = le32_to_cpu (qi_rsp -> OutputBufferLength );
1820
1824
if (copy_to_user (& pqi -> input_buffer_length ,
1821
1825
& qi .input_buffer_length ,
1822
- sizeof (qi .input_buffer_length )))
1823
- goto e_fault ;
1826
+ sizeof (qi .input_buffer_length ))) {
1827
+ rc = - EFAULT ;
1828
+ goto out ;
1829
+ }
1824
1830
1825
1831
if (copy_to_user (pqi + 1 , qi_rsp -> Buffer ,
1826
1832
qi .input_buffer_length ))
1827
- goto e_fault ;
1833
+ rc = - EFAULT ;
1828
1834
}
1829
1835
1830
- iqinf_exit :
1831
- cifs_small_buf_release (rqst [0 ].rq_iov [0 ].iov_base );
1832
- cifs_small_buf_release (rqst [1 ].rq_iov [0 ].iov_base );
1833
- cifs_small_buf_release (rqst [2 ].rq_iov [0 ].iov_base );
1836
+ out :
1834
1837
free_rsp_buf (resp_buftype [0 ], rsp_iov [0 ].iov_base );
1835
1838
free_rsp_buf (resp_buftype [1 ], rsp_iov [1 ].iov_base );
1836
1839
free_rsp_buf (resp_buftype [2 ], rsp_iov [2 ].iov_base );
1837
- kfree (vars );
1840
+ SMB2_close_free (& rqst [2 ]);
1841
+ free_req_1 :
1842
+ free_req1_func (& rqst [1 ]);
1843
+ free_open_req :
1844
+ SMB2_open_free (& rqst [0 ]);
1845
+ free_output_buffer :
1838
1846
kfree (buffer );
1847
+ free_vars :
1848
+ kfree (vars );
1839
1849
return rc ;
1840
-
1841
- e_fault :
1842
- rc = - EFAULT ;
1843
- goto iqinf_exit ;
1844
1850
}
1845
1851
1846
1852
static ssize_t
0 commit comments