linux/tools/testing/selftests/efivarfs/open-unlink.c
<<
>>
Prefs
   1#include <errno.h>
   2#include <stdio.h>
   3#include <stdint.h>
   4#include <stdlib.h>
   5#include <unistd.h>
   6#include <sys/ioctl.h>
   7#include <sys/types.h>
   8#include <sys/stat.h>
   9#include <fcntl.h>
  10#include <linux/fs.h>
  11
  12static int set_immutable(const char *path, int immutable)
  13{
  14        unsigned int flags;
  15        int fd;
  16        int rc;
  17        int error;
  18
  19        fd = open(path, O_RDONLY);
  20        if (fd < 0)
  21                return fd;
  22
  23        rc = ioctl(fd, FS_IOC_GETFLAGS, &flags);
  24        if (rc < 0) {
  25                error = errno;
  26                close(fd);
  27                errno = error;
  28                return rc;
  29        }
  30
  31        if (immutable)
  32                flags |= FS_IMMUTABLE_FL;
  33        else
  34                flags &= ~FS_IMMUTABLE_FL;
  35
  36        rc = ioctl(fd, FS_IOC_SETFLAGS, &flags);
  37        error = errno;
  38        close(fd);
  39        errno = error;
  40        return rc;
  41}
  42
  43static int get_immutable(const char *path)
  44{
  45        unsigned int flags;
  46        int fd;
  47        int rc;
  48        int error;
  49
  50        fd = open(path, O_RDONLY);
  51        if (fd < 0)
  52                return fd;
  53
  54        rc = ioctl(fd, FS_IOC_GETFLAGS, &flags);
  55        if (rc < 0) {
  56                error = errno;
  57                close(fd);
  58                errno = error;
  59                return rc;
  60        }
  61        close(fd);
  62        if (flags & FS_IMMUTABLE_FL)
  63                return 1;
  64        return 0;
  65}
  66
  67int main(int argc, char **argv)
  68{
  69        const char *path;
  70        char buf[5];
  71        int fd, rc;
  72
  73        if (argc < 2) {
  74                fprintf(stderr, "usage: %s <path>\n", argv[0]);
  75                return EXIT_FAILURE;
  76        }
  77
  78        path = argv[1];
  79
  80        /* attributes: EFI_VARIABLE_NON_VOLATILE |
  81         *              EFI_VARIABLE_BOOTSERVICE_ACCESS |
  82         *              EFI_VARIABLE_RUNTIME_ACCESS
  83         */
  84        *(uint32_t *)buf = 0x7;
  85        buf[4] = 0;
  86
  87        /* create a test variable */
  88        fd = open(path, O_WRONLY | O_CREAT, 0600);
  89        if (fd < 0) {
  90                perror("open(O_WRONLY)");
  91                return EXIT_FAILURE;
  92        }
  93
  94        rc = write(fd, buf, sizeof(buf));
  95        if (rc != sizeof(buf)) {
  96                perror("write");
  97                return EXIT_FAILURE;
  98        }
  99
 100        close(fd);
 101
 102        rc = get_immutable(path);
 103        if (rc < 0) {
 104                perror("ioctl(FS_IOC_GETFLAGS)");
 105                return EXIT_FAILURE;
 106        } else if (rc) {
 107                rc = set_immutable(path, 0);
 108                if (rc < 0) {
 109                        perror("ioctl(FS_IOC_SETFLAGS)");
 110                        return EXIT_FAILURE;
 111                }
 112        }
 113
 114        fd = open(path, O_RDONLY);
 115        if (fd < 0) {
 116                perror("open");
 117                return EXIT_FAILURE;
 118        }
 119
 120        if (unlink(path) < 0) {
 121                perror("unlink");
 122                return EXIT_FAILURE;
 123        }
 124
 125        rc = read(fd, buf, sizeof(buf));
 126        if (rc > 0) {
 127                fprintf(stderr, "reading from an unlinked variable "
 128                                "shouldn't be possible\n");
 129                return EXIT_FAILURE;
 130        }
 131
 132        return EXIT_SUCCESS;
 133}
 134