]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/nvdimm/dimm_devs.c
Merge tag 'selinux-pr-20191007' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / nvdimm / dimm_devs.c
index 29a065e769ea897359778dba417a78d7a54c7053..196aa44c4936a74a0e0a1147d19d740fca801120 100644 (file)
@@ -372,106 +372,26 @@ __weak ssize_t security_show(struct device *dev,
 {
        struct nvdimm *nvdimm = to_nvdimm(dev);
 
-       switch (nvdimm->sec.state) {
-       case NVDIMM_SECURITY_DISABLED:
+       if (test_bit(NVDIMM_SECURITY_DISABLED, &nvdimm->sec.flags))
                return sprintf(buf, "disabled\n");
-       case NVDIMM_SECURITY_UNLOCKED:
+       if (test_bit(NVDIMM_SECURITY_UNLOCKED, &nvdimm->sec.flags))
                return sprintf(buf, "unlocked\n");
-       case NVDIMM_SECURITY_LOCKED:
+       if (test_bit(NVDIMM_SECURITY_LOCKED, &nvdimm->sec.flags))
                return sprintf(buf, "locked\n");
-       case NVDIMM_SECURITY_FROZEN:
-               return sprintf(buf, "frozen\n");
-       case NVDIMM_SECURITY_OVERWRITE:
+       if (test_bit(NVDIMM_SECURITY_OVERWRITE, &nvdimm->sec.flags))
                return sprintf(buf, "overwrite\n");
-       default:
-               return -ENOTTY;
-       }
-
        return -ENOTTY;
 }
 
-#define OPS                                                    \
-       C( OP_FREEZE,           "freeze",               1),     \
-       C( OP_DISABLE,          "disable",              2),     \
-       C( OP_UPDATE,           "update",               3),     \
-       C( OP_ERASE,            "erase",                2),     \
-       C( OP_OVERWRITE,        "overwrite",            2),     \
-       C( OP_MASTER_UPDATE,    "master_update",        3),     \
-       C( OP_MASTER_ERASE,     "master_erase",         2)
-#undef C
-#define C(a, b, c) a
-enum nvdimmsec_op_ids { OPS };
-#undef C
-#define C(a, b, c) { b, c }
-static struct {
-       const char *name;
-       int args;
-} ops[] = { OPS };
-#undef C
-
-#define SEC_CMD_SIZE 32
-#define KEY_ID_SIZE 10
-
-static ssize_t __security_store(struct device *dev, const char *buf, size_t len)
+static ssize_t frozen_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
 {
        struct nvdimm *nvdimm = to_nvdimm(dev);
-       ssize_t rc;
-       char cmd[SEC_CMD_SIZE+1], keystr[KEY_ID_SIZE+1],
-               nkeystr[KEY_ID_SIZE+1];
-       unsigned int key, newkey;
-       int i;
 
-       if (atomic_read(&nvdimm->busy))
-               return -EBUSY;
-
-       rc = sscanf(buf, "%"__stringify(SEC_CMD_SIZE)"s"
-                       " %"__stringify(KEY_ID_SIZE)"s"
-                       " %"__stringify(KEY_ID_SIZE)"s",
-                       cmd, keystr, nkeystr);
-       if (rc < 1)
-               return -EINVAL;
-       for (i = 0; i < ARRAY_SIZE(ops); i++)
-               if (sysfs_streq(cmd, ops[i].name))
-                       break;
-       if (i >= ARRAY_SIZE(ops))
-               return -EINVAL;
-       if (ops[i].args > 1)
-               rc = kstrtouint(keystr, 0, &key);
-       if (rc >= 0 && ops[i].args > 2)
-               rc = kstrtouint(nkeystr, 0, &newkey);
-       if (rc < 0)
-               return rc;
-
-       if (i == OP_FREEZE) {
-               dev_dbg(dev, "freeze\n");
-               rc = nvdimm_security_freeze(nvdimm);
-       } else if (i == OP_DISABLE) {
-               dev_dbg(dev, "disable %u\n", key);
-               rc = nvdimm_security_disable(nvdimm, key);
-       } else if (i == OP_UPDATE) {
-               dev_dbg(dev, "update %u %u\n", key, newkey);
-               rc = nvdimm_security_update(nvdimm, key, newkey, NVDIMM_USER);
-       } else if (i == OP_ERASE) {
-               dev_dbg(dev, "erase %u\n", key);
-               rc = nvdimm_security_erase(nvdimm, key, NVDIMM_USER);
-       } else if (i == OP_OVERWRITE) {
-               dev_dbg(dev, "overwrite %u\n", key);
-               rc = nvdimm_security_overwrite(nvdimm, key);
-       } else if (i == OP_MASTER_UPDATE) {
-               dev_dbg(dev, "master_update %u %u\n", key, newkey);
-               rc = nvdimm_security_update(nvdimm, key, newkey,
-                               NVDIMM_MASTER);
-       } else if (i == OP_MASTER_ERASE) {
-               dev_dbg(dev, "master_erase %u\n", key);
-               rc = nvdimm_security_erase(nvdimm, key,
-                               NVDIMM_MASTER);
-       } else
-               return -EINVAL;
-
-       if (rc == 0)
-               rc = len;
-       return rc;
+       return sprintf(buf, "%d\n", test_bit(NVDIMM_SECURITY_FROZEN,
+                               &nvdimm->sec.flags));
 }
+static DEVICE_ATTR_RO(frozen);
 
 static ssize_t security_store(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t len)
@@ -487,7 +407,7 @@ static ssize_t security_store(struct device *dev,
        nd_device_lock(dev);
        nvdimm_bus_lock(dev);
        wait_nvdimm_bus_probe_idle(dev);
-       rc = __security_store(dev, buf, len);
+       rc = nvdimm_security_store(dev, buf, len);
        nvdimm_bus_unlock(dev);
        nd_device_unlock(dev);
 
@@ -501,6 +421,7 @@ static struct attribute *nvdimm_attributes[] = {
        &dev_attr_commands.attr,
        &dev_attr_available_slots.attr,
        &dev_attr_security.attr,
+       &dev_attr_frozen.attr,
        NULL,
 };
 
@@ -509,17 +430,24 @@ static umode_t nvdimm_visible(struct kobject *kobj, struct attribute *a, int n)
        struct device *dev = container_of(kobj, typeof(*dev), kobj);
        struct nvdimm *nvdimm = to_nvdimm(dev);
 
-       if (a != &dev_attr_security.attr)
+       if (a != &dev_attr_security.attr && a != &dev_attr_frozen.attr)
                return a->mode;
-       if (nvdimm->sec.state < 0)
+       if (!nvdimm->sec.flags)
                return 0;
-       /* Are there any state mutation ops? */
-       if (nvdimm->sec.ops->freeze || nvdimm->sec.ops->disable
-                       || nvdimm->sec.ops->change_key
-                       || nvdimm->sec.ops->erase
-                       || nvdimm->sec.ops->overwrite)
+
+       if (a == &dev_attr_security.attr) {
+               /* Are there any state mutation ops (make writable)? */
+               if (nvdimm->sec.ops->freeze || nvdimm->sec.ops->disable
+                               || nvdimm->sec.ops->change_key
+                               || nvdimm->sec.ops->erase
+                               || nvdimm->sec.ops->overwrite)
+                       return a->mode;
+               return 0444;
+       }
+
+       if (nvdimm->sec.ops->freeze)
                return a->mode;
-       return 0444;
+       return 0;
 }
 
 struct attribute_group nvdimm_attribute_group = {
@@ -569,8 +497,8 @@ struct nvdimm *__nvdimm_create(struct nvdimm_bus *nvdimm_bus,
         * attribute visibility.
         */
        /* get security state and extended (master) state */
-       nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER);
-       nvdimm->sec.ext_state = nvdimm_security_state(nvdimm, NVDIMM_MASTER);
+       nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER);
+       nvdimm->sec.ext_flags = nvdimm_security_flags(nvdimm, NVDIMM_MASTER);
        nd_device_register(dev);
 
        return nvdimm;
@@ -588,7 +516,7 @@ int nvdimm_security_setup_events(struct device *dev)
 {
        struct nvdimm *nvdimm = to_nvdimm(dev);
 
-       if (nvdimm->sec.state < 0 || !nvdimm->sec.ops
+       if (!nvdimm->sec.flags || !nvdimm->sec.ops
                        || !nvdimm->sec.ops->overwrite)
                return 0;
        nvdimm->sec.overwrite_state = sysfs_get_dirent(dev->kobj.sd, "security");
@@ -614,7 +542,7 @@ int nvdimm_security_freeze(struct nvdimm *nvdimm)
        if (!nvdimm->sec.ops || !nvdimm->sec.ops->freeze)
                return -EOPNOTSUPP;
 
-       if (nvdimm->sec.state < 0)
+       if (!nvdimm->sec.flags)
                return -EIO;
 
        if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) {
@@ -623,7 +551,7 @@ int nvdimm_security_freeze(struct nvdimm *nvdimm)
        }
 
        rc = nvdimm->sec.ops->freeze(nvdimm);
-       nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER);
+       nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER);
 
        return rc;
 }