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