Re: [PATCH 4/4] Add MMC Password Protection (lock/unlock) support V9: mmc_sysfs.diff

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Pierre,

ext Pierre Ossman wrote:
> Anderson Briglia wrote:
>> Hi Pierre,
>>
>> How about now? Is better?
>>
>>   
> 
> Locking problem is still there. You need to unclaim the host even when
> claim fails.

Bug fixed. Is there anything else to improve?

Regards,

Anderson Briglia
Implement MMC password force erase, remove password, change password,
unlock card and assign password operations. It uses the sysfs mechanism
to send commands to the MMC subsystem. 

Signed-off-by: Carlos Eduardo Aguiar <[email protected]>
Signed-off-by: Anderson Lizardo <[email protected]>
Signed-off-by: Anderson Briglia <[email protected]>

Index: linux-linus-2.6/drivers/mmc/mmc_sysfs.c
===================================================================
--- linux-linus-2.6.orig/drivers/mmc/mmc_sysfs.c	2007-02-05 17:32:05.000000000 -0400
+++ linux-linus-2.6/drivers/mmc/mmc_sysfs.c	2007-02-05 17:32:19.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/idr.h>
 #include <linux/workqueue.h>
 #include <linux/key.h>
+#include <linux/err.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -65,6 +66,102 @@ static struct device_attribute mmc_dev_a
 
 static 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, "unsupported\n");
+	else
+		return sprintf(buf, "%slocked\n", mmc_card_locked(card) ?
+			"" : "un");
+}
+
+/*
+ * implement MMC password functions: force erase, remove password, change
+ * password, unlock card and assign 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);
+	int ret;
+
+	if(!mmc_card_lockable(card))
+		return -EINVAL;
+
+	ret = mmc_card_claim_host(card);
+	if (ret != MMC_ERR_NONE) {
+		mmc_card_release_host(card);
+		return -EINVAL;
+	}
+
+	ret = -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);
+		ret = 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", "remove");
+
+		if (!IS_ERR(mmc_key)) {
+			ret =  mmc_lock_unlock(card, mmc_key, MMC_LOCK_MODE_CLR_PWD);
+			if (!ret)
+				ret = len;
+		} else
+			dev_dbg(&card->dev, "request_key returned error %ld\n", PTR_ERR(mmc_key));
+	} else if (!mmc_card_locked(card) && ((!strncmp(data, "assign", 6)) ||
+					      (!strncmp(data, "change", 6)))) {
+		/* assign or change */
+		struct key *mmc_key;
+
+		if(!(strncmp(data, "assign", 6)))
+			mmc_key = request_key(&mmc_key_type, "mmc:key", "assign");
+		else
+			mmc_key = request_key(&mmc_key_type, "mmc:key", "change");
+
+		if (!IS_ERR(mmc_key)) {
+			ret =  mmc_lock_unlock(card, mmc_key, MMC_LOCK_MODE_SET_PWD);
+			if (!ret)
+				ret = len;
+		} else
+			dev_dbg(&card->dev, "request_key returned error %ld\n", PTR_ERR(mmc_key));
+	} else if (mmc_card_locked(card) && !strncmp(data, "unlock", 6)) {
+		/* unlock */
+		struct key *mmc_key = request_key(&mmc_key_type, "mmc:key", "unlock");
+		if (!IS_ERR(mmc_key)) {
+			ret = mmc_lock_unlock(card, mmc_key, MMC_LOCK_MODE_UNLOCK);
+			if (ret) {
+				dev_dbg(&card->dev, "Wrong password\n");
+				ret = -EINVAL;
+			}
+			else {
+				mmc_card_release_host(card);
+				device_release_driver(dev);
+				ret = device_attach(dev);
+				if(!ret)
+					return -EINVAL;
+				else
+					return len;
+			}
+		} else
+			dev_dbg(&card->dev, "request_key returned error %ld\n", PTR_ERR(mmc_key));
+	}
+
+	mmc_card_release_host(card);
+	return ret;
+}
+
+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)
 {
@@ -234,6 +331,11 @@ int mmc_register_card(struct mmc_card *c
 			if (ret)
 				device_del(&card->dev);
 		}
+#ifdef CONFIG_MMC_PASSWORDS
+		ret = device_create_file(&card->dev, &mmc_dev_attr_lockable);
+		if (ret)
+			device_del(&card->dev);
+#endif
 	}
 	return ret;
 }
@@ -248,6 +350,9 @@ void mmc_remove_card(struct mmc_card *ca
 		if (mmc_card_sd(card))
 			device_remove_file(&card->dev, &mmc_dev_attr_scr);
 
+#ifdef CONFIG_MMC_PASSWORDS
+		device_remove_file(&card->dev, &mmc_dev_attr_lockable);
+#endif
 		device_del(&card->dev);
 	}
 

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux