@@ -1856,49 +1856,39 @@ static int do_cmd_ioctl(struct comedi_device *dev,
1856
1856
* possibly modified comedi_cmd structure
1857
1857
*/
1858
1858
static int do_cmdtest_ioctl (struct comedi_device * dev ,
1859
- struct comedi_cmd __user * arg , void * file )
1859
+ struct comedi_cmd * cmd , bool * copy , void * file )
1860
1860
{
1861
- struct comedi_cmd cmd ;
1862
1861
struct comedi_subdevice * s ;
1863
1862
unsigned int __user * user_chanlist ;
1864
1863
int ret ;
1865
1864
1866
1865
lockdep_assert_held (& dev -> mutex );
1867
1866
1868
- if (copy_from_user (& cmd , arg , sizeof (cmd ))) {
1869
- dev_dbg (dev -> class_dev , "bad cmd address\n" );
1870
- return - EFAULT ;
1871
- }
1872
-
1873
- /* get the user's cmd and do some simple validation */
1874
- ret = __comedi_get_user_cmd (dev , & cmd );
1867
+ /* do some simple cmd validation */
1868
+ ret = __comedi_get_user_cmd (dev , cmd );
1875
1869
if (ret )
1876
1870
return ret ;
1877
1871
1878
1872
/* save user's chanlist pointer so it can be restored later */
1879
- user_chanlist = (unsigned int __user * )cmd . chanlist ;
1873
+ user_chanlist = (unsigned int __user * )cmd -> chanlist ;
1880
1874
1881
- s = & dev -> subdevices [cmd . subdev ];
1875
+ s = & dev -> subdevices [cmd -> subdev ];
1882
1876
1883
1877
/* user_chanlist can be NULL for COMEDI_CMDTEST ioctl */
1884
1878
if (user_chanlist ) {
1885
1879
/* load channel/gain list */
1886
- ret = __comedi_get_user_chanlist (dev , s , user_chanlist , & cmd );
1880
+ ret = __comedi_get_user_chanlist (dev , s , user_chanlist , cmd );
1887
1881
if (ret )
1888
1882
return ret ;
1889
1883
}
1890
1884
1891
- ret = s -> do_cmdtest (dev , s , & cmd );
1885
+ ret = s -> do_cmdtest (dev , s , cmd );
1892
1886
1893
- kfree (cmd . chanlist ); /* free kernel copy of user chanlist */
1887
+ kfree (cmd -> chanlist ); /* free kernel copy of user chanlist */
1894
1888
1895
1889
/* restore chanlist pointer before copying back */
1896
- cmd .chanlist = (unsigned int __force * )user_chanlist ;
1897
-
1898
- if (copy_to_user (arg , & cmd , sizeof (cmd ))) {
1899
- dev_dbg (dev -> class_dev , "bad cmd address\n" );
1900
- ret = - EFAULT ;
1901
- }
1890
+ cmd -> chanlist = (unsigned int __force * )user_chanlist ;
1891
+ * copy = true;
1902
1892
1903
1893
return ret ;
1904
1894
}
@@ -2220,10 +2210,19 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
2220
2210
case COMEDI_CMD :
2221
2211
rc = do_cmd_ioctl (dev , (struct comedi_cmd __user * )arg , file );
2222
2212
break ;
2223
- case COMEDI_CMDTEST :
2224
- rc = do_cmdtest_ioctl (dev , (struct comedi_cmd __user * )arg ,
2225
- file );
2213
+ case COMEDI_CMDTEST : {
2214
+ struct comedi_cmd cmd ;
2215
+ bool copy = false;
2216
+
2217
+ if (copy_from_user (& cmd , (void __user * )arg , sizeof (cmd ))) {
2218
+ rc = - EFAULT ;
2219
+ break ;
2220
+ }
2221
+ rc = do_cmdtest_ioctl (dev , & cmd , & copy , file );
2222
+ if (copy && copy_to_user ((void __user * )arg , & cmd , sizeof (cmd )))
2223
+ rc = - EFAULT ;
2226
2224
break ;
2225
+ }
2227
2226
case COMEDI_INSNLIST : {
2228
2227
struct comedi_insnlist insnlist ;
2229
2228
struct comedi_insn * insns = NULL ;
0 commit comments