aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/card/block.c
diff options
context:
space:
mode:
authorJohan Rudholm <johan.rudholm@stericsson.com>2011-11-23 03:05:58 -0500
committerLuis Henriques <luis.henriques@canonical.com>2012-03-26 05:26:36 -0400
commiteeee7c3219d7d56c3cf6bb09411c16141058d9a6 (patch)
tree5e963fa0fecfab3814f1c5fcdc33b93e45af7a6c /drivers/mmc/card/block.c
parent948781482cb779bbdad5e9a6b8191d84ae2ca870 (diff)
mmc: core: check for zero length ioctl data
BugLink: http://bugs.launchpad.net/bugs/954576 commit 4d6144de8ba263eb3691a737c547e5b2fdc45287 upstream. If the read or write buffer size associated with the command sent through the mmc_blk_ioctl is zero, do not prepare data buffer. This enables a ioctl(2) call to for instance send a MMC_SWITCH to set a byte in the ext_csd. Signed-off-by: Johan Rudholm <johan.rudholm@stericsson.com> Signed-off-by: Chris Ball <cjb@laptop.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/mmc/card/block.c')
-rw-r--r--drivers/mmc/card/block.c82
1 files changed, 45 insertions, 37 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index f85e4222455..c0839d48f6c 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -251,6 +251,9 @@ static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user(
251 goto idata_err; 251 goto idata_err;
252 } 252 }
253 253
254 if (!idata->buf_bytes)
255 return idata;
256
254 idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL); 257 idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL);
255 if (!idata->buf) { 258 if (!idata->buf) {
256 err = -ENOMEM; 259 err = -ENOMEM;
@@ -297,25 +300,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
297 if (IS_ERR(idata)) 300 if (IS_ERR(idata))
298 return PTR_ERR(idata); 301 return PTR_ERR(idata);
299 302
300 cmd.opcode = idata->ic.opcode;
301 cmd.arg = idata->ic.arg;
302 cmd.flags = idata->ic.flags;
303
304 data.sg = &sg;
305 data.sg_len = 1;
306 data.blksz = idata->ic.blksz;
307 data.blocks = idata->ic.blocks;
308
309 sg_init_one(data.sg, idata->buf, idata->buf_bytes);
310
311 if (idata->ic.write_flag)
312 data.flags = MMC_DATA_WRITE;
313 else
314 data.flags = MMC_DATA_READ;
315
316 mrq.cmd = &cmd;
317 mrq.data = &data;
318
319 md = mmc_blk_get(bdev->bd_disk); 303 md = mmc_blk_get(bdev->bd_disk);
320 if (!md) { 304 if (!md) {
321 err = -EINVAL; 305 err = -EINVAL;
@@ -328,6 +312,48 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
328 goto cmd_done; 312 goto cmd_done;
329 } 313 }
330 314
315 cmd.opcode = idata->ic.opcode;
316 cmd.arg = idata->ic.arg;
317 cmd.flags = idata->ic.flags;
318
319 if (idata->buf_bytes) {
320 data.sg = &sg;
321 data.sg_len = 1;
322 data.blksz = idata->ic.blksz;
323 data.blocks = idata->ic.blocks;
324
325 sg_init_one(data.sg, idata->buf, idata->buf_bytes);
326
327 if (idata->ic.write_flag)
328 data.flags = MMC_DATA_WRITE;
329 else
330 data.flags = MMC_DATA_READ;
331
332 /* data.flags must already be set before doing this. */
333 mmc_set_data_timeout(&data, card);
334
335 /* Allow overriding the timeout_ns for empirical tuning. */
336 if (idata->ic.data_timeout_ns)
337 data.timeout_ns = idata->ic.data_timeout_ns;
338
339 if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
340 /*
341 * Pretend this is a data transfer and rely on the
342 * host driver to compute timeout. When all host
343 * drivers support cmd.cmd_timeout for R1B, this
344 * 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 mrq.data = &data;
353 }
354
355 mrq.cmd = &cmd;
356
331 mmc_claim_host(card->host); 357 mmc_claim_host(card->host);
332 358
333 if (idata->ic.is_acmd) { 359 if (idata->ic.is_acmd) {
@@ -336,24 +362,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
336 goto cmd_rel_host; 362 goto cmd_rel_host;
337 } 363 }
338 364
339 /* data.flags must already be set before doing this. */
340 mmc_set_data_timeout(&data, card);
341 /* Allow overriding the timeout_ns for empirical tuning. */
342 if (idata->ic.data_timeout_ns)
343 data.timeout_ns = idata->ic.data_timeout_ns;
344
345 if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
346 /*
347 * Pretend this is a data transfer and rely on the host driver
348 * to compute timeout. When all host drivers support
349 * cmd.cmd_timeout for R1B, this can be changed to:
350 *
351 * mrq.data = NULL;
352 * cmd.cmd_timeout = idata->ic.cmd_timeout_ms;
353 */
354 data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000;
355 }
356
357 mmc_wait_for_req(card->host, &mrq); 365 mmc_wait_for_req(card->host, &mrq);
358 366
359 if (cmd.error) { 367 if (cmd.error) {