@@ -1637,6 +1637,7 @@ smb2_ioctl_query_info(const unsigned int xid,
16371637 unsigned int size [2 ];
16381638 void * data [2 ];
16391639 int create_options = is_dir ? CREATE_NOT_FILE : CREATE_NOT_DIR ;
1640+ void (* free_req1_func )(struct smb_rqst * r );
16401641
16411642 vars = kzalloc (sizeof (* vars ), GFP_ATOMIC );
16421643 if (vars == NULL )
@@ -1646,17 +1647,18 @@ smb2_ioctl_query_info(const unsigned int xid,
16461647
16471648 resp_buftype [0 ] = resp_buftype [1 ] = resp_buftype [2 ] = CIFS_NO_BUFFER ;
16481649
1649- if (copy_from_user (& qi , arg , sizeof (struct smb_query_info )))
1650- goto e_fault ;
1651-
1650+ if (copy_from_user (& qi , arg , sizeof (struct smb_query_info ))) {
1651+ rc = - EFAULT ;
1652+ goto free_vars ;
1653+ }
16521654 if (qi .output_buffer_length > 1024 ) {
1653- kfree ( vars ) ;
1654- return - EINVAL ;
1655+ rc = - EINVAL ;
1656+ goto free_vars ;
16551657 }
16561658
16571659 if (!ses || !server ) {
1658- kfree ( vars ) ;
1659- return - EIO ;
1660+ rc = - EIO ;
1661+ goto free_vars ;
16601662 }
16611663
16621664 if (smb3_encryption_required (tcon ))
@@ -1665,8 +1667,8 @@ smb2_ioctl_query_info(const unsigned int xid,
16651667 if (qi .output_buffer_length ) {
16661668 buffer = memdup_user (arg + sizeof (struct smb_query_info ), qi .output_buffer_length );
16671669 if (IS_ERR (buffer )) {
1668- kfree ( vars );
1669- return PTR_ERR ( buffer ) ;
1670+ rc = PTR_ERR ( buffer );
1671+ goto free_vars ;
16701672 }
16711673 }
16721674
@@ -1705,48 +1707,45 @@ smb2_ioctl_query_info(const unsigned int xid,
17051707 rc = SMB2_open_init (tcon , server ,
17061708 & rqst [0 ], & oplock , & oparms , path );
17071709 if (rc )
1708- goto iqinf_exit ;
1710+ goto free_output_buffer ;
17091711 smb2_set_next_command (tcon , & rqst [0 ]);
17101712
17111713 /* Query */
17121714 if (qi .flags & PASSTHRU_FSCTL ) {
17131715 /* Can eventually relax perm check since server enforces too */
1714- if (!capable (CAP_SYS_ADMIN ))
1716+ if (!capable (CAP_SYS_ADMIN )) {
17151717 rc = - EPERM ;
1716- else {
1717- rqst [1 ].rq_iov = & vars -> io_iov [0 ];
1718- rqst [1 ].rq_nvec = SMB2_IOCTL_IOV_SIZE ;
1719-
1720- rc = SMB2_ioctl_init (tcon , server ,
1721- & rqst [1 ],
1722- COMPOUND_FID , COMPOUND_FID ,
1723- qi .info_type , true, buffer ,
1724- qi .output_buffer_length ,
1725- CIFSMaxBufSize -
1726- MAX_SMB2_CREATE_RESPONSE_SIZE -
1727- MAX_SMB2_CLOSE_RESPONSE_SIZE );
1718+ goto free_open_req ;
17281719 }
1720+ rqst [1 ].rq_iov = & vars -> io_iov [0 ];
1721+ rqst [1 ].rq_nvec = SMB2_IOCTL_IOV_SIZE ;
1722+
1723+ rc = SMB2_ioctl_init (tcon , server , & rqst [1 ], COMPOUND_FID , COMPOUND_FID ,
1724+ qi .info_type , true, buffer , qi .output_buffer_length ,
1725+ CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE -
1726+ MAX_SMB2_CLOSE_RESPONSE_SIZE );
1727+ free_req1_func = SMB2_ioctl_free ;
17291728 } else if (qi .flags == PASSTHRU_SET_INFO ) {
17301729 /* Can eventually relax perm check since server enforces too */
1731- if (!capable (CAP_SYS_ADMIN ))
1730+ if (!capable (CAP_SYS_ADMIN )) {
17321731 rc = - EPERM ;
1733- else if (qi .output_buffer_length < 8 )
1732+ goto free_open_req ;
1733+ }
1734+ if (qi .output_buffer_length < 8 ) {
17341735 rc = - EINVAL ;
1735- else {
1736- rqst [1 ].rq_iov = & vars -> si_iov [0 ];
1737- rqst [1 ].rq_nvec = 1 ;
1738-
1739- /* MS-FSCC 2.4.13 FileEndOfFileInformation */
1740- size [0 ] = 8 ;
1741- data [0 ] = buffer ;
1742-
1743- rc = SMB2_set_info_init (tcon , server ,
1744- & rqst [1 ],
1745- COMPOUND_FID , COMPOUND_FID ,
1746- current -> tgid ,
1747- FILE_END_OF_FILE_INFORMATION ,
1748- SMB2_O_INFO_FILE , 0 , data , size );
1736+ goto free_open_req ;
17491737 }
1738+ rqst [1 ].rq_iov = & vars -> si_iov [0 ];
1739+ rqst [1 ].rq_nvec = 1 ;
1740+
1741+ /* MS-FSCC 2.4.13 FileEndOfFileInformation */
1742+ size [0 ] = 8 ;
1743+ data [0 ] = buffer ;
1744+
1745+ rc = SMB2_set_info_init (tcon , server , & rqst [1 ], COMPOUND_FID , COMPOUND_FID ,
1746+ current -> tgid , FILE_END_OF_FILE_INFORMATION ,
1747+ SMB2_O_INFO_FILE , 0 , data , size );
1748+ free_req1_func = SMB2_set_info_free ;
17501749 } else if (qi .flags == PASSTHRU_QUERY_INFO ) {
17511750 rqst [1 ].rq_iov = & vars -> qi_iov [0 ];
17521751 rqst [1 ].rq_nvec = 1 ;
@@ -1757,14 +1756,15 @@ smb2_ioctl_query_info(const unsigned int xid,
17571756 qi .info_type , qi .additional_information ,
17581757 qi .input_buffer_length ,
17591758 qi .output_buffer_length , buffer );
1759+ free_req1_func = SMB2_query_info_free ;
17601760 } else { /* unknown flags */
17611761 cifs_tcon_dbg (VFS , "Invalid passthru query flags: 0x%x\n" ,
17621762 qi .flags );
17631763 rc = - EINVAL ;
17641764 }
17651765
17661766 if (rc )
1767- goto iqinf_exit ;
1767+ goto free_open_req ;
17681768 smb2_set_next_command (tcon , & rqst [1 ]);
17691769 smb2_set_related (& rqst [1 ]);
17701770
@@ -1775,14 +1775,14 @@ smb2_ioctl_query_info(const unsigned int xid,
17751775 rc = SMB2_close_init (tcon , server ,
17761776 & rqst [2 ], COMPOUND_FID , COMPOUND_FID , false);
17771777 if (rc )
1778- goto iqinf_exit ;
1778+ goto free_req_1 ;
17791779 smb2_set_related (& rqst [2 ]);
17801780
17811781 rc = compound_send_recv (xid , ses , server ,
17821782 flags , 3 , rqst ,
17831783 resp_buftype , rsp_iov );
17841784 if (rc )
1785- goto iqinf_exit ;
1785+ goto out ;
17861786
17871787 /* No need to bump num_remote_opens since handle immediately closed */
17881788 if (qi .flags & PASSTHRU_FSCTL ) {
@@ -1792,47 +1792,53 @@ smb2_ioctl_query_info(const unsigned int xid,
17921792 qi .input_buffer_length = le32_to_cpu (io_rsp -> OutputCount );
17931793 if (qi .input_buffer_length > 0 &&
17941794 le32_to_cpu (io_rsp -> OutputOffset ) + qi .input_buffer_length
1795- > rsp_iov [1 ].iov_len )
1796- goto e_fault ;
1795+ > rsp_iov [1 ].iov_len ) {
1796+ rc = - EFAULT ;
1797+ goto out ;
1798+ }
17971799
17981800 if (copy_to_user (& pqi -> input_buffer_length ,
17991801 & qi .input_buffer_length ,
1800- sizeof (qi .input_buffer_length )))
1801- goto e_fault ;
1802+ sizeof (qi .input_buffer_length ))) {
1803+ rc = - EFAULT ;
1804+ goto out ;
1805+ }
18021806
18031807 if (copy_to_user ((void __user * )pqi + sizeof (struct smb_query_info ),
18041808 (const void * )io_rsp + le32_to_cpu (io_rsp -> OutputOffset ),
18051809 qi .input_buffer_length ))
1806- goto e_fault ;
1810+ rc = - EFAULT ;
18071811 } else {
18081812 pqi = (struct smb_query_info __user * )arg ;
18091813 qi_rsp = (struct smb2_query_info_rsp * )rsp_iov [1 ].iov_base ;
18101814 if (le32_to_cpu (qi_rsp -> OutputBufferLength ) < qi .input_buffer_length )
18111815 qi .input_buffer_length = le32_to_cpu (qi_rsp -> OutputBufferLength );
18121816 if (copy_to_user (& pqi -> input_buffer_length ,
18131817 & qi .input_buffer_length ,
1814- sizeof (qi .input_buffer_length )))
1815- goto e_fault ;
1818+ sizeof (qi .input_buffer_length ))) {
1819+ rc = - EFAULT ;
1820+ goto out ;
1821+ }
18161822
18171823 if (copy_to_user (pqi + 1 , qi_rsp -> Buffer ,
18181824 qi .input_buffer_length ))
1819- goto e_fault ;
1825+ rc = - EFAULT ;
18201826 }
18211827
1822- iqinf_exit :
1823- cifs_small_buf_release (rqst [0 ].rq_iov [0 ].iov_base );
1824- cifs_small_buf_release (rqst [1 ].rq_iov [0 ].iov_base );
1825- cifs_small_buf_release (rqst [2 ].rq_iov [0 ].iov_base );
1828+ out :
18261829 free_rsp_buf (resp_buftype [0 ], rsp_iov [0 ].iov_base );
18271830 free_rsp_buf (resp_buftype [1 ], rsp_iov [1 ].iov_base );
18281831 free_rsp_buf (resp_buftype [2 ], rsp_iov [2 ].iov_base );
1829- kfree (vars );
1832+ SMB2_close_free (& rqst [2 ]);
1833+ free_req_1 :
1834+ free_req1_func (& rqst [1 ]);
1835+ free_open_req :
1836+ SMB2_open_free (& rqst [0 ]);
1837+ free_output_buffer :
18301838 kfree (buffer );
1839+ free_vars :
1840+ kfree (vars );
18311841 return rc ;
1832-
1833- e_fault :
1834- rc = - EFAULT ;
1835- goto iqinf_exit ;
18361842}
18371843
18381844static ssize_t
0 commit comments