common.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Linux Security Module infrastructure tests
  4. *
  5. * Copyright © 2023 Casey Schaufler <casey@schaufler-ca.com>
  6. */
  7. #define _GNU_SOURCE
  8. #include <linux/lsm.h>
  9. #include <fcntl.h>
  10. #include <string.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <sys/types.h>
  15. #include "common.h"
  16. #define PROCATTR "/proc/self/attr/"
  17. int read_proc_attr(const char *attr, char *value, size_t size)
  18. {
  19. int fd;
  20. int len;
  21. char *path;
  22. len = strlen(PROCATTR) + strlen(attr) + 1;
  23. path = calloc(len, 1);
  24. if (path == NULL)
  25. return -1;
  26. sprintf(path, "%s%s", PROCATTR, attr);
  27. fd = open(path, O_RDONLY);
  28. free(path);
  29. if (fd < 0)
  30. return -1;
  31. len = read(fd, value, size);
  32. close(fd);
  33. /* Ensure value is terminated */
  34. if (len <= 0 || len == size)
  35. return -1;
  36. value[len] = '\0';
  37. path = strchr(value, '\n');
  38. if (path)
  39. *path = '\0';
  40. return 0;
  41. }
  42. int read_sysfs_lsms(char *lsms, size_t size)
  43. {
  44. FILE *fp;
  45. size_t red;
  46. fp = fopen("/sys/kernel/security/lsm", "r");
  47. if (fp == NULL)
  48. return -1;
  49. red = fread(lsms, 1, size, fp);
  50. fclose(fp);
  51. if (red <= 0 || red == size)
  52. return -1;
  53. lsms[red] = '\0';
  54. return 0;
  55. }
  56. int attr_lsm_count(void)
  57. {
  58. char *names = calloc(sysconf(_SC_PAGESIZE), 1);
  59. int count = 0;
  60. if (!names)
  61. return 0;
  62. if (read_sysfs_lsms(names, sysconf(_SC_PAGESIZE)))
  63. return 0;
  64. if (strstr(names, "selinux"))
  65. count++;
  66. if (strstr(names, "smack"))
  67. count++;
  68. if (strstr(names, "apparmor"))
  69. count++;
  70. return count;
  71. }