1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2019 IBM Corporation <nayna@linux.ibm.com> 4 * 5 * This code exposes secure variables to user via sysfs 6 */ 7 8 #define pr_fmt(fmt) "secvar-sysfs: "fmt 9 10 #include <linux/slab.h> 11 #include <linux/compat.h> 12 #include <linux/string.h> 13 #include <linux/of.h> 14 #include <asm/secvar.h> 15 #include <asm/plpks.h> 16 17 #define NAME_MAX_SIZE 1024 18 19 static struct kobject *secvar_kobj; 20 static struct kset *secvar_kset; 21 22 static ssize_t format_show(struct kobject *kobj, struct kobj_attribute *attr, 23 char *buf) 24 { 25 char tmp[32]; 26 ssize_t len = secvar_ops->format(tmp, sizeof(tmp)); 27 28 if (len > 0) 29 return sysfs_emit(buf, "%s\n", tmp); 30 else if (len < 0) 31 pr_err("Error %zd reading format string\n", len); 32 else 33 pr_err("Got empty format string from backend\n"); 34 35 return -EIO; 36 } 37 38 39 static ssize_t size_show(struct kobject *kobj, struct kobj_attribute *attr, 40 char *buf) 41 { 42 u64 dsize; 43 int rc; 44 45 rc = secvar_ops->get(kobj->name, strlen(kobj->name) + 1, NULL, &dsize); 46 if (rc) { 47 if (rc != -ENOENT) 48 pr_err("Error retrieving %s variable size %d\n", kobj->name, rc); 49 return rc; 50 } 51 52 return sysfs_emit(buf, "%llu\n", dsize); 53 } 54 55 static ssize_t data_read(struct file *filep, struct kobject *kobj, 56 const struct bin_attribute *attr, char *buf, loff_t off, 57 size_t count) 58 { 59 char *data; 60 u64 dsize; 61 int rc; 62 63 rc = secvar_ops->get(kobj->name, strlen(kobj->name) + 1, NULL, &dsize); 64 if (rc) { 65 if (rc != -ENOENT) 66 pr_err("Error getting %s variable size %d\n", kobj->name, rc); 67 return rc; 68 } 69 pr_debug("dsize is %llu\n", dsize); 70 71 data = kzalloc(dsize, GFP_KERNEL); 72 if (!data) 73 return -ENOMEM; 74 75 rc = secvar_ops->get(kobj->name, strlen(kobj->name) + 1, data, &dsize); 76 if (rc) { 77 pr_err("Error getting %s variable %d\n", kobj->name, rc); 78 goto data_fail; 79 } 80 81 rc = memory_read_from_buffer(buf, count, &off, data, dsize); 82 83 data_fail: 84 kfree(data); 85 return rc; 86 } 87 88 static ssize_t update_write(struct file *filep, struct kobject *kobj, 89 const struct bin_attribute *attr, char *buf, loff_t off, 90 size_t count) 91 { 92 int rc; 93 94 pr_debug("count is %ld\n", count); 95 rc = secvar_ops->set(kobj->name, strlen(kobj->name) + 1, buf, count); 96 if (rc) { 97 pr_err("Error setting the %s variable %d\n", kobj->name, rc); 98 return rc; 99 } 100 101 return count; 102 } 103 104 static struct kobj_attribute format_attr = __ATTR_RO(format); 105 106 static struct kobj_attribute size_attr = __ATTR_RO(size); 107 108 static struct bin_attribute data_attr __ro_after_init = __BIN_ATTR_RO(data, 0); 109 110 static struct bin_attribute update_attr __ro_after_init = __BIN_ATTR_WO(update, 0); 111 112 static const struct bin_attribute *const secvar_bin_attrs[] = { 113 &data_attr, 114 &update_attr, 115 NULL, 116 }; 117 118 static struct attribute *secvar_attrs[] = { 119 &size_attr.attr, 120 NULL, 121 }; 122 123 static const struct attribute_group secvar_attr_group = { 124 .attrs = secvar_attrs, 125 .bin_attrs = secvar_bin_attrs, 126 }; 127 __ATTRIBUTE_GROUPS(secvar_attr); 128 129 static const struct kobj_type secvar_ktype = { 130 .sysfs_ops = &kobj_sysfs_ops, 131 .default_groups = secvar_attr_groups, 132 }; 133 134 static __init int update_kobj_size(void) 135 { 136 137 u64 varsize; 138 int rc = secvar_ops->max_size(&varsize); 139 140 if (rc) 141 return rc; 142 143 data_attr.size = varsize; 144 update_attr.size = varsize; 145 146 return 0; 147 } 148 149 static __init int add_var(const char *name) 150 { 151 struct kobject *kobj; 152 int rc; 153 154 kobj = kzalloc(sizeof(*kobj), GFP_KERNEL); 155 if (!kobj) 156 return -ENOMEM; 157 158 kobject_init(kobj, &secvar_ktype); 159 160 rc = kobject_add(kobj, &secvar_kset->kobj, "%s", name); 161 if (rc) { 162 pr_warn("kobject_add error %d for attribute: %s\n", rc, 163 name); 164 kobject_put(kobj); 165 return rc; 166 } 167 168 kobject_uevent(kobj, KOBJ_ADD); 169 return 0; 170 } 171 172 static __init int secvar_sysfs_load(void) 173 { 174 u64 namesize = 0; 175 char *name; 176 int rc; 177 178 name = kzalloc(NAME_MAX_SIZE, GFP_KERNEL); 179 if (!name) 180 return -ENOMEM; 181 182 do { 183 rc = secvar_ops->get_next(name, &namesize, NAME_MAX_SIZE); 184 if (rc) { 185 if (rc != -ENOENT) 186 pr_err("error getting secvar from firmware %d\n", rc); 187 else 188 rc = 0; 189 190 break; 191 } 192 193 rc = add_var(name); 194 } while (!rc); 195 196 kfree(name); 197 return rc; 198 } 199 200 static __init int secvar_sysfs_load_static(void) 201 { 202 const char * const *name_ptr = secvar_ops->var_names; 203 int rc; 204 205 while (*name_ptr) { 206 rc = add_var(*name_ptr); 207 if (rc) 208 return rc; 209 name_ptr++; 210 } 211 212 return 0; 213 } 214 215 static __init int secvar_sysfs_init(void) 216 { 217 u64 max_size; 218 int rc; 219 220 if (!secvar_ops) { 221 pr_warn("Failed to retrieve secvar operations\n"); 222 return -ENODEV; 223 } 224 225 secvar_kobj = kobject_create_and_add("secvar", firmware_kobj); 226 if (!secvar_kobj) { 227 pr_err("Failed to create firmware kobj\n"); 228 return -ENOMEM; 229 } 230 231 rc = sysfs_create_file(secvar_kobj, &format_attr.attr); 232 if (rc) { 233 pr_err("Failed to create format object\n"); 234 rc = -ENOMEM; 235 goto err; 236 } 237 238 secvar_kset = kset_create_and_add("vars", NULL, secvar_kobj); 239 if (!secvar_kset) { 240 pr_err("sysfs kobject registration failed\n"); 241 rc = -ENOMEM; 242 goto err; 243 } 244 245 rc = update_kobj_size(); 246 if (rc) { 247 pr_err("Cannot read the size of the attribute\n"); 248 goto err; 249 } 250 251 rc = plpks_config_create_softlink(secvar_kobj); 252 if (rc) { 253 pr_err("Failed to create softlink to PLPKS config directory"); 254 goto err; 255 } 256 257 pr_info("/sys/firmware/secvar/config is now deprecated.\n"); 258 pr_info("Will be removed in future versions.\n"); 259 260 if (secvar_ops->get_next) 261 rc = secvar_sysfs_load(); 262 else 263 rc = secvar_sysfs_load_static(); 264 265 if (rc) { 266 pr_err("Failed to create variable attributes\n"); 267 goto err; 268 } 269 270 // Due to sysfs limitations, we will only ever get a write buffer of 271 // up to 1 page in size. Print a warning if this is potentially going 272 // to cause problems, so that the user is aware. 273 secvar_ops->max_size(&max_size); 274 if (max_size > PAGE_SIZE) 275 pr_warn_ratelimited("PAGE_SIZE (%lu) is smaller than maximum object size (%llu), writes are limited to PAGE_SIZE\n", 276 PAGE_SIZE, max_size); 277 278 return 0; 279 err: 280 kobject_put(secvar_kobj); 281 return rc; 282 } 283 284 late_initcall(secvar_sysfs_init); 285