1 #ifndef SELINUX_INTERNAL_H_
2 #define SELINUX_INTERNAL_H_
3
4 #include <selinux/selinux.h>
5 #include <errno.h>
6 #include <pthread.h>
7 #include <stdio.h>
8
9
10 extern int require_seusers ;
11 extern int selinux_page_size ;
12
13 /* Make pthread_once optional */
14 #pragma weak pthread_once
15 #pragma weak pthread_key_create
16 #pragma weak pthread_key_delete
17 #pragma weak pthread_setspecific
18 #pragma weak pthread_getspecific
19
20 /* Call handler iff the first call. */
21 #define __selinux_once(ONCE_CONTROL, INIT_FUNCTION) \
22 do { \
23 if (pthread_once != NULL) \
24 pthread_once (&(ONCE_CONTROL), (INIT_FUNCTION)); \
25 else if ((ONCE_CONTROL) == PTHREAD_ONCE_INIT) { \
26 INIT_FUNCTION (); \
27 (ONCE_CONTROL) = 2; \
28 } \
29 } while (0)
30
31 /* Pthread key macros */
32 #define __selinux_key_create(KEY, DESTRUCTOR) \
33 (pthread_key_create != NULL ? pthread_key_create(KEY, DESTRUCTOR) : -1)
34
35 #define __selinux_key_delete(KEY) \
36 do { \
37 if (pthread_key_delete != NULL) \
38 pthread_key_delete(KEY); \
39 } while (0)
40
41 #define __selinux_setspecific(KEY, VALUE) \
42 do { \
43 if (pthread_setspecific != NULL) \
44 pthread_setspecific(KEY, VALUE); \
45 } while (0)
46
47 #define __selinux_getspecific(KEY) \
48 (pthread_getspecific != NULL ? pthread_getspecific(KEY) : NULL)
49
50 /* selabel_lookup() is only thread safe if we're compiled with pthreads */
51
52 #pragma weak pthread_mutex_init
53 #pragma weak pthread_mutex_destroy
54 #pragma weak pthread_mutex_lock
55 #pragma weak pthread_mutex_unlock
56
57 #define __pthread_mutex_init(LOCK, ATTR) \
58 do { \
59 if (pthread_mutex_init != NULL) \
60 pthread_mutex_init(LOCK, ATTR); \
61 } while (0)
62
63 #define __pthread_mutex_destroy(LOCK) \
64 do { \
65 if (pthread_mutex_destroy != NULL) \
66 pthread_mutex_destroy(LOCK); \
67 } while (0)
68
69 #define __pthread_mutex_lock(LOCK) \
70 do { \
71 if (pthread_mutex_lock != NULL) \
72 pthread_mutex_lock(LOCK); \
73 } while (0)
74
75 #define __pthread_mutex_unlock(LOCK) \
76 do { \
77 if (pthread_mutex_unlock != NULL) \
78 pthread_mutex_unlock(LOCK); \
79 } while (0)
80
81 #pragma weak pthread_create
82 #pragma weak pthread_join
83 #pragma weak pthread_cond_init
84 #pragma weak pthread_cond_signal
85 #pragma weak pthread_cond_destroy
86 #pragma weak pthread_cond_wait
87
88 /* check if all functions needed to do parallel operations are available */
89 #define __pthread_supported ( \
90 pthread_create && \
91 pthread_join && \
92 pthread_cond_init && \
93 pthread_cond_destroy && \
94 pthread_cond_signal && \
95 pthread_cond_wait \
96 )
97
98 #define SELINUXDIR "/etc/selinux/"
99 #define SELINUXCONFIG SELINUXDIR "config"
100
101 extern int has_selinux_config ;
102
103 #ifndef HAVE_STRLCPY
104 size_t strlcpy(char *dest, const char *src, size_t size);
105 #endif
106
107 #ifndef HAVE_REALLOCARRAY
108 void *reallocarray(void *ptr, size_t nmemb, size_t size);
109 #endif
110
111 /* Use to ignore intentional unsigned under- and overflows while running under UBSAN. */
112 #if defined(__clang__) && defined(__clang_major__) && (__clang_major__ >= 4)
113 #if (__clang_major__ >= 12)
114 #define ignore_unsigned_overflow_ __attribute__((no_sanitize("unsigned-integer-overflow", "unsigned-shift-base")))
115 #else
116 #define ignore_unsigned_overflow_ __attribute__((no_sanitize("unsigned-integer-overflow")))
117 #endif
118 #else
119 #define ignore_unsigned_overflow_
120 #endif
121
122 /* Ignore usage of deprecated declaration */
123 #ifdef __clang__
124 #define IGNORE_DEPRECATED_DECLARATION_BEGIN \
125 _Pragma("clang diagnostic push") \
126 _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
127 #define IGNORE_DEPRECATED_DECLARATION_END \
128 _Pragma("clang diagnostic pop")
129 #elif defined __GNUC__
130 #define IGNORE_DEPRECATED_DECLARATION_BEGIN \
131 _Pragma("GCC diagnostic push") \
132 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
133 #define IGNORE_DEPRECATED_DECLARATION_END \
134 _Pragma("GCC diagnostic pop")
135 #else
136 #define IGNORE_DEPRECATED_DECLARATION_BEGIN
137 #define IGNORE_DEPRECATED_DECLARATION_END
138 #endif
139
fclose_errno_safe(FILE * stream)140 static inline void fclose_errno_safe(FILE *stream)
141 {
142 int saved_errno;
143
144 saved_errno = errno;
145 (void) fclose(stream);
146 errno = saved_errno;
147 }
148
149 #endif /* SELINUX_INTERNAL_H_ */
150