History

Merge tag '20160610_uvc_compat_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/luto/linux

Pull uvc compat XU ioctl fixes from Andy Lutomirski: "uvc's compat XU ioctls go through tons of potentially buggy indirection. The first patch removes the indirection. The second one cleans up the code. Compile-tested only. I have the hardware, but I have absolutely no idea what XU does, how to use it, what software to recompile as 32-bit, or what to test in that software" * tag '20160610_uvc_compat_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/luto/linux: uvc_v4l2: Simplify compat ioctl implementation uvc: Forward compat ioctls to their handlers directly

Linus Torvalds committed 10 years ago

Commit f1c32af2 parents 3d0f0b6 f89dec71 file · +20 −77Browse files

Unified · Split

drivers/media/usb/uvc/uvc_v4l2.c+20−77
@@ -1274,8 +1274,6 @@ struct uvc_xu_control_mapping32 { · 1273 unmodified lines
12741274 static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp,
12751275 const struct uvc_xu_control_mapping32 __user *up)
12761276 {
1277− struct uvc_menu_info __user *umenus;
1278− struct uvc_menu_info __user *kmenus;
12791277 compat_caddr_t p;
12801278
12811279 if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
@@ -1292,17 +1290,7 @@ static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp, · 10 unmodified lines
12921290
12931291 if (__get_user(p, &up->menu_info))
12941292 return -EFAULT;
1295− umenus = compat_ptr(p);
1296− if (!access_ok(VERIFY_READ, umenus, kp->menu_count * sizeof(*umenus)))
1297− return -EFAULT;
1298−
1299− kmenus = compat_alloc_user_space(kp->menu_count * sizeof(*kmenus));
1300− if (kmenus == NULL)
1301− return -EFAULT;
1302− kp->menu_info = kmenus;
1303−
1304− if (copy_in_user(kmenus, umenus, kp->menu_count * sizeof(*umenus)))
1305− return -EFAULT;
1293+ kp->menu_info = compat_ptr(p);
13061294
13071295 return 0;
13081296 }
@@ -1310,10 +1298,6 @@ static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp, · 1 unmodified line
13101298 static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp,
13111299 struct uvc_xu_control_mapping32 __user *up)
13121300 {
1313− struct uvc_menu_info __user *umenus;
1314− struct uvc_menu_info __user *kmenus = kp->menu_info;
1315− compat_caddr_t p;
1316−
13171301 if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
13181302 __copy_to_user(up, kp, offsetof(typeof(*up), menu_info)) ||
13191303 __put_user(kp->menu_count, &up->menu_count))
@@ -1322,16 +1306,6 @@ static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp, · 2 unmodified lines
13221306 if (__clear_user(up->reserved, sizeof(up->reserved)))
13231307 return -EFAULT;
13241308
1325− if (kp->menu_count == 0)
1326− return 0;
1327−
1328− if (get_user(p, &up->menu_info))
1329− return -EFAULT;
1330− umenus = compat_ptr(p);
1331−
1332− if (copy_in_user(umenus, kmenus, kp->menu_count * sizeof(*umenus)))
1333− return -EFAULT;
1334−
13351309 return 0;
13361310 }
13371311
@@ -1346,8 +1320,6 @@ struct uvc_xu_control_query32 { · 8 unmodified lines
13461320 static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp,
13471321 const struct uvc_xu_control_query32 __user *up)
13481322 {
1349− u8 __user *udata;
1350− u8 __user *kdata;
13511323 compat_caddr_t p;
13521324
13531325 if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
@@ -1361,17 +1333,7 @@ static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp, · 7 unmodified lines
13611333
13621334 if (__get_user(p, &up->data))
13631335 return -EFAULT;
1364− udata = compat_ptr(p);
1365− if (!access_ok(VERIFY_READ, udata, kp->size))
1366− return -EFAULT;
1367−
1368− kdata = compat_alloc_user_space(kp->size);
1369− if (kdata == NULL)
1370− return -EFAULT;
1371− kp->data = kdata;
1372−
1373− if (copy_in_user(kdata, udata, kp->size))
1374− return -EFAULT;
1336+ kp->data = compat_ptr(p);
13751337
13761338 return 0;
13771339 }
@@ -1379,26 +1341,10 @@ static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp, · 1 unmodified line
13791341 static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp,
13801342 struct uvc_xu_control_query32 __user *up)
13811343 {
1382− u8 __user *udata;
1383− u8 __user *kdata = kp->data;
1384− compat_caddr_t p;
1385−
13861344 if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
13871345 __copy_to_user(up, kp, offsetof(typeof(*up), data)))
13881346 return -EFAULT;
13891347
1390− if (kp->size == 0)
1391− return 0;
1392−
1393− if (get_user(p, &up->data))
1394− return -EFAULT;
1395− udata = compat_ptr(p);
1396− if (!access_ok(VERIFY_READ, udata, kp->size))
1397− return -EFAULT;
1398−
1399− if (copy_in_user(udata, kdata, kp->size))
1400− return -EFAULT;
1401−
14021348 return 0;
14031349 }
14041350
@@ -1408,47 +1354,44 @@ static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp, · 3 unmodified lines
14081354 static long uvc_v4l2_compat_ioctl32(struct file *file,
14091355 unsigned int cmd, unsigned long arg)
14101356 {
1357+ struct uvc_fh *handle = file->private_data;
14111358 union {
14121359 struct uvc_xu_control_mapping xmap;
14131360 struct uvc_xu_control_query xqry;
14141361 } karg;
14151362 void __user *up = compat_ptr(arg);
1416− mm_segment_t old_fs;
14171363 long ret;
14181364
14191365 switch (cmd) {
14201366 case UVCIOC_CTRL_MAP32:
1421− cmd = UVCIOC_CTRL_MAP;
14221367 ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up);
1368+ if (ret)
1369+ return ret;
1370+ ret = uvc_ioctl_ctrl_map(handle->chain, &karg.xmap);
1371+ if (ret)
1372+ return ret;
1373+ ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
1374+ if (ret)
1375+ return ret;
1376+
14231377 break;
14241378
14251379 case UVCIOC_CTRL_QUERY32:
1426− cmd = UVCIOC_CTRL_QUERY;
14271380 ret = uvc_v4l2_get_xu_query(&karg.xqry, up);
1381+ if (ret)
1382+ return ret;
1383+ ret = uvc_xu_ctrl_query(handle->chain, &karg.xqry);
1384+ if (ret)
1385+ return ret;
1386+ ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
1387+ if (ret)
1388+ return ret;
14281389 break;
14291390
14301391 default:
14311392 return -ENOIOCTLCMD;
14321393 }
14331394
1434− old_fs = get_fs();
1435− set_fs(KERNEL_DS);
1436− ret = video_ioctl2(file, cmd, (unsigned long)&karg);
1437− set_fs(old_fs);
1438−
1439− if (ret < 0)
1440− return ret;
1441−
1442− switch (cmd) {
1443− case UVCIOC_CTRL_MAP:
1444− ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
1445− break;
1446−
1447− case UVCIOC_CTRL_QUERY:
1448− ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
1449− break;
1450− }
1451−
14521395 return ret;
14531396 }
14541397 #endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t