v4l2-compat-ioctl32.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464
  1. /*
  2. * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
  3. * Separated from fs stuff by Arnd Bergmann <arnd@arndb.de>
  4. *
  5. * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
  6. * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
  7. * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs
  8. * Copyright (C) 2003 Pavel Machek (pavel@ucw.cz)
  9. * Copyright (C) 2005 Philippe De Muyter (phdm@macqel.be)
  10. * Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
  11. *
  12. * These routines maintain argument size conversion between 32bit and 64bit
  13. * ioctls.
  14. */
  15. #include <linux/compat.h>
  16. #include <linux/module.h>
  17. #include <linux/videodev2.h>
  18. #include <linux/v4l2-subdev.h>
  19. #include <media/v4l2-dev.h>
  20. #include <media/v4l2-fh.h>
  21. #include <media/v4l2-ctrls.h>
  22. #include <media/v4l2-ioctl.h>
  23. /**
  24. * assign_in_user() - Copy from one __user var to another one
  25. *
  26. * @to: __user var where data will be stored
  27. * @from: __user var where data will be retrieved.
  28. *
  29. * As this code very often needs to allocate userspace memory, it is easier
  30. * to have a macro that will do both get_user() and put_user() at once.
  31. *
  32. * This function complements the macros defined at asm-generic/uaccess.h.
  33. * It uses the same argument order as copy_in_user()
  34. */
  35. #define assign_in_user(to, from) \
  36. ({ \
  37. typeof(*from) __assign_tmp; \
  38. \
  39. get_user(__assign_tmp, from) || put_user(__assign_tmp, to); \
  40. })
  41. /**
  42. * get_user_cast() - Stores at a kernelspace local var the contents from a
  43. * pointer with userspace data that is not tagged with __user.
  44. *
  45. * @__x: var where data will be stored
  46. * @__ptr: var where data will be retrieved.
  47. *
  48. * Sometimes we need to declare a pointer without __user because it
  49. * comes from a pointer struct field that will be retrieved from userspace
  50. * by the 64-bit native ioctl handler. This function ensures that the
  51. * @__ptr will be cast to __user before calling get_user() in order to
  52. * avoid warnings with static code analyzers like smatch.
  53. */
  54. #define get_user_cast(__x, __ptr) \
  55. ({ \
  56. get_user(__x, (typeof(*__ptr) __user *)(__ptr)); \
  57. })
  58. /**
  59. * put_user_force() - Stores the contents of a kernelspace local var
  60. * into a userspace pointer, removing any __user cast.
  61. *
  62. * @__x: var where data will be stored
  63. * @__ptr: var where data will be retrieved.
  64. *
  65. * Sometimes we need to remove the __user attribute from some data,
  66. * by passing the __force macro. This function ensures that the
  67. * @__ptr will be cast with __force before calling put_user(), in order to
  68. * avoid warnings with static code analyzers like smatch.
  69. */
  70. #define put_user_force(__x, __ptr) \
  71. ({ \
  72. put_user((typeof(*__x) __force *)(__x), __ptr); \
  73. })
  74. /**
  75. * assign_in_user_cast() - Copy from one __user var to another one
  76. *
  77. * @to: __user var where data will be stored
  78. * @from: var where data will be retrieved that needs to be cast to __user.
  79. *
  80. * As this code very often needs to allocate userspace memory, it is easier
  81. * to have a macro that will do both get_user_cast() and put_user() at once.
  82. *
  83. * This function should be used instead of assign_in_user() when the @from
  84. * variable was not declared as __user. See get_user_cast() for more details.
  85. *
  86. * This function complements the macros defined at asm-generic/uaccess.h.
  87. * It uses the same argument order as copy_in_user()
  88. */
  89. #define assign_in_user_cast(to, from) \
  90. ({ \
  91. typeof(*from) __assign_tmp; \
  92. \
  93. get_user_cast(__assign_tmp, from) || put_user(__assign_tmp, to);\
  94. })
  95. /**
  96. * native_ioctl - Ancillary function that calls the native 64 bits ioctl
  97. * handler.
  98. *
  99. * @file: pointer to &struct file with the file handler
  100. * @cmd: ioctl to be called
  101. * @arg: arguments passed from/to the ioctl handler
  102. *
  103. * This function calls the native ioctl handler at v4l2-dev, e. g. v4l2_ioctl()
  104. */
  105. static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  106. {
  107. long ret = -ENOIOCTLCMD;
  108. if (file->f_op->unlocked_ioctl)
  109. ret = file->f_op->unlocked_ioctl(file, cmd, arg);
  110. return ret;
  111. }
  112. /*
  113. * Per-ioctl data copy handlers.
  114. *
  115. * Those come in pairs, with a get_v4l2_foo() and a put_v4l2_foo() routine,
  116. * where "v4l2_foo" is the name of the V4L2 struct.
  117. *
  118. * They basically get two __user pointers, one with a 32-bits struct that
  119. * came from the userspace call and a 64-bits struct, also allocated as
  120. * userspace, but filled internally by do_video_ioctl().
  121. *
  122. * For ioctls that have pointers inside it, the functions will also
  123. * receive an ancillary buffer with extra space, used to pass extra
  124. * data to the routine.
  125. */
  126. struct v4l2_clip32 {
  127. struct v4l2_rect c;
  128. compat_caddr_t next;
  129. };
  130. struct v4l2_window32 {
  131. struct v4l2_rect w;
  132. __u32 field; /* enum v4l2_field */
  133. __u32 chromakey;
  134. compat_caddr_t clips; /* actually struct v4l2_clip32 * */
  135. __u32 clipcount;
  136. compat_caddr_t bitmap;
  137. __u8 global_alpha;
  138. };
  139. static int get_v4l2_window32(struct v4l2_window __user *p64,
  140. struct v4l2_window32 __user *p32,
  141. void __user *aux_buf, u32 aux_space)
  142. {
  143. struct v4l2_clip32 __user *uclips;
  144. struct v4l2_clip __user *kclips;
  145. compat_caddr_t p;
  146. u32 clipcount;
  147. if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
  148. copy_in_user(&p64->w, &p32->w, sizeof(p32->w)) ||
  149. assign_in_user(&p64->field, &p32->field) ||
  150. assign_in_user(&p64->chromakey, &p32->chromakey) ||
  151. assign_in_user(&p64->global_alpha, &p32->global_alpha) ||
  152. get_user(clipcount, &p32->clipcount) ||
  153. put_user(clipcount, &p64->clipcount))
  154. return -EFAULT;
  155. if (clipcount > 2048)
  156. return -EINVAL;
  157. if (!clipcount)
  158. return put_user(NULL, &p64->clips);
  159. if (get_user(p, &p32->clips))
  160. return -EFAULT;
  161. uclips = compat_ptr(p);
  162. if (aux_space < clipcount * sizeof(*kclips))
  163. return -EFAULT;
  164. kclips = aux_buf;
  165. if (put_user(kclips, &p64->clips))
  166. return -EFAULT;
  167. while (clipcount--) {
  168. if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
  169. return -EFAULT;
  170. if (put_user(clipcount ? kclips + 1 : NULL, &kclips->next))
  171. return -EFAULT;
  172. uclips++;
  173. kclips++;
  174. }
  175. return 0;
  176. }
  177. static int put_v4l2_window32(struct v4l2_window __user *p64,
  178. struct v4l2_window32 __user *p32)
  179. {
  180. struct v4l2_clip __user *kclips;
  181. struct v4l2_clip32 __user *uclips;
  182. compat_caddr_t p;
  183. u32 clipcount;
  184. if (copy_in_user(&p32->w, &p64->w, sizeof(p64->w)) ||
  185. assign_in_user(&p32->field, &p64->field) ||
  186. assign_in_user(&p32->chromakey, &p64->chromakey) ||
  187. assign_in_user(&p32->global_alpha, &p64->global_alpha) ||
  188. get_user(clipcount, &p64->clipcount) ||
  189. put_user(clipcount, &p32->clipcount))
  190. return -EFAULT;
  191. if (!clipcount)
  192. return 0;
  193. if (get_user(kclips, &p64->clips))
  194. return -EFAULT;
  195. if (get_user(p, &p32->clips))
  196. return -EFAULT;
  197. uclips = compat_ptr(p);
  198. while (clipcount--) {
  199. if (copy_in_user(&uclips->c, &kclips->c, sizeof(uclips->c)))
  200. return -EFAULT;
  201. uclips++;
  202. kclips++;
  203. }
  204. return 0;
  205. }
  206. struct v4l2_format32 {
  207. __u32 type; /* enum v4l2_buf_type */
  208. union {
  209. struct v4l2_pix_format pix;
  210. struct v4l2_pix_format_mplane pix_mp;
  211. struct v4l2_window32 win;
  212. struct v4l2_vbi_format vbi;
  213. struct v4l2_sliced_vbi_format sliced;
  214. struct v4l2_sdr_format sdr;
  215. struct v4l2_meta_format meta;
  216. __u8 raw_data[200]; /* user-defined */
  217. } fmt;
  218. };
  219. /**
  220. * struct v4l2_create_buffers32 - VIDIOC_CREATE_BUFS32 argument
  221. * @index: on return, index of the first created buffer
  222. * @count: entry: number of requested buffers,
  223. * return: number of created buffers
  224. * @memory: buffer memory type
  225. * @format: frame format, for which buffers are requested
  226. * @reserved: future extensions
  227. */
  228. struct v4l2_create_buffers32 {
  229. __u32 index;
  230. __u32 count;
  231. __u32 memory; /* enum v4l2_memory */
  232. struct v4l2_format32 format;
  233. __u32 reserved[8];
  234. };
  235. static int __bufsize_v4l2_format(struct v4l2_format32 __user *p32, u32 *size)
  236. {
  237. u32 type;
  238. if (get_user(type, &p32->type))
  239. return -EFAULT;
  240. switch (type) {
  241. case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  242. case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
  243. u32 clipcount;
  244. if (get_user(clipcount, &p32->fmt.win.clipcount))
  245. return -EFAULT;
  246. if (clipcount > 2048)
  247. return -EINVAL;
  248. *size = clipcount * sizeof(struct v4l2_clip);
  249. return 0;
  250. }
  251. default:
  252. *size = 0;
  253. return 0;
  254. }
  255. }
  256. static int bufsize_v4l2_format(struct v4l2_format32 __user *p32, u32 *size)
  257. {
  258. if (!access_ok(VERIFY_READ, p32, sizeof(*p32)))
  259. return -EFAULT;
  260. return __bufsize_v4l2_format(p32, size);
  261. }
  262. static int __get_v4l2_format32(struct v4l2_format __user *p64,
  263. struct v4l2_format32 __user *p32,
  264. void __user *aux_buf, u32 aux_space)
  265. {
  266. u32 type;
  267. if (get_user(type, &p32->type) || put_user(type, &p64->type))
  268. return -EFAULT;
  269. switch (type) {
  270. case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  271. case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  272. return copy_in_user(&p64->fmt.pix, &p32->fmt.pix,
  273. sizeof(p64->fmt.pix)) ? -EFAULT : 0;
  274. case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
  275. case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
  276. return copy_in_user(&p64->fmt.pix_mp, &p32->fmt.pix_mp,
  277. sizeof(p64->fmt.pix_mp)) ? -EFAULT : 0;
  278. case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  279. case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
  280. return get_v4l2_window32(&p64->fmt.win, &p32->fmt.win,
  281. aux_buf, aux_space);
  282. case V4L2_BUF_TYPE_VBI_CAPTURE:
  283. case V4L2_BUF_TYPE_VBI_OUTPUT:
  284. return copy_in_user(&p64->fmt.vbi, &p32->fmt.vbi,
  285. sizeof(p64->fmt.vbi)) ? -EFAULT : 0;
  286. case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  287. case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  288. return copy_in_user(&p64->fmt.sliced, &p32->fmt.sliced,
  289. sizeof(p64->fmt.sliced)) ? -EFAULT : 0;
  290. case V4L2_BUF_TYPE_SDR_CAPTURE:
  291. case V4L2_BUF_TYPE_SDR_OUTPUT:
  292. return copy_in_user(&p64->fmt.sdr, &p32->fmt.sdr,
  293. sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
  294. case V4L2_BUF_TYPE_META_CAPTURE:
  295. return copy_in_user(&p64->fmt.meta, &p32->fmt.meta,
  296. sizeof(p64->fmt.meta)) ? -EFAULT : 0;
  297. default:
  298. return -EINVAL;
  299. }
  300. }
  301. static int get_v4l2_format32(struct v4l2_format __user *p64,
  302. struct v4l2_format32 __user *p32,
  303. void __user *aux_buf, u32 aux_space)
  304. {
  305. if (!access_ok(VERIFY_READ, p32, sizeof(*p32)))
  306. return -EFAULT;
  307. return __get_v4l2_format32(p64, p32, aux_buf, aux_space);
  308. }
  309. static int bufsize_v4l2_create(struct v4l2_create_buffers32 __user *p32,
  310. u32 *size)
  311. {
  312. if (!access_ok(VERIFY_READ, p32, sizeof(*p32)))
  313. return -EFAULT;
  314. return __bufsize_v4l2_format(&p32->format, size);
  315. }
  316. static int get_v4l2_create32(struct v4l2_create_buffers __user *p64,
  317. struct v4l2_create_buffers32 __user *p32,
  318. void __user *aux_buf, u32 aux_space)
  319. {
  320. if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
  321. copy_in_user(p64, p32,
  322. offsetof(struct v4l2_create_buffers32, format)))
  323. return -EFAULT;
  324. return __get_v4l2_format32(&p64->format, &p32->format,
  325. aux_buf, aux_space);
  326. }
  327. static int __put_v4l2_format32(struct v4l2_format __user *p64,
  328. struct v4l2_format32 __user *p32)
  329. {
  330. u32 type;
  331. if (get_user(type, &p64->type))
  332. return -EFAULT;
  333. switch (type) {
  334. case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  335. case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  336. return copy_in_user(&p32->fmt.pix, &p64->fmt.pix,
  337. sizeof(p64->fmt.pix)) ? -EFAULT : 0;
  338. case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
  339. case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
  340. return copy_in_user(&p32->fmt.pix_mp, &p64->fmt.pix_mp,
  341. sizeof(p64->fmt.pix_mp)) ? -EFAULT : 0;
  342. case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  343. case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
  344. return put_v4l2_window32(&p64->fmt.win, &p32->fmt.win);
  345. case V4L2_BUF_TYPE_VBI_CAPTURE:
  346. case V4L2_BUF_TYPE_VBI_OUTPUT:
  347. return copy_in_user(&p32->fmt.vbi, &p64->fmt.vbi,
  348. sizeof(p64->fmt.vbi)) ? -EFAULT : 0;
  349. case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  350. case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  351. return copy_in_user(&p32->fmt.sliced, &p64->fmt.sliced,
  352. sizeof(p64->fmt.sliced)) ? -EFAULT : 0;
  353. case V4L2_BUF_TYPE_SDR_CAPTURE:
  354. case V4L2_BUF_TYPE_SDR_OUTPUT:
  355. return copy_in_user(&p32->fmt.sdr, &p64->fmt.sdr,
  356. sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
  357. case V4L2_BUF_TYPE_META_CAPTURE:
  358. return copy_in_user(&p32->fmt.meta, &p64->fmt.meta,
  359. sizeof(p64->fmt.meta)) ? -EFAULT : 0;
  360. default:
  361. return -EINVAL;
  362. }
  363. }
  364. static int put_v4l2_format32(struct v4l2_format __user *p64,
  365. struct v4l2_format32 __user *p32)
  366. {
  367. if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)))
  368. return -EFAULT;
  369. return __put_v4l2_format32(p64, p32);
  370. }
  371. static int put_v4l2_create32(struct v4l2_create_buffers __user *p64,
  372. struct v4l2_create_buffers32 __user *p32)
  373. {
  374. if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
  375. copy_in_user(p32, p64,
  376. offsetof(struct v4l2_create_buffers32, format)) ||
  377. copy_in_user(p32->reserved, p64->reserved, sizeof(p64->reserved)))
  378. return -EFAULT;
  379. return __put_v4l2_format32(&p64->format, &p32->format);
  380. }
  381. struct v4l2_standard32 {
  382. __u32 index;
  383. compat_u64 id;
  384. __u8 name[24];
  385. struct v4l2_fract frameperiod; /* Frames, not fields */
  386. __u32 framelines;
  387. __u32 reserved[4];
  388. };
  389. static int get_v4l2_standard32(struct v4l2_standard __user *p64,
  390. struct v4l2_standard32 __user *p32)
  391. {
  392. /* other fields are not set by the user, nor used by the driver */
  393. if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
  394. assign_in_user(&p64->index, &p32->index))
  395. return -EFAULT;
  396. return 0;
  397. }
  398. static int put_v4l2_standard32(struct v4l2_standard __user *p64,
  399. struct v4l2_standard32 __user *p32)
  400. {
  401. if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
  402. assign_in_user(&p32->index, &p64->index) ||
  403. assign_in_user(&p32->id, &p64->id) ||
  404. copy_in_user(p32->name, p64->name, sizeof(p32->name)) ||
  405. copy_in_user(&p32->frameperiod, &p64->frameperiod,
  406. sizeof(p32->frameperiod)) ||
  407. assign_in_user(&p32->framelines, &p64->framelines) ||
  408. copy_in_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
  409. return -EFAULT;
  410. return 0;
  411. }
  412. struct v4l2_plane32 {
  413. __u32 bytesused;
  414. __u32 length;
  415. union {
  416. __u32 mem_offset;
  417. compat_long_t userptr;
  418. __s32 fd;
  419. } m;
  420. __u32 data_offset;
  421. __u32 reserved[11];
  422. };
  423. struct v4l2_buffer32 {
  424. __u32 index;
  425. __u32 type; /* enum v4l2_buf_type */
  426. __u32 bytesused;
  427. __u32 flags;
  428. __u32 field; /* enum v4l2_field */
  429. struct compat_timeval timestamp;
  430. struct v4l2_timecode timecode;
  431. __u32 sequence;
  432. /* memory location */
  433. __u32 memory; /* enum v4l2_memory */
  434. union {
  435. __u32 offset;
  436. compat_long_t userptr;
  437. compat_caddr_t planes;
  438. __s32 fd;
  439. } m;
  440. __u32 length;
  441. __u32 reserved2;
  442. __u32 reserved;
  443. };
  444. static int get_v4l2_plane32(struct v4l2_plane __user *p64,
  445. struct v4l2_plane32 __user *p32,
  446. enum v4l2_memory memory)
  447. {
  448. compat_ulong_t p;
  449. if (copy_in_user(p64, p32, 2 * sizeof(__u32)) ||
  450. copy_in_user(&p64->data_offset, &p32->data_offset,
  451. sizeof(p64->data_offset)))
  452. return -EFAULT;
  453. switch (memory) {
  454. case V4L2_MEMORY_MMAP:
  455. case V4L2_MEMORY_OVERLAY:
  456. if (copy_in_user(&p64->m.mem_offset, &p32->m.mem_offset,
  457. sizeof(p32->m.mem_offset)))
  458. return -EFAULT;
  459. break;
  460. case V4L2_MEMORY_USERPTR:
  461. if (get_user(p, &p32->m.userptr) ||
  462. put_user((unsigned long)compat_ptr(p), &p64->m.userptr))
  463. return -EFAULT;
  464. break;
  465. case V4L2_MEMORY_DMABUF:
  466. if (copy_in_user(&p64->m.fd, &p32->m.fd, sizeof(p32->m.fd)))
  467. return -EFAULT;
  468. break;
  469. }
  470. return 0;
  471. }
  472. static int put_v4l2_plane32(struct v4l2_plane __user *p64,
  473. struct v4l2_plane32 __user *p32,
  474. enum v4l2_memory memory)
  475. {
  476. unsigned long p;
  477. if (copy_in_user(p32, p64, 2 * sizeof(__u32)) ||
  478. copy_in_user(&p32->data_offset, &p64->data_offset,
  479. sizeof(p64->data_offset)))
  480. return -EFAULT;
  481. switch (memory) {
  482. case V4L2_MEMORY_MMAP:
  483. case V4L2_MEMORY_OVERLAY:
  484. if (copy_in_user(&p32->m.mem_offset, &p64->m.mem_offset,
  485. sizeof(p64->m.mem_offset)))
  486. return -EFAULT;
  487. break;
  488. case V4L2_MEMORY_USERPTR:
  489. if (get_user(p, &p64->m.userptr) ||
  490. put_user((compat_ulong_t)ptr_to_compat((void __user *)p),
  491. &p32->m.userptr))
  492. return -EFAULT;
  493. break;
  494. case V4L2_MEMORY_DMABUF:
  495. if (copy_in_user(&p32->m.fd, &p64->m.fd, sizeof(p64->m.fd)))
  496. return -EFAULT;
  497. break;
  498. }
  499. return 0;
  500. }
  501. static int bufsize_v4l2_buffer(struct v4l2_buffer32 __user *p32, u32 *size)
  502. {
  503. u32 type;
  504. u32 length;
  505. if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
  506. get_user(type, &p32->type) ||
  507. get_user(length, &p32->length))
  508. return -EFAULT;
  509. if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
  510. if (length > VIDEO_MAX_PLANES)
  511. return -EINVAL;
  512. /*
  513. * We don't really care if userspace decides to kill itself
  514. * by passing a very big length value
  515. */
  516. *size = length * sizeof(struct v4l2_plane);
  517. } else {
  518. *size = 0;
  519. }
  520. return 0;
  521. }
  522. static int get_v4l2_buffer32(struct v4l2_buffer __user *p64,
  523. struct v4l2_buffer32 __user *p32,
  524. void __user *aux_buf, u32 aux_space)
  525. {
  526. u32 type;
  527. u32 length;
  528. enum v4l2_memory memory;
  529. struct v4l2_plane32 __user *uplane32;
  530. struct v4l2_plane __user *uplane;
  531. compat_caddr_t p;
  532. int ret;
  533. if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
  534. assign_in_user(&p64->index, &p32->index) ||
  535. get_user(type, &p32->type) ||
  536. put_user(type, &p64->type) ||
  537. assign_in_user(&p64->flags, &p32->flags) ||
  538. get_user(memory, &p32->memory) ||
  539. put_user(memory, &p64->memory) ||
  540. get_user(length, &p32->length) ||
  541. put_user(length, &p64->length))
  542. return -EFAULT;
  543. if (V4L2_TYPE_IS_OUTPUT(type))
  544. if (assign_in_user(&p64->bytesused, &p32->bytesused) ||
  545. assign_in_user(&p64->field, &p32->field) ||
  546. assign_in_user(&p64->timestamp.tv_sec,
  547. &p32->timestamp.tv_sec) ||
  548. assign_in_user(&p64->timestamp.tv_usec,
  549. &p32->timestamp.tv_usec))
  550. return -EFAULT;
  551. if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
  552. u32 num_planes = length;
  553. if (num_planes == 0) {
  554. /*
  555. * num_planes == 0 is legal, e.g. when userspace doesn't
  556. * need planes array on DQBUF
  557. */
  558. return put_user(NULL, &p64->m.planes);
  559. }
  560. if (num_planes > VIDEO_MAX_PLANES)
  561. return -EINVAL;
  562. if (get_user(p, &p32->m.planes))
  563. return -EFAULT;
  564. uplane32 = compat_ptr(p);
  565. if (!access_ok(VERIFY_READ, uplane32,
  566. num_planes * sizeof(*uplane32)))
  567. return -EFAULT;
  568. /*
  569. * We don't really care if userspace decides to kill itself
  570. * by passing a very big num_planes value
  571. */
  572. if (aux_space < num_planes * sizeof(*uplane))
  573. return -EFAULT;
  574. uplane = aux_buf;
  575. if (put_user_force(uplane, &p64->m.planes))
  576. return -EFAULT;
  577. while (num_planes--) {
  578. ret = get_v4l2_plane32(uplane, uplane32, memory);
  579. if (ret)
  580. return ret;
  581. uplane++;
  582. uplane32++;
  583. }
  584. } else {
  585. switch (memory) {
  586. case V4L2_MEMORY_MMAP:
  587. case V4L2_MEMORY_OVERLAY:
  588. if (assign_in_user(&p64->m.offset, &p32->m.offset))
  589. return -EFAULT;
  590. break;
  591. case V4L2_MEMORY_USERPTR: {
  592. compat_ulong_t userptr;
  593. if (get_user(userptr, &p32->m.userptr) ||
  594. put_user((unsigned long)compat_ptr(userptr),
  595. &p64->m.userptr))
  596. return -EFAULT;
  597. break;
  598. }
  599. case V4L2_MEMORY_DMABUF:
  600. if (assign_in_user(&p64->m.fd, &p32->m.fd))
  601. return -EFAULT;
  602. break;
  603. }
  604. }
  605. return 0;
  606. }
  607. static int put_v4l2_buffer32(struct v4l2_buffer __user *p64,
  608. struct v4l2_buffer32 __user *p32)
  609. {
  610. u32 type;
  611. u32 length;
  612. enum v4l2_memory memory;
  613. struct v4l2_plane32 __user *uplane32;
  614. struct v4l2_plane *uplane;
  615. compat_caddr_t p;
  616. int ret;
  617. if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
  618. assign_in_user(&p32->index, &p64->index) ||
  619. get_user(type, &p64->type) ||
  620. put_user(type, &p32->type) ||
  621. assign_in_user(&p32->flags, &p64->flags) ||
  622. get_user(memory, &p64->memory) ||
  623. put_user(memory, &p32->memory))
  624. return -EFAULT;
  625. if (assign_in_user(&p32->bytesused, &p64->bytesused) ||
  626. assign_in_user(&p32->field, &p64->field) ||
  627. assign_in_user(&p32->timestamp.tv_sec, &p64->timestamp.tv_sec) ||
  628. assign_in_user(&p32->timestamp.tv_usec, &p64->timestamp.tv_usec) ||
  629. copy_in_user(&p32->timecode, &p64->timecode, sizeof(p64->timecode)) ||
  630. assign_in_user(&p32->sequence, &p64->sequence) ||
  631. assign_in_user(&p32->reserved2, &p64->reserved2) ||
  632. assign_in_user(&p32->reserved, &p64->reserved) ||
  633. get_user(length, &p64->length) ||
  634. put_user(length, &p32->length))
  635. return -EFAULT;
  636. if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
  637. u32 num_planes = length;
  638. if (num_planes == 0)
  639. return 0;
  640. /* We need to define uplane without __user, even though
  641. * it does point to data in userspace here. The reason is
  642. * that v4l2-ioctl.c copies it from userspace to kernelspace,
  643. * so its definition in videodev2.h doesn't have a
  644. * __user markup. Defining uplane with __user causes
  645. * smatch warnings, so instead declare it without __user
  646. * and cast it as a userspace pointer to put_v4l2_plane32().
  647. */
  648. if (get_user(uplane, &p64->m.planes))
  649. return -EFAULT;
  650. if (get_user(p, &p32->m.planes))
  651. return -EFAULT;
  652. uplane32 = compat_ptr(p);
  653. while (num_planes--) {
  654. ret = put_v4l2_plane32((void __user *)uplane,
  655. uplane32, memory);
  656. if (ret)
  657. return ret;
  658. ++uplane;
  659. ++uplane32;
  660. }
  661. } else {
  662. switch (memory) {
  663. case V4L2_MEMORY_MMAP:
  664. case V4L2_MEMORY_OVERLAY:
  665. if (assign_in_user(&p32->m.offset, &p64->m.offset))
  666. return -EFAULT;
  667. break;
  668. case V4L2_MEMORY_USERPTR:
  669. if (assign_in_user(&p32->m.userptr, &p64->m.userptr))
  670. return -EFAULT;
  671. break;
  672. case V4L2_MEMORY_DMABUF:
  673. if (assign_in_user(&p32->m.fd, &p64->m.fd))
  674. return -EFAULT;
  675. break;
  676. }
  677. }
  678. return 0;
  679. }
  680. struct v4l2_framebuffer32 {
  681. __u32 capability;
  682. __u32 flags;
  683. compat_caddr_t base;
  684. struct {
  685. __u32 width;
  686. __u32 height;
  687. __u32 pixelformat;
  688. __u32 field;
  689. __u32 bytesperline;
  690. __u32 sizeimage;
  691. __u32 colorspace;
  692. __u32 priv;
  693. } fmt;
  694. };
  695. static int get_v4l2_framebuffer32(struct v4l2_framebuffer __user *p64,
  696. struct v4l2_framebuffer32 __user *p32)
  697. {
  698. compat_caddr_t tmp;
  699. if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
  700. get_user(tmp, &p32->base) ||
  701. put_user_force(compat_ptr(tmp), &p64->base) ||
  702. assign_in_user(&p64->capability, &p32->capability) ||
  703. assign_in_user(&p64->flags, &p32->flags) ||
  704. copy_in_user(&p64->fmt, &p32->fmt, sizeof(p64->fmt)))
  705. return -EFAULT;
  706. return 0;
  707. }
  708. static int put_v4l2_framebuffer32(struct v4l2_framebuffer __user *p64,
  709. struct v4l2_framebuffer32 __user *p32)
  710. {
  711. void *base;
  712. if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
  713. get_user(base, &p64->base) ||
  714. put_user(ptr_to_compat((void __user *)base), &p32->base) ||
  715. assign_in_user(&p32->capability, &p64->capability) ||
  716. assign_in_user(&p32->flags, &p64->flags) ||
  717. copy_in_user(&p32->fmt, &p64->fmt, sizeof(p64->fmt)))
  718. return -EFAULT;
  719. return 0;
  720. }
  721. struct v4l2_input32 {
  722. __u32 index; /* Which input */
  723. __u8 name[32]; /* Label */
  724. __u32 type; /* Type of input */
  725. __u32 audioset; /* Associated audios (bitfield) */
  726. __u32 tuner; /* Associated tuner */
  727. compat_u64 std;
  728. __u32 status;
  729. __u32 capabilities;
  730. __u32 reserved[3];
  731. };
  732. /*
  733. * The 64-bit v4l2_input struct has extra padding at the end of the struct.
  734. * Otherwise it is identical to the 32-bit version.
  735. */
  736. static inline int get_v4l2_input32(struct v4l2_input __user *p64,
  737. struct v4l2_input32 __user *p32)
  738. {
  739. if (copy_in_user(p64, p32, sizeof(*p32)))
  740. return -EFAULT;
  741. return 0;
  742. }
  743. static inline int put_v4l2_input32(struct v4l2_input __user *p64,
  744. struct v4l2_input32 __user *p32)
  745. {
  746. if (copy_in_user(p32, p64, sizeof(*p32)))
  747. return -EFAULT;
  748. return 0;
  749. }
  750. struct v4l2_ext_controls32 {
  751. __u32 which;
  752. __u32 count;
  753. __u32 error_idx;
  754. __u32 reserved[2];
  755. compat_caddr_t controls; /* actually struct v4l2_ext_control32 * */
  756. };
  757. struct v4l2_ext_control32 {
  758. __u32 id;
  759. __u32 size;
  760. __u32 reserved2[1];
  761. union {
  762. __s32 value;
  763. __s64 value64;
  764. compat_caddr_t string; /* actually char * */
  765. };
  766. } __attribute__ ((packed));
  767. /* Return true if this control is a pointer type. */
  768. static inline bool ctrl_is_pointer(struct file *file, u32 id)
  769. {
  770. struct video_device *vdev = video_devdata(file);
  771. struct v4l2_fh *fh = NULL;
  772. struct v4l2_ctrl_handler *hdl = NULL;
  773. struct v4l2_query_ext_ctrl qec = { id };
  774. const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
  775. if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags))
  776. fh = file->private_data;
  777. if (fh && fh->ctrl_handler)
  778. hdl = fh->ctrl_handler;
  779. else if (vdev->ctrl_handler)
  780. hdl = vdev->ctrl_handler;
  781. if (hdl) {
  782. struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, id);
  783. return ctrl && ctrl->is_ptr;
  784. }
  785. if (!ops || !ops->vidioc_query_ext_ctrl)
  786. return false;
  787. return !ops->vidioc_query_ext_ctrl(file, fh, &qec) &&
  788. (qec.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD);
  789. }
  790. static int bufsize_v4l2_ext_controls(struct v4l2_ext_controls32 __user *p32,
  791. u32 *size)
  792. {
  793. u32 count;
  794. if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
  795. get_user(count, &p32->count))
  796. return -EFAULT;
  797. if (count > V4L2_CID_MAX_CTRLS)
  798. return -EINVAL;
  799. *size = count * sizeof(struct v4l2_ext_control);
  800. return 0;
  801. }
  802. static int get_v4l2_ext_controls32(struct file *file,
  803. struct v4l2_ext_controls __user *p64,
  804. struct v4l2_ext_controls32 __user *p32,
  805. void __user *aux_buf, u32 aux_space)
  806. {
  807. struct v4l2_ext_control32 __user *ucontrols;
  808. struct v4l2_ext_control __user *kcontrols;
  809. u32 count;
  810. u32 n;
  811. compat_caddr_t p;
  812. if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
  813. assign_in_user(&p64->which, &p32->which) ||
  814. get_user(count, &p32->count) ||
  815. put_user(count, &p64->count) ||
  816. assign_in_user(&p64->error_idx, &p32->error_idx) ||
  817. copy_in_user(p64->reserved, p32->reserved, sizeof(p64->reserved)))
  818. return -EFAULT;
  819. if (count == 0)
  820. return put_user(NULL, &p64->controls);
  821. if (count > V4L2_CID_MAX_CTRLS)
  822. return -EINVAL;
  823. if (get_user(p, &p32->controls))
  824. return -EFAULT;
  825. ucontrols = compat_ptr(p);
  826. if (!access_ok(VERIFY_READ, ucontrols, count * sizeof(*ucontrols)))
  827. return -EFAULT;
  828. if (aux_space < count * sizeof(*kcontrols))
  829. return -EFAULT;
  830. kcontrols = aux_buf;
  831. if (put_user_force(kcontrols, &p64->controls))
  832. return -EFAULT;
  833. for (n = 0; n < count; n++) {
  834. u32 id;
  835. if (copy_in_user(kcontrols, ucontrols, sizeof(*ucontrols)))
  836. return -EFAULT;
  837. if (get_user(id, &kcontrols->id))
  838. return -EFAULT;
  839. if (ctrl_is_pointer(file, id)) {
  840. void __user *s;
  841. if (get_user(p, &ucontrols->string))
  842. return -EFAULT;
  843. s = compat_ptr(p);
  844. if (put_user(s, &kcontrols->string))
  845. return -EFAULT;
  846. }
  847. ucontrols++;
  848. kcontrols++;
  849. }
  850. return 0;
  851. }
  852. static int put_v4l2_ext_controls32(struct file *file,
  853. struct v4l2_ext_controls __user *p64,
  854. struct v4l2_ext_controls32 __user *p32)
  855. {
  856. struct v4l2_ext_control32 __user *ucontrols;
  857. struct v4l2_ext_control *kcontrols;
  858. u32 count;
  859. u32 n;
  860. compat_caddr_t p;
  861. /*
  862. * We need to define kcontrols without __user, even though it does
  863. * point to data in userspace here. The reason is that v4l2-ioctl.c
  864. * copies it from userspace to kernelspace, so its definition in
  865. * videodev2.h doesn't have a __user markup. Defining kcontrols
  866. * with __user causes smatch warnings, so instead declare it
  867. * without __user and cast it as a userspace pointer where needed.
  868. */
  869. if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
  870. assign_in_user(&p32->which, &p64->which) ||
  871. get_user(count, &p64->count) ||
  872. put_user(count, &p32->count) ||
  873. assign_in_user(&p32->error_idx, &p64->error_idx) ||
  874. copy_in_user(p32->reserved, p64->reserved, sizeof(p32->reserved)) ||
  875. get_user(kcontrols, &p64->controls))
  876. return -EFAULT;
  877. if (!count || count > (U32_MAX/sizeof(*ucontrols)))
  878. return 0;
  879. if (get_user(p, &p32->controls))
  880. return -EFAULT;
  881. ucontrols = compat_ptr(p);
  882. if (!access_ok(VERIFY_WRITE, ucontrols, count * sizeof(*ucontrols)))
  883. return -EFAULT;
  884. for (n = 0; n < count; n++) {
  885. unsigned int size = sizeof(*ucontrols);
  886. u32 id;
  887. if (get_user_cast(id, &kcontrols->id) ||
  888. put_user(id, &ucontrols->id) ||
  889. assign_in_user_cast(&ucontrols->size, &kcontrols->size) ||
  890. copy_in_user(&ucontrols->reserved2,
  891. (void __user *)&kcontrols->reserved2,
  892. sizeof(ucontrols->reserved2)))
  893. return -EFAULT;
  894. /*
  895. * Do not modify the pointer when copying a pointer control.
  896. * The contents of the pointer was changed, not the pointer
  897. * itself.
  898. */
  899. if (ctrl_is_pointer(file, id))
  900. size -= sizeof(ucontrols->value64);
  901. if (copy_in_user(ucontrols,
  902. (void __user *)kcontrols, size))
  903. return -EFAULT;
  904. ucontrols++;
  905. kcontrols++;
  906. }
  907. return 0;
  908. }
  909. struct v4l2_event32 {
  910. __u32 type;
  911. union {
  912. compat_s64 value64;
  913. __u8 data[64];
  914. } u;
  915. __u32 pending;
  916. __u32 sequence;
  917. struct compat_timespec timestamp;
  918. __u32 id;
  919. __u32 reserved[8];
  920. };
  921. static int put_v4l2_event32(struct v4l2_event __user *p64,
  922. struct v4l2_event32 __user *p32)
  923. {
  924. if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
  925. assign_in_user(&p32->type, &p64->type) ||
  926. copy_in_user(&p32->u, &p64->u, sizeof(p64->u)) ||
  927. assign_in_user(&p32->pending, &p64->pending) ||
  928. assign_in_user(&p32->sequence, &p64->sequence) ||
  929. assign_in_user(&p32->timestamp.tv_sec, &p64->timestamp.tv_sec) ||
  930. assign_in_user(&p32->timestamp.tv_nsec, &p64->timestamp.tv_nsec) ||
  931. assign_in_user(&p32->id, &p64->id) ||
  932. copy_in_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
  933. return -EFAULT;
  934. return 0;
  935. }
  936. struct v4l2_edid32 {
  937. __u32 pad;
  938. __u32 start_block;
  939. __u32 blocks;
  940. __u32 reserved[5];
  941. compat_caddr_t edid;
  942. };
  943. static int get_v4l2_edid32(struct v4l2_edid __user *p64,
  944. struct v4l2_edid32 __user *p32)
  945. {
  946. compat_uptr_t tmp;
  947. if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
  948. assign_in_user(&p64->pad, &p32->pad) ||
  949. assign_in_user(&p64->start_block, &p32->start_block) ||
  950. assign_in_user_cast(&p64->blocks, &p32->blocks) ||
  951. get_user(tmp, &p32->edid) ||
  952. put_user_force(compat_ptr(tmp), &p64->edid) ||
  953. copy_in_user(p64->reserved, p32->reserved, sizeof(p64->reserved)))
  954. return -EFAULT;
  955. return 0;
  956. }
  957. static int put_v4l2_edid32(struct v4l2_edid __user *p64,
  958. struct v4l2_edid32 __user *p32)
  959. {
  960. void *edid;
  961. if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
  962. assign_in_user(&p32->pad, &p64->pad) ||
  963. assign_in_user(&p32->start_block, &p64->start_block) ||
  964. assign_in_user(&p32->blocks, &p64->blocks) ||
  965. get_user(edid, &p64->edid) ||
  966. put_user(ptr_to_compat((void __user *)edid), &p32->edid) ||
  967. copy_in_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
  968. return -EFAULT;
  969. return 0;
  970. }
  971. /*
  972. * List of ioctls that require 32-bits/64-bits conversion
  973. *
  974. * The V4L2 ioctls that aren't listed there don't have pointer arguments
  975. * and the struct size is identical for both 32 and 64 bits versions, so
  976. * they don't need translations.
  977. */
  978. #define VIDIOC_G_FMT32 _IOWR('V', 4, struct v4l2_format32)
  979. #define VIDIOC_S_FMT32 _IOWR('V', 5, struct v4l2_format32)
  980. #define VIDIOC_QUERYBUF32 _IOWR('V', 9, struct v4l2_buffer32)
  981. #define VIDIOC_G_FBUF32 _IOR ('V', 10, struct v4l2_framebuffer32)
  982. #define VIDIOC_S_FBUF32 _IOW ('V', 11, struct v4l2_framebuffer32)
  983. #define VIDIOC_QBUF32 _IOWR('V', 15, struct v4l2_buffer32)
  984. #define VIDIOC_DQBUF32 _IOWR('V', 17, struct v4l2_buffer32)
  985. #define VIDIOC_ENUMSTD32 _IOWR('V', 25, struct v4l2_standard32)
  986. #define VIDIOC_ENUMINPUT32 _IOWR('V', 26, struct v4l2_input32)
  987. #define VIDIOC_G_EDID32 _IOWR('V', 40, struct v4l2_edid32)
  988. #define VIDIOC_S_EDID32 _IOWR('V', 41, struct v4l2_edid32)
  989. #define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32)
  990. #define VIDIOC_G_EXT_CTRLS32 _IOWR('V', 71, struct v4l2_ext_controls32)
  991. #define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32)
  992. #define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32)
  993. #define VIDIOC_DQEVENT32 _IOR ('V', 89, struct v4l2_event32)
  994. #define VIDIOC_CREATE_BUFS32 _IOWR('V', 92, struct v4l2_create_buffers32)
  995. #define VIDIOC_PREPARE_BUF32 _IOWR('V', 93, struct v4l2_buffer32)
  996. #define VIDIOC_OVERLAY32 _IOW ('V', 14, s32)
  997. #define VIDIOC_STREAMON32 _IOW ('V', 18, s32)
  998. #define VIDIOC_STREAMOFF32 _IOW ('V', 19, s32)
  999. #define VIDIOC_G_INPUT32 _IOR ('V', 38, s32)
  1000. #define VIDIOC_S_INPUT32 _IOWR('V', 39, s32)
  1001. #define VIDIOC_G_OUTPUT32 _IOR ('V', 46, s32)
  1002. #define VIDIOC_S_OUTPUT32 _IOWR('V', 47, s32)
  1003. /**
  1004. * alloc_userspace() - Allocates a 64-bits userspace pointer compatible
  1005. * for calling the native 64-bits version of an ioctl.
  1006. *
  1007. * @size: size of the structure itself to be allocated.
  1008. * @aux_space: extra size needed to store "extra" data, e.g. space for
  1009. * other __user data that is pointed to fields inside the
  1010. * structure.
  1011. * @new_p64: pointer to a pointer to be filled with the allocated struct.
  1012. *
  1013. * Return:
  1014. *
  1015. * if it can't allocate memory, either -ENOMEM or -EFAULT will be returned.
  1016. * Zero otherwise.
  1017. */
  1018. static int alloc_userspace(unsigned int size, u32 aux_space,
  1019. void __user **new_p64)
  1020. {
  1021. *new_p64 = compat_alloc_user_space(size + aux_space);
  1022. if (!*new_p64)
  1023. return -ENOMEM;
  1024. if (clear_user(*new_p64, size))
  1025. return -EFAULT;
  1026. return 0;
  1027. }
  1028. /**
  1029. * do_video_ioctl() - Ancillary function with handles a compat32 ioctl call
  1030. *
  1031. * @file: pointer to &struct file with the file handler
  1032. * @cmd: ioctl to be called
  1033. * @arg: arguments passed from/to the ioctl handler
  1034. *
  1035. * This function is called when a 32 bits application calls a V4L2 ioctl
  1036. * and the Kernel is compiled with 64 bits.
  1037. *
  1038. * This function is called by v4l2_compat_ioctl32() when the function is
  1039. * not private to some specific driver.
  1040. *
  1041. * It converts a 32-bits struct into a 64 bits one, calls the native 64-bits
  1042. * ioctl handler and fills back the 32-bits struct with the results of the
  1043. * native call.
  1044. */
  1045. static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  1046. {
  1047. void __user *p32 = compat_ptr(arg);
  1048. void __user *new_p64 = NULL;
  1049. void __user *aux_buf;
  1050. u32 aux_space;
  1051. int compatible_arg = 1;
  1052. long err = 0;
  1053. unsigned int ncmd;
  1054. /*
  1055. * 1. When struct size is different, converts the command.
  1056. */
  1057. switch (cmd) {
  1058. case VIDIOC_G_FMT32: ncmd = VIDIOC_G_FMT; break;
  1059. case VIDIOC_S_FMT32: ncmd = VIDIOC_S_FMT; break;
  1060. case VIDIOC_QUERYBUF32: ncmd = VIDIOC_QUERYBUF; break;
  1061. case VIDIOC_G_FBUF32: ncmd = VIDIOC_G_FBUF; break;
  1062. case VIDIOC_S_FBUF32: ncmd = VIDIOC_S_FBUF; break;
  1063. case VIDIOC_QBUF32: ncmd = VIDIOC_QBUF; break;
  1064. case VIDIOC_DQBUF32: ncmd = VIDIOC_DQBUF; break;
  1065. case VIDIOC_ENUMSTD32: ncmd = VIDIOC_ENUMSTD; break;
  1066. case VIDIOC_ENUMINPUT32: ncmd = VIDIOC_ENUMINPUT; break;
  1067. case VIDIOC_TRY_FMT32: ncmd = VIDIOC_TRY_FMT; break;
  1068. case VIDIOC_G_EXT_CTRLS32: ncmd = VIDIOC_G_EXT_CTRLS; break;
  1069. case VIDIOC_S_EXT_CTRLS32: ncmd = VIDIOC_S_EXT_CTRLS; break;
  1070. case VIDIOC_TRY_EXT_CTRLS32: ncmd = VIDIOC_TRY_EXT_CTRLS; break;
  1071. case VIDIOC_DQEVENT32: ncmd = VIDIOC_DQEVENT; break;
  1072. case VIDIOC_OVERLAY32: ncmd = VIDIOC_OVERLAY; break;
  1073. case VIDIOC_STREAMON32: ncmd = VIDIOC_STREAMON; break;
  1074. case VIDIOC_STREAMOFF32: ncmd = VIDIOC_STREAMOFF; break;
  1075. case VIDIOC_G_INPUT32: ncmd = VIDIOC_G_INPUT; break;
  1076. case VIDIOC_S_INPUT32: ncmd = VIDIOC_S_INPUT; break;
  1077. case VIDIOC_G_OUTPUT32: ncmd = VIDIOC_G_OUTPUT; break;
  1078. case VIDIOC_S_OUTPUT32: ncmd = VIDIOC_S_OUTPUT; break;
  1079. case VIDIOC_CREATE_BUFS32: ncmd = VIDIOC_CREATE_BUFS; break;
  1080. case VIDIOC_PREPARE_BUF32: ncmd = VIDIOC_PREPARE_BUF; break;
  1081. case VIDIOC_G_EDID32: ncmd = VIDIOC_G_EDID; break;
  1082. case VIDIOC_S_EDID32: ncmd = VIDIOC_S_EDID; break;
  1083. default: ncmd = cmd; break;
  1084. }
  1085. /*
  1086. * 2. Allocates a 64-bits userspace pointer to store the
  1087. * values of the ioctl and copy data from the 32-bits __user
  1088. * argument into it.
  1089. */
  1090. switch (cmd) {
  1091. case VIDIOC_OVERLAY32:
  1092. case VIDIOC_STREAMON32:
  1093. case VIDIOC_STREAMOFF32:
  1094. case VIDIOC_S_INPUT32:
  1095. case VIDIOC_S_OUTPUT32:
  1096. err = alloc_userspace(sizeof(unsigned int), 0, &new_p64);
  1097. if (!err && assign_in_user((unsigned int __user *)new_p64,
  1098. (compat_uint_t __user *)p32))
  1099. err = -EFAULT;
  1100. compatible_arg = 0;
  1101. break;
  1102. case VIDIOC_G_INPUT32:
  1103. case VIDIOC_G_OUTPUT32:
  1104. err = alloc_userspace(sizeof(unsigned int), 0, &new_p64);
  1105. compatible_arg = 0;
  1106. break;
  1107. case VIDIOC_G_EDID32:
  1108. case VIDIOC_S_EDID32:
  1109. err = alloc_userspace(sizeof(struct v4l2_edid), 0, &new_p64);
  1110. if (!err)
  1111. err = get_v4l2_edid32(new_p64, p32);
  1112. compatible_arg = 0;
  1113. break;
  1114. case VIDIOC_G_FMT32:
  1115. case VIDIOC_S_FMT32:
  1116. case VIDIOC_TRY_FMT32:
  1117. err = bufsize_v4l2_format(p32, &aux_space);
  1118. if (!err)
  1119. err = alloc_userspace(sizeof(struct v4l2_format),
  1120. aux_space, &new_p64);
  1121. if (!err) {
  1122. aux_buf = new_p64 + sizeof(struct v4l2_format);
  1123. err = get_v4l2_format32(new_p64, p32,
  1124. aux_buf, aux_space);
  1125. }
  1126. compatible_arg = 0;
  1127. break;
  1128. case VIDIOC_CREATE_BUFS32:
  1129. err = bufsize_v4l2_create(p32, &aux_space);
  1130. if (!err)
  1131. err = alloc_userspace(sizeof(struct v4l2_create_buffers),
  1132. aux_space, &new_p64);
  1133. if (!err) {
  1134. aux_buf = new_p64 + sizeof(struct v4l2_create_buffers);
  1135. err = get_v4l2_create32(new_p64, p32,
  1136. aux_buf, aux_space);
  1137. }
  1138. compatible_arg = 0;
  1139. break;
  1140. case VIDIOC_PREPARE_BUF32:
  1141. case VIDIOC_QUERYBUF32:
  1142. case VIDIOC_QBUF32:
  1143. case VIDIOC_DQBUF32:
  1144. err = bufsize_v4l2_buffer(p32, &aux_space);
  1145. if (!err)
  1146. err = alloc_userspace(sizeof(struct v4l2_buffer),
  1147. aux_space, &new_p64);
  1148. if (!err) {
  1149. aux_buf = new_p64 + sizeof(struct v4l2_buffer);
  1150. err = get_v4l2_buffer32(new_p64, p32,
  1151. aux_buf, aux_space);
  1152. }
  1153. compatible_arg = 0;
  1154. break;
  1155. case VIDIOC_S_FBUF32:
  1156. err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
  1157. &new_p64);
  1158. if (!err)
  1159. err = get_v4l2_framebuffer32(new_p64, p32);
  1160. compatible_arg = 0;
  1161. break;
  1162. case VIDIOC_G_FBUF32:
  1163. err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
  1164. &new_p64);
  1165. compatible_arg = 0;
  1166. break;
  1167. case VIDIOC_ENUMSTD32:
  1168. err = alloc_userspace(sizeof(struct v4l2_standard), 0,
  1169. &new_p64);
  1170. if (!err)
  1171. err = get_v4l2_standard32(new_p64, p32);
  1172. compatible_arg = 0;
  1173. break;
  1174. case VIDIOC_ENUMINPUT32:
  1175. err = alloc_userspace(sizeof(struct v4l2_input), 0, &new_p64);
  1176. if (!err)
  1177. err = get_v4l2_input32(new_p64, p32);
  1178. compatible_arg = 0;
  1179. break;
  1180. case VIDIOC_G_EXT_CTRLS32:
  1181. case VIDIOC_S_EXT_CTRLS32:
  1182. case VIDIOC_TRY_EXT_CTRLS32:
  1183. err = bufsize_v4l2_ext_controls(p32, &aux_space);
  1184. if (!err)
  1185. err = alloc_userspace(sizeof(struct v4l2_ext_controls),
  1186. aux_space, &new_p64);
  1187. if (!err) {
  1188. aux_buf = new_p64 + sizeof(struct v4l2_ext_controls);
  1189. err = get_v4l2_ext_controls32(file, new_p64, p32,
  1190. aux_buf, aux_space);
  1191. }
  1192. compatible_arg = 0;
  1193. break;
  1194. case VIDIOC_DQEVENT32:
  1195. err = alloc_userspace(sizeof(struct v4l2_event), 0, &new_p64);
  1196. compatible_arg = 0;
  1197. break;
  1198. }
  1199. if (err)
  1200. return err;
  1201. /*
  1202. * 3. Calls the native 64-bits ioctl handler.
  1203. *
  1204. * For the functions where a conversion was not needed,
  1205. * compatible_arg is true, and it will call it with the arguments
  1206. * provided by userspace and stored at @p32 var.
  1207. *
  1208. * Otherwise, it will pass the newly allocated @new_p64 argument.
  1209. */
  1210. if (compatible_arg)
  1211. err = native_ioctl(file, ncmd, (unsigned long)p32);
  1212. else
  1213. err = native_ioctl(file, ncmd, (unsigned long)new_p64);
  1214. if (err == -ENOTTY)
  1215. return err;
  1216. /*
  1217. * 4. Special case: even after an error we need to put the
  1218. * results back for some ioctls.
  1219. *
  1220. * In the case of EXT_CTRLS, the error_idx will contain information
  1221. * on which control failed.
  1222. *
  1223. * In the case of S_EDID, the driver can return E2BIG and set
  1224. * the blocks to maximum allowed value.
  1225. */
  1226. switch (cmd) {
  1227. case VIDIOC_G_EXT_CTRLS32:
  1228. case VIDIOC_S_EXT_CTRLS32:
  1229. case VIDIOC_TRY_EXT_CTRLS32:
  1230. if (put_v4l2_ext_controls32(file, new_p64, p32))
  1231. err = -EFAULT;
  1232. break;
  1233. case VIDIOC_S_EDID32:
  1234. if (put_v4l2_edid32(new_p64, p32))
  1235. err = -EFAULT;
  1236. break;
  1237. }
  1238. if (err)
  1239. return err;
  1240. /*
  1241. * 5. Copy the data returned at the 64 bits userspace pointer to
  1242. * the original 32 bits structure.
  1243. */
  1244. switch (cmd) {
  1245. case VIDIOC_S_INPUT32:
  1246. case VIDIOC_S_OUTPUT32:
  1247. case VIDIOC_G_INPUT32:
  1248. case VIDIOC_G_OUTPUT32:
  1249. if (assign_in_user((compat_uint_t __user *)p32,
  1250. ((unsigned int __user *)new_p64)))
  1251. err = -EFAULT;
  1252. break;
  1253. case VIDIOC_G_FBUF32:
  1254. err = put_v4l2_framebuffer32(new_p64, p32);
  1255. break;
  1256. case VIDIOC_DQEVENT32:
  1257. err = put_v4l2_event32(new_p64, p32);
  1258. break;
  1259. case VIDIOC_G_EDID32:
  1260. err = put_v4l2_edid32(new_p64, p32);
  1261. break;
  1262. case VIDIOC_G_FMT32:
  1263. case VIDIOC_S_FMT32:
  1264. case VIDIOC_TRY_FMT32:
  1265. err = put_v4l2_format32(new_p64, p32);
  1266. break;
  1267. case VIDIOC_CREATE_BUFS32:
  1268. err = put_v4l2_create32(new_p64, p32);
  1269. break;
  1270. case VIDIOC_PREPARE_BUF32:
  1271. case VIDIOC_QUERYBUF32:
  1272. case VIDIOC_QBUF32:
  1273. case VIDIOC_DQBUF32:
  1274. err = put_v4l2_buffer32(new_p64, p32);
  1275. break;
  1276. case VIDIOC_ENUMSTD32:
  1277. err = put_v4l2_standard32(new_p64, p32);
  1278. break;
  1279. case VIDIOC_ENUMINPUT32:
  1280. err = put_v4l2_input32(new_p64, p32);
  1281. break;
  1282. }
  1283. return err;
  1284. }
  1285. /**
  1286. * v4l2_compat_ioctl32() - Handles a compat32 ioctl call
  1287. *
  1288. * @file: pointer to &struct file with the file handler
  1289. * @cmd: ioctl to be called
  1290. * @arg: arguments passed from/to the ioctl handler
  1291. *
  1292. * This function is meant to be used as .compat_ioctl fops at v4l2-dev.c
  1293. * in order to deal with 32-bit calls on a 64-bits Kernel.
  1294. *
  1295. * This function calls do_video_ioctl() for non-private V4L2 ioctls.
  1296. * If the function is a private one it calls vdev->fops->compat_ioctl32
  1297. * instead.
  1298. */
  1299. long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
  1300. {
  1301. struct video_device *vdev = video_devdata(file);
  1302. long ret = -ENOIOCTLCMD;
  1303. if (!file->f_op->unlocked_ioctl)
  1304. return ret;
  1305. if (_IOC_TYPE(cmd) == 'V' && _IOC_NR(cmd) < BASE_VIDIOC_PRIVATE)
  1306. ret = do_video_ioctl(file, cmd, arg);
  1307. else if (vdev->fops->compat_ioctl32)
  1308. ret = vdev->fops->compat_ioctl32(file, cmd, arg);
  1309. if (ret == -ENOIOCTLCMD)
  1310. pr_debug("compat_ioctl32: unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
  1311. _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd);
  1312. return ret;
  1313. }
  1314. EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32);