Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: core: Add mmc CMD+ACMD passthrough ioctl

Allows appropriately-privileged applications to send CMD (normal) and ACMD
(application-specific; preceded with CMD55) commands to cards/devices on
the mmc bus. This is primarily useful for enabling the security
functionality built in to every SD card.

It can also be used as a generic passthrough (e.g. to enable virtual
machines to control mmc bus devices directly). However, this use case has
not been tested rigorously. Generic passthrough testing was only conducted
for a few non-security opcodes to prove the feasibility of the passthrough.

Since any opcode can be sent using this passthrough, it is very possible to
render the card/device unusable. Applications that use this ioctl must
have CAP_SYS_RAWIO.

Security commands tested on TI PCIxx12 (SDHCI), Sigma Designs SMP8652 SoC,
TI OMAP3621/OMAP3630 SoC, Samsung S5PC110 SoC, Qualcomm MSM7200A SoC.

Signed-off-by: John Calixto <john.calixto@modsystems.com>
Reviewed-by: Andrei Warkentin <andreiw@motorola.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Chris Ball <cjb@laptop.org>

authored by

John Calixto and committed by
Chris Ball
cb87ea28 641c3187

+261 -1
+1
Documentation/ioctl/ioctl-number.txt
··· 304 304 0xB0 all RATIO devices in development: 305 305 <mailto:vgo@ratio.de> 306 306 0xB1 00-1F PPPoX <mailto:mostrows@styx.uwaterloo.ca> 307 + 0xB3 00 linux/mmc/ioctl.h 307 308 0xC0 00-0F linux/usb/iowarrior.h 308 309 0xCB 00-1F CBM serial IEC bus in development: 309 310 <mailto:michael.klein@puffin.lb.shuttle.de>
+201
drivers/mmc/card/block.c
··· 31 31 #include <linux/mutex.h> 32 32 #include <linux/scatterlist.h> 33 33 #include <linux/string_helpers.h> 34 + #include <linux/delay.h> 35 + #include <linux/capability.h> 36 + #include <linux/compat.h> 34 37 38 + #include <linux/mmc/ioctl.h> 35 39 #include <linux/mmc/card.h> 36 40 #include <linux/mmc/host.h> 37 41 #include <linux/mmc/mmc.h> ··· 222 218 return 0; 223 219 } 224 220 221 + struct mmc_blk_ioc_data { 222 + struct mmc_ioc_cmd ic; 223 + unsigned char *buf; 224 + u64 buf_bytes; 225 + }; 226 + 227 + static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user( 228 + struct mmc_ioc_cmd __user *user) 229 + { 230 + struct mmc_blk_ioc_data *idata; 231 + int err; 232 + 233 + idata = kzalloc(sizeof(*idata), GFP_KERNEL); 234 + if (!idata) { 235 + err = -ENOMEM; 236 + goto copy_err; 237 + } 238 + 239 + if (copy_from_user(&idata->ic, user, sizeof(idata->ic))) { 240 + err = -EFAULT; 241 + goto copy_err; 242 + } 243 + 244 + idata->buf_bytes = (u64) idata->ic.blksz * idata->ic.blocks; 245 + if (idata->buf_bytes > MMC_IOC_MAX_BYTES) { 246 + err = -EOVERFLOW; 247 + goto copy_err; 248 + } 249 + 250 + idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL); 251 + if (!idata->buf) { 252 + err = -ENOMEM; 253 + goto copy_err; 254 + } 255 + 256 + if (copy_from_user(idata->buf, (void __user *)(unsigned long) 257 + idata->ic.data_ptr, idata->buf_bytes)) { 258 + err = -EFAULT; 259 + goto copy_err; 260 + } 261 + 262 + return idata; 263 + 264 + copy_err: 265 + kfree(idata->buf); 266 + kfree(idata); 267 + return ERR_PTR(err); 268 + 269 + } 270 + 271 + static int mmc_blk_ioctl_cmd(struct block_device *bdev, 272 + struct mmc_ioc_cmd __user *ic_ptr) 273 + { 274 + struct mmc_blk_ioc_data *idata; 275 + struct mmc_blk_data *md; 276 + struct mmc_card *card; 277 + struct mmc_command cmd = {0}; 278 + struct mmc_data data = {0}; 279 + struct mmc_request mrq = {0}; 280 + struct scatterlist sg; 281 + int err; 282 + 283 + /* 284 + * The caller must have CAP_SYS_RAWIO, and must be calling this on the 285 + * whole block device, not on a partition. This prevents overspray 286 + * between sibling partitions. 287 + */ 288 + if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains)) 289 + return -EPERM; 290 + 291 + idata = mmc_blk_ioctl_copy_from_user(ic_ptr); 292 + if (IS_ERR(idata)) 293 + return PTR_ERR(idata); 294 + 295 + cmd.opcode = idata->ic.opcode; 296 + cmd.arg = idata->ic.arg; 297 + cmd.flags = idata->ic.flags; 298 + 299 + data.sg = &sg; 300 + data.sg_len = 1; 301 + data.blksz = idata->ic.blksz; 302 + data.blocks = idata->ic.blocks; 303 + 304 + sg_init_one(data.sg, idata->buf, idata->buf_bytes); 305 + 306 + if (idata->ic.write_flag) 307 + data.flags = MMC_DATA_WRITE; 308 + else 309 + data.flags = MMC_DATA_READ; 310 + 311 + mrq.cmd = &cmd; 312 + mrq.data = &data; 313 + 314 + md = mmc_blk_get(bdev->bd_disk); 315 + if (!md) { 316 + err = -EINVAL; 317 + goto cmd_done; 318 + } 319 + 320 + card = md->queue.card; 321 + if (IS_ERR(card)) { 322 + err = PTR_ERR(card); 323 + goto cmd_done; 324 + } 325 + 326 + mmc_claim_host(card->host); 327 + 328 + if (idata->ic.is_acmd) { 329 + err = mmc_app_cmd(card->host, card); 330 + if (err) 331 + goto cmd_rel_host; 332 + } 333 + 334 + /* data.flags must already be set before doing this. */ 335 + mmc_set_data_timeout(&data, card); 336 + /* Allow overriding the timeout_ns for empirical tuning. */ 337 + if (idata->ic.data_timeout_ns) 338 + data.timeout_ns = idata->ic.data_timeout_ns; 339 + 340 + if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { 341 + /* 342 + * Pretend this is a data transfer and rely on the host driver 343 + * to compute timeout. When all host drivers support 344 + * cmd.cmd_timeout for R1B, this can be changed to: 345 + * 346 + * mrq.data = NULL; 347 + * cmd.cmd_timeout = idata->ic.cmd_timeout_ms; 348 + */ 349 + data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000; 350 + } 351 + 352 + mmc_wait_for_req(card->host, &mrq); 353 + 354 + if (cmd.error) { 355 + dev_err(mmc_dev(card->host), "%s: cmd error %d\n", 356 + __func__, cmd.error); 357 + err = cmd.error; 358 + goto cmd_rel_host; 359 + } 360 + if (data.error) { 361 + dev_err(mmc_dev(card->host), "%s: data error %d\n", 362 + __func__, data.error); 363 + err = data.error; 364 + goto cmd_rel_host; 365 + } 366 + 367 + /* 368 + * According to the SD specs, some commands require a delay after 369 + * issuing the command. 370 + */ 371 + if (idata->ic.postsleep_min_us) 372 + usleep_range(idata->ic.postsleep_min_us, idata->ic.postsleep_max_us); 373 + 374 + if (copy_to_user(&(ic_ptr->response), cmd.resp, sizeof(cmd.resp))) { 375 + err = -EFAULT; 376 + goto cmd_rel_host; 377 + } 378 + 379 + if (!idata->ic.write_flag) { 380 + if (copy_to_user((void __user *)(unsigned long) idata->ic.data_ptr, 381 + idata->buf, idata->buf_bytes)) { 382 + err = -EFAULT; 383 + goto cmd_rel_host; 384 + } 385 + } 386 + 387 + cmd_rel_host: 388 + mmc_release_host(card->host); 389 + 390 + cmd_done: 391 + mmc_blk_put(md); 392 + kfree(idata->buf); 393 + kfree(idata); 394 + return err; 395 + } 396 + 397 + static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode, 398 + unsigned int cmd, unsigned long arg) 399 + { 400 + int ret = -EINVAL; 401 + if (cmd == MMC_IOC_CMD) 402 + ret = mmc_blk_ioctl_cmd(bdev, (struct mmc_ioc_cmd __user *)arg); 403 + return ret; 404 + } 405 + 406 + #ifdef CONFIG_COMPAT 407 + static int mmc_blk_compat_ioctl(struct block_device *bdev, fmode_t mode, 408 + unsigned int cmd, unsigned long arg) 409 + { 410 + return mmc_blk_ioctl(bdev, mode, cmd, (unsigned long) compat_ptr(arg)); 411 + } 412 + #endif 413 + 225 414 static const struct block_device_operations mmc_bdops = { 226 415 .open = mmc_blk_open, 227 416 .release = mmc_blk_release, 228 417 .getgeo = mmc_blk_getgeo, 229 418 .owner = THIS_MODULE, 419 + .ioctl = mmc_blk_ioctl, 420 + #ifdef CONFIG_COMPAT 421 + .compat_ioctl = mmc_blk_compat_ioctl, 422 + #endif 230 423 }; 231 424 232 425 struct mmc_blk_request {
+2 -1
drivers/mmc/core/sd_ops.c
··· 21 21 #include "core.h" 22 22 #include "sd_ops.h" 23 23 24 - static int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) 24 + int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) 25 25 { 26 26 int err; 27 27 struct mmc_command cmd = {0}; ··· 49 49 50 50 return 0; 51 51 } 52 + EXPORT_SYMBOL_GPL(mmc_app_cmd); 52 53 53 54 /** 54 55 * mmc_wait_for_app_cmd - start an application command and wait for
+1
include/linux/Kbuild
··· 4 4 header-y += dvb/ 5 5 header-y += hdlc/ 6 6 header-y += isdn/ 7 + header-y += mmc/ 7 8 header-y += nfsd/ 8 9 header-y += raid/ 9 10 header-y += spi/
+1
include/linux/mmc/Kbuild
··· 1 + header-y += ioctl.h
+1
include/linux/mmc/core.h
··· 133 133 134 134 extern void mmc_wait_for_req(struct mmc_host *, struct mmc_request *); 135 135 extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); 136 + extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *); 136 137 extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, 137 138 struct mmc_command *, int); 138 139 extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int);
+54
include/linux/mmc/ioctl.h
··· 1 + #ifndef LINUX_MMC_IOCTL_H 2 + #define LINUX_MMC_IOCTL_H 3 + struct mmc_ioc_cmd { 4 + /* Implies direction of data. true = write, false = read */ 5 + int write_flag; 6 + 7 + /* Application-specific command. true = precede with CMD55 */ 8 + int is_acmd; 9 + 10 + __u32 opcode; 11 + __u32 arg; 12 + __u32 response[4]; /* CMD response */ 13 + unsigned int flags; 14 + unsigned int blksz; 15 + unsigned int blocks; 16 + 17 + /* 18 + * Sleep at least postsleep_min_us useconds, and at most 19 + * postsleep_max_us useconds *after* issuing command. Needed for 20 + * some read commands for which cards have no other way of indicating 21 + * they're ready for the next command (i.e. there is no equivalent of 22 + * a "busy" indicator for read operations). 23 + */ 24 + unsigned int postsleep_min_us; 25 + unsigned int postsleep_max_us; 26 + 27 + /* 28 + * Override driver-computed timeouts. Note the difference in units! 29 + */ 30 + unsigned int data_timeout_ns; 31 + unsigned int cmd_timeout_ms; 32 + 33 + /* 34 + * For 64-bit machines, the next member, ``__u64 data_ptr``, wants to 35 + * be 8-byte aligned. Make sure this struct is the same size when 36 + * built for 32-bit. 37 + */ 38 + __u32 __pad; 39 + 40 + /* DAT buffer */ 41 + __u64 data_ptr; 42 + }; 43 + #define mmc_ioc_cmd_set_data(ic, ptr) ic.data_ptr = (__u64)(unsigned long) ptr 44 + 45 + #define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd) 46 + 47 + /* 48 + * Since this ioctl is only meant to enhance (and not replace) normal access 49 + * to the mmc bus device, an upper data transfer limit of MMC_IOC_MAX_BYTES 50 + * is enforced per ioctl call. For larger data transfers, use the normal 51 + * block device operations. 52 + */ 53 + #define MMC_IOC_MAX_BYTES (512L * 256) 54 + #endif /* LINUX_MMC_IOCTL_H */