Add MMC password protection (lock/unlock) support V3
PATCH 3/5 Add MMC password protection (lock/unlock) support V3
Implement key retention operations. mmc_key_instantiate() is used for unlocking and password assignment (from no-password state). mmc_key_update() is used for password change.
drivers/mmc/Kconfig +13 -0
@@ -19,6 +19,19 @@ config MMC_DEBUG This is an option for use by developers; most people should say N here. This enables MMC core and driver debugging. +config MMC_PASSWORDS + boolean "MMC card lock/unlock passwords (EXPERIMENTAL)" + depends on MMC && EXPERIMENTAL + select KEYS + help + Say Y here to enable the use of passwords to lock and unlock + MMC cards. This uses the access key retention support, using + request_key to look up the key associated with each card. + + For example, if you have an MMC card that was locked using + Symbian OS on your cell phone, you won't be able to read it + on Linux without this support. + config MMC_BLOCK tristate "MMC block device driver" depends on MMC
drivers/mmc/mmc.h +8 -0
@@ -18,4 +18,12 @@ struct mmc_host *mmc_alloc_host_sysfs(inint mmc_add_host_sysfs (struct mmc_host *host);void mmc_remove_host_sysfs (struct mmc_host *host);void mmc_free_host_sysfs (struct mmc_host *host); + +/* core-internal data */ +extern struct key_type mmc_key_type; +struct mmc_key_payload { +struct rcu_head rcu;/* RCU destructor */ +unsigned short datalen;/* length of this data */ +char data[0 ];/* actual data */ +};#endif
drivers/mmc/mmc_sysfs.c +154 -0
190 lines not on this page · raw message
drivers/mmc/mmc_sysfs.c static struct class mmc_host_class = { · line 355
Quoted 13 lines · Anderson Briglia
drivers/mmc/mmc_sysfs.c +13
-0+ dev =bus_find_device (&mmc_bus_type,NULL ,NULL , mmc_match_lockable); +if (!dev) + goto error; + card =dev_to_mmc_card (dev); + +if (operation ==KEY_OP_INSTANTIATE ) {/* KEY_OP_INSTANTIATE */ +if (mmc_card_locked (card)) { + ret =mmc_lock_unlock (card, key,MMC_LOCK_MODE_UNLOCK ); +mmc_remove_card (card); +mmc_register_card (card); + } +else + ret =mmc_lock_unlock (card, key,MMC_LOCK_MODE_SET_PWD );
I really don't like this - if the MMC card is not locked, we set a password on it. If it's locked, we unlock it.
That's a potential race condition if you're trying to unlock a card and the card is changed beneath you while you slept waiting for memory - you end up setting that password on the new card.
It's far better to have separate "unlock this card" and "set a password on this card" commands rather than trying to combine the two operations.
Also, removing and re-registering a card is an offence. These things are ref-counted, and mmc_remove_card() will drop the last reference - so the memory associated with it will be freed. Then you re-register it. Whoops.
If you merely want to try to attach a driver, use device_attach() instead.
Also, what if you have multiple MMC cards? I have a board here with two MMC slots. I'd rather not have it try to set the same password on both devices.
Signature · 3 lines
Russell King Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/ maintainer of: 2.6 Serial core
Quoted 22 lines · Russell King
Quoted 5 lines · Anderson Briglia
drivers/mmc/mmc_sysfs.c +3
-0+ dev =bus_find_device (&mmc_bus_type,NULL ,NULL , mmc_match_lockable); +if (!dev) + goto error;drivers/mmc/mmc_sysfs.c static struct class mmc_host_class = { · line 355
Quoted 10 lines
drivers/mmc/mmc_sysfs.c +10
-0+ card =dev_to_mmc_card (dev); + +if (operation ==KEY_OP_INSTANTIATE ) {/* KEY_OP_INSTANTIATE */ +if (mmc_card_locked (card)) { + ret =mmc_lock_unlock (card, key,MMC_LOCK_MODE_UNLOCK ); +mmc_remove_card (card); +mmc_register_card (card); + } +else + ret =mmc_lock_unlock (card, key,MMC_LOCK_MODE_SET_PWD );I really don't like this - if the MMC card is not locked, we set a password on it. If it's locked, we unlock it.
Quoted 9 lines
That's a potential race condition if you're trying to unlock a card and the card is changed beneath you while you slept waiting for memory - you end up setting that password on the new card.
It's far better to have separate "unlock this card" and "set a password on this card" commands rather than trying to combine the two operations.
Ok.
Quoted 9 lines
Also, removing and re-registering a card is an offence. These things are ref-counted, and
mmc_remove_card()will drop the last reference - so the memory associated with it will be freed. Then you re-register it. Whoops.If you merely want to try to attach a driver, use
device_attach()instead.
If we use device_attach(), the mmc_block driver is not informed about the card's unlocking. I did some tests, using device_attach() instead of those mmc functions and seems that the mmc_block driver tries to use a invalid device reference. What do you suggest on this case?
Quoted 5 lines
Also, what if you have multiple MMC cards? I have a board here with two MMC slots. I'd rather not have it try to set the same password on both devices.
Sorry, but this series of patches only support one mmc host. I'll update the TODO section of the summary e-mail.
Anderson Briglia
INdT - Manaus
Quoted 27 lines · Anderson Briglia
Quoted 24 lines · Russell King
Quoted 4 lines · Anderson Briglia
drivers/mmc/mmc_sysfs.c +3
-0+ dev =bus_find_device (&mmc_bus_type,NULL ,NULL , mmc_match_lockable); +if (!dev) + goto error;drivers/mmc/mmc_sysfs.c static struct class mmc_host_class = { · line 355
Quoted 10 lines
drivers/mmc/mmc_sysfs.c +10
-0+ card =dev_to_mmc_card (dev); + +if (operation ==KEY_OP_INSTANTIATE ) {/* KEY_OP_INSTANTIATE */ +if (mmc_card_locked (card)) { + ret =mmc_lock_unlock (card, key,MMC_LOCK_MODE_UNLOCK ); +mmc_remove_card (card); +mmc_register_card (card); + } +else + ret =mmc_lock_unlock (card, key,MMC_LOCK_MODE_SET_PWD );Also, removing and re-registering a card is an offence. These things are ref-counted, and
mmc_remove_card()will drop the last reference - so the memory associated with it will be freed. Then you re-register it. Whoops.
Quoted 3 lines
Quoted 3 lines
If you merely want to try to attach a driver, use
device_attach()instead.
We changed the mmc_remove_card() and mmc_register_card() by device_release_driver() and device_attach(), supposedly avoiding ref-counts issues.
Regards,
Anderson Briglia
INdT - Manaus
Quoted 28 lines · Anderson Briglia
Quoted 27 lines · Anderson Briglia
Quoted 24 lines · Russell King
Quoted 4 lines · Anderson Briglia
drivers/mmc/mmc_sysfs.c +3
-0+ dev =bus_find_device (&mmc_bus_type,NULL ,NULL , mmc_match_lockable); +if (!dev) + goto error;drivers/mmc/mmc_sysfs.c static struct class mmc_host_class = { · line 355
Quoted 10 lines
drivers/mmc/mmc_sysfs.c +10
-0+ card =dev_to_mmc_card (dev); + +if (operation ==KEY_OP_INSTANTIATE ) {/* KEY_OP_INSTANTIATE */ +if (mmc_card_locked (card)) { + ret =mmc_lock_unlock (card, key,MMC_LOCK_MODE_UNLOCK ); +mmc_remove_card (card); +mmc_register_card (card); + } +else + ret =mmc_lock_unlock (card, key,MMC_LOCK_MODE_SET_PWD );Also, removing and re-registering a card is an offence. These things are ref-counted, and
mmc_remove_card()will drop the last reference - so the memory associated with it will be freed. Then you re-register it. Whoops.
Quoted 6 lines
Quoted 3 lines
Quoted 3 lines
If you merely want to try to attach a driver, use
device_attach()instead.We changed the
mmc_remove_card()andmmc_register_card()bydevice_release_driver()anddevice_attach(), supposedly avoiding ref-counts issues.
As per my previous mail - I think this probably comes down to differences between mainline and the omap tree. My suggestion should work fine in mainline. I can only suspect that the OMAP tree is doing something it shouldn't.
Signature · 3 lines
Russell King Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/ maintainer of: 2.6 Serial core