open-unlink.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. static int set_immutable(const char *path, int immutable)
  12. {
  13. unsigned int flags;
  14. int fd;
  15. int rc;
  16. int error;
  17. fd = open(path, O_RDONLY);
  18. if (fd < 0)
  19. return fd;
  20. rc = ioctl(fd, FS_IOC_GETFLAGS, &flags);
  21. if (rc < 0) {
  22. error = errno;
  23. close(fd);
  24. errno = error;
  25. return rc;
  26. }
  27. if (immutable)
  28. flags |= FS_IMMUTABLE_FL;
  29. else
  30. flags &= ~FS_IMMUTABLE_FL;
  31. rc = ioctl(fd, FS_IOC_SETFLAGS, &flags);
  32. error = errno;
  33. close(fd);
  34. errno = error;
  35. return rc;
  36. }
  37. static int get_immutable(const char *path)
  38. {
  39. unsigned int flags;
  40. int fd;
  41. int rc;
  42. int error;
  43. fd = open(path, O_RDONLY);
  44. if (fd < 0)
  45. return fd;
  46. rc = ioctl(fd, FS_IOC_GETFLAGS, &flags);
  47. if (rc < 0) {
  48. error = errno;
  49. close(fd);
  50. errno = error;
  51. return rc;
  52. }
  53. close(fd);
  54. if (flags & FS_IMMUTABLE_FL)
  55. return 1;
  56. return 0;
  57. }
  58. int main(int argc, char **argv)
  59. {
  60. const char *path;
  61. char buf[5];
  62. int fd, rc;
  63. if (argc < 2) {
  64. fprintf(stderr, "usage: %s <path>\n", argv[0]);
  65. return EXIT_FAILURE;
  66. }
  67. path = argv[1];
  68. /* attributes: EFI_VARIABLE_NON_VOLATILE |
  69. * EFI_VARIABLE_BOOTSERVICE_ACCESS |
  70. * EFI_VARIABLE_RUNTIME_ACCESS
  71. */
  72. *(uint32_t *)buf = 0x7;
  73. buf[4] = 0;
  74. /* create a test variable */
  75. fd = open(path, O_WRONLY | O_CREAT, 0600);
  76. if (fd < 0) {
  77. perror("open(O_WRONLY)");
  78. return EXIT_FAILURE;
  79. }
  80. rc = write(fd, buf, sizeof(buf));
  81. if (rc != sizeof(buf)) {
  82. perror("write");
  83. return EXIT_FAILURE;
  84. }
  85. close(fd);
  86. rc = get_immutable(path);
  87. if (rc < 0) {
  88. perror("ioctl(FS_IOC_GETFLAGS)");
  89. return EXIT_FAILURE;
  90. } else if (rc) {
  91. rc = set_immutable(path, 0);
  92. if (rc < 0) {
  93. perror("ioctl(FS_IOC_SETFLAGS)");
  94. return EXIT_FAILURE;
  95. }
  96. }
  97. fd = open(path, O_RDONLY);
  98. if (fd < 0) {
  99. perror("open");
  100. return EXIT_FAILURE;
  101. }
  102. if (unlink(path) < 0) {
  103. perror("unlink");
  104. return EXIT_FAILURE;
  105. }
  106. rc = read(fd, buf, sizeof(buf));
  107. if (rc > 0) {
  108. fprintf(stderr, "reading from an unlinked variable "
  109. "shouldn't be possible\n");
  110. return EXIT_FAILURE;
  111. }
  112. return EXIT_SUCCESS;
  113. }