Add MMC password protection (lock/unlock) support
PATCH 4/5 Add MMC password protection (lock/unlock) support
Implement MMC password reset and forced erase support. It uses the sysfs mechanism to send commands to the MMC subsystem. Usage:
Forced erase:
echo erase > /sys/bus/mmc/devices/mmc0\:0001/lockable
Remove password:
echo remove > /sys/bus/mmc/devices/mmc0\:0001/lockable
Signed-off-by Anderson Briglia <[email protected]>
Signed-off-by Anderson Lizardo <[email protected]>
Signed-off-by Carlos Eduardo Aguiar <[email protected]>
drivers/mmc/mmc_sysfs.c +64 -1
@@ -16,6 +16,7 @@#include <linux/device.h> #include <linux/idr.h> #include <linux/key.h> +#include <linux/err.h> #include <linux/mmc/card.h> #include <linux/mmc/host.h>
@@ -64,6 +65,58 @@ static struct device_attribute mmc_dev_astatic struct device_attribute mmc_dev_attr_scr =MMC_ATTR_RO (scr); +#ifdef CONFIG_MMC_PASSWORDS + +static ssize_t +mmc_lockable_show (struct device *dev,struct device_attribute *att,char *buf) +{ +struct mmc_card *card =dev_to_mmc_card (dev); + +if (!mmc_card_lockable (card)) +return sprintf (buf,"unlockable\n" ); +else +return sprintf (buf,"lockable, %slocked\n" ,mmc_card_locked (card) ? +"" :"un" ); +} + +/* +* implement MMC password reset ("remove password") and forced erase ("forgot +* password"). +*/ +static ssize_t +mmc_lockable_store (struct device *dev,struct device_attribute *att, +const char *data,size_t len) +{ +struct mmc_card *card =dev_to_mmc_card (dev); + +if (!mmc_card_lockable (card)) +return -EINVAL ; + +if (mmc_card_locked (card) && !strncmp (data,"erase" ,5 )) { +/* forced erase only works while card is locked */ +mmc_lock_unlock (card,NULL ,MMC_LOCK_MODE_ERASE ); +return len; + }else if (!mmc_card_locked (card) && !strncmp (data,"remove" ,6 )) { +/* remove password only works while card is unlocked */ +struct key *mmc_key =request_key (&mmc_key_type,"mmc:key" ,NULL ); + +if (!IS_ERR (mmc_key)) { +int err =mmc_lock_unlock (card, mmc_key,MMC_LOCK_MODE_CLR_PWD ); +if (!err) +return len; + }else +dev_dbg (&card->dev,"request_key returned error %ld\n" ,PTR_ERR (mmc_key)); + } + +return -EINVAL ; +} + +static struct device_attribute mmc_dev_attr_lockable = +__ATTR (lockable,S_IWUSR |S_IRUGO , + mmc_lockable_show, mmc_lockable_store); + +#endif +static void mmc_release_card (struct device *dev) {
@@ -235,6 +288,13 @@ int mmc_register_card(struct mmc_card *cif (ret)device_del (&card->dev); } +#ifdef CONFIG_MMC_PASSWORDS +if (mmc_card_lockable (card)) { + ret =device_create_file (&card->dev, &mmc_dev_attr_lockable); +if (ret) +device_del (&card->dev); + } +#endif }return ret; }
@@ -248,7 +308,10 @@ void mmc_remove_card(struct mmc_card *caif (mmc_card_present (card)) {if (mmc_card_sd (card))device_remove_file (&card->dev, &mmc_dev_attr_scr); - +#ifdef CONFIG_MMC_PASSWORDS +if (mmc_card_lockable (card)) +device_remove_file (&card->dev, &mmc_dev_attr_lockable); +#endif device_del (&card->dev); }
--
Anderson Briglia,
Anderson Lizardo,
Carlos Eduardo Aguiar
Embedded Linux Lab - 10LE
Nokia Institute of Technology - INdT
Manaus - Brazil