Blob: efivars.c
Blob id: d4e724e2ded6af25102d898a5c159d5971b35a6b
Size: 2.3 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | // SPDX-License-Identifier: LGPL-2.1-or-later /* * * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2015 Intel Corporation. All rights reserved. * * */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #define _GNU_SOURCE #include <stdio.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <stdint.h> #include <limits.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/param.h> #include <sys/uio.h> #include "peripheral/efivars.h" #define SYSFS_EFIVARS "/sys/firmware/efi/efivars" typedef struct { uint32_t data1; uint16_t data2; uint16_t data3; uint8_t data4[8]; } efi_guid_t; #define VENDOR_GUID \ (efi_guid_t) { 0xd5f9d775, 0x1a09, 0x4e89, \ { 0x96, 0xcf, 0x1d, 0x19, 0x55, 0x4d, 0xa6, 0x67 } } static void efivars_pathname(const char *name, char *pathname, size_t size) { static efi_guid_t guid = VENDOR_GUID; snprintf(pathname, size - 1, "%s/%s-%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", SYSFS_EFIVARS, name, guid.data1, guid.data2, guid.data3, guid.data4[0], guid.data4[1], guid.data4[2], guid.data4[3], guid.data4[4], guid.data4[5], guid.data4[6], guid.data4[7]); } int efivars_read(const char *name, uint32_t *attributes, void *data, size_t size) { char pathname[PATH_MAX]; struct iovec iov[2]; uint32_t attr; ssize_t len; int fd; efivars_pathname(name, pathname, PATH_MAX); fd = open(pathname, O_RDONLY | O_CLOEXEC); if (fd < 0) return -EIO; iov[0].iov_base = &attr; iov[0].iov_len = sizeof(attr); iov[1].iov_base = data; iov[1].iov_len = size; len = readv(fd, iov, 2); close(fd); if (len < 0) return -EIO; if (attributes) *attributes = attr; return 0; } int efivars_write(const char *name, uint32_t attributes, const void *data, size_t size) { char pathname[PATH_MAX]; void *buf; ssize_t written; int fd; efivars_pathname(name, pathname, PATH_MAX); buf = malloc(size + sizeof(attributes)); if (!buf) return -ENOMEM; fd = open(pathname, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0644); if (fd < 0) { free(buf); return -EIO; } memcpy(buf, &attributes, sizeof(attributes)); memcpy(buf + sizeof(attributes), data, size); written = write(fd, buf, size + sizeof(attributes)); close(fd); free(buf); if (written < 0) return -EIO; return 0; } |