1 /* -*- mode: C; c-file-style: "gnu" -*-
2 * selinux.c SELinux security checks for D-Bus
4 * Author: Matthew Rickard <mjricka@epoch.ncsc.mil>
6 * Licensed under the Academic Free License version 2.1
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <dbus/dbus-internals.h>
24 #include <dbus/dbus-string.h>
29 #include "config-parser.h"
32 #include <sys/types.h>
37 #include <selinux/selinux.h>
38 #include <selinux/avc.h>
39 #include <selinux/av_permissions.h>
40 #include <selinux/flask.h>
46 #endif /* HAVE_LIBAUDIT */
47 #endif /* HAVE_SELINUX */
49 #define BUS_SID_FROM_SELINUX(sid) ((BusSELinuxID*) (sid))
50 #define SELINUX_SID_FROM_BUS(sid) ((security_id_t) (sid))
53 /* Store the value telling us if SELinux is enabled in the kernel. */
54 static dbus_bool_t selinux_enabled = FALSE;
56 /* Store an avc_entry_ref to speed AVC decisions. */
57 static struct avc_entry_ref aeref;
59 /* Store the SID of the bus itself to use as the default. */
60 static security_id_t bus_sid = SECSID_WILD;
62 /* Thread to listen for SELinux status changes via netlink. */
63 static pthread_t avc_notify_thread;
65 /* Prototypes for AVC callback functions. */
66 static void log_callback (const char *fmt, ...);
67 static void log_audit_callback (void *data, security_class_t class, char *buf, size_t bufleft);
68 static void *avc_create_thread (void (*run) (void));
69 static void avc_stop_thread (void *thread);
70 static void *avc_alloc_lock (void);
71 static void avc_get_lock (void *lock);
72 static void avc_release_lock (void *lock);
73 static void avc_free_lock (void *lock);
75 /* AVC callback structures for use in avc_init. */
76 static const struct avc_memory_callback mem_cb =
78 .func_malloc = dbus_malloc,
79 .func_free = dbus_free
81 static const struct avc_log_callback log_cb =
83 .func_log = log_callback,
84 .func_audit = log_audit_callback
86 static const struct avc_thread_callback thread_cb =
88 .func_create_thread = avc_create_thread,
89 .func_stop_thread = avc_stop_thread
91 static const struct avc_lock_callback lock_cb =
93 .func_alloc_lock = avc_alloc_lock,
94 .func_get_lock = avc_get_lock,
95 .func_release_lock = avc_release_lock,
96 .func_free_lock = avc_free_lock
98 #endif /* HAVE_SELINUX */
101 * Log callback to log denial messages from the AVC.
102 * This is used in avc_init. Logs to both standard
105 * @param fmt the format string
106 * @param variable argument list
111 static int audit_fd = -1;
118 audit_fd = audit_open ();
122 /* If kernel doesn't support audit, bail out */
123 if (errno == EINVAL || errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT)
125 /* If user bus, bail out */
126 if (errno == EPERM && getuid() != 0)
128 _dbus_warn ("Failed opening connection to the audit subsystem");
130 #endif /* HAVE_LIBAUDIT */
134 log_callback (const char *fmt, ...)
143 char buf[PATH_MAX*2];
145 /* FIXME: need to change this to show real user */
146 vsnprintf(buf, sizeof(buf), fmt, ap);
147 audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL,
151 #endif /* HAVE_LIBAUDIT */
153 vsyslog (LOG_INFO, fmt, ap);
158 * On a policy reload we need to reparse the SELinux configuration file, since
159 * this could have changed. Send a SIGHUP to reload all configs.
162 policy_reload_callback (u_int32_t event, security_id_t ssid,
163 security_id_t tsid, security_class_t tclass,
164 access_vector_t perms, access_vector_t *out_retained)
166 if (event == AVC_CALLBACK_RESET)
167 return raise (SIGHUP);
173 * Log any auxiliary data
176 log_audit_callback (void *data, security_class_t class, char *buf, size_t bufleft)
178 DBusString *audmsg = data;
179 _dbus_string_copy_to_buffer (audmsg, buf, bufleft);
183 * Create thread to notify the AVC of enforcing and policy reload
184 * changes via netlink.
186 * @param run the thread run function
187 * @return pointer to the thread
190 avc_create_thread (void (*run) (void))
194 rc = pthread_create (&avc_notify_thread, NULL, (void *(*) (void *)) run, NULL);
197 _dbus_warn ("Failed to start AVC thread: %s\n", _dbus_strerror (rc));
200 return &avc_notify_thread;
203 /* Stop AVC netlink thread. */
205 avc_stop_thread (void *thread)
207 pthread_cancel (*(pthread_t *) thread);
210 /* Allocate a new AVC lock. */
212 avc_alloc_lock (void)
214 pthread_mutex_t *avc_mutex;
216 avc_mutex = dbus_new (pthread_mutex_t, 1);
217 if (avc_mutex == NULL)
219 _dbus_warn ("Could not create mutex: %s\n", _dbus_strerror (errno));
222 pthread_mutex_init (avc_mutex, NULL);
227 /* Acquire an AVC lock. */
229 avc_get_lock (void *lock)
231 pthread_mutex_lock (lock);
234 /* Release an AVC lock. */
236 avc_release_lock (void *lock)
238 pthread_mutex_unlock (lock);
241 /* Free an AVC lock. */
243 avc_free_lock (void *lock)
245 pthread_mutex_destroy (lock);
248 #endif /* HAVE_SELINUX */
251 * Return whether or not SELinux is enabled; must be
252 * called after bus_selinux_init.
255 bus_selinux_enabled (void)
258 return selinux_enabled;
261 #endif /* HAVE_SELINUX */
265 * Do early initialization; determine whether SELinux is enabled.
268 bus_selinux_pre_init (void)
272 _dbus_assert (bus_sid == SECSID_WILD);
274 /* Determine if we are running an SELinux kernel. */
275 r = is_selinux_enabled ();
278 _dbus_warn ("Could not tell if SELinux is enabled: %s\n",
279 _dbus_strerror (errno));
283 selinux_enabled = r != 0;
291 * Initialize the user space access vector cache (AVC) for D-Bus and set up
295 bus_selinux_full_init (void)
300 _dbus_assert (bus_sid == SECSID_WILD);
302 if (!selinux_enabled)
304 _dbus_verbose ("SELinux not enabled in this kernel.\n");
308 _dbus_verbose ("SELinux is enabled in this kernel.\n");
310 avc_entry_ref_init (&aeref);
311 if (avc_init ("avc", &mem_cb, &log_cb, &thread_cb, &lock_cb) < 0)
313 _dbus_warn ("Failed to start Access Vector Cache (AVC).\n");
318 openlog ("dbus", LOG_PERROR, LOG_USER);
319 _dbus_verbose ("Access Vector Cache (AVC) started.\n");
322 if (avc_add_callback (policy_reload_callback, AVC_CALLBACK_RESET,
323 NULL, NULL, 0, 0) < 0)
325 _dbus_warn ("Failed to add policy reload callback: %s\n",
326 _dbus_strerror (errno));
332 bus_sid = SECSID_WILD;
334 if (getcon (&bus_context) < 0)
336 _dbus_verbose ("Error getting context of bus: %s\n",
337 _dbus_strerror (errno));
341 if (avc_context_to_sid (bus_context, &bus_sid) < 0)
343 _dbus_verbose ("Error getting SID from bus context: %s\n",
344 _dbus_strerror (errno));
345 freecon (bus_context);
349 freecon (bus_context);
356 #endif /* HAVE_SELINUX */
360 * Decrement SID reference count.
362 * @param sid the SID to decrement
365 bus_selinux_id_unref (BusSELinuxID *sid)
368 if (!selinux_enabled)
371 _dbus_assert (sid != NULL);
373 sidput (SELINUX_SID_FROM_BUS (sid));
374 #endif /* HAVE_SELINUX */
378 bus_selinux_id_ref (BusSELinuxID *sid)
381 if (!selinux_enabled)
384 _dbus_assert (sid != NULL);
386 sidget (SELINUX_SID_FROM_BUS (sid));
387 #endif /* HAVE_SELINUX */
391 * Determine if the SELinux security policy allows the given sender
392 * security context to go to the given recipient security context.
393 * This function determines if the requested permissions are to be
394 * granted from the connection to the message bus or to another
395 * optionally supplied security identifier (e.g. for a service
396 * context). Currently these permissions are either send_msg or
397 * acquire_svc in the dbus class.
399 * @param sender_sid source security context
400 * @param override_sid is the target security context. If SECSID_WILD this will
401 * use the context of the bus itself (e.g. the default).
402 * @param target_class is the target security class.
403 * @param requested is the requested permissions.
404 * @returns #TRUE if security policy allows the send.
408 bus_selinux_check (BusSELinuxID *sender_sid,
409 BusSELinuxID *override_sid,
410 security_class_t target_class,
411 access_vector_t requested,
414 if (!selinux_enabled)
417 /* Make the security check. AVC checks enforcing mode here as well. */
418 if (avc_has_perm (SELINUX_SID_FROM_BUS (sender_sid),
420 SELINUX_SID_FROM_BUS (override_sid) :
421 SELINUX_SID_FROM_BUS (bus_sid),
422 target_class, requested, &aeref, auxdata) < 0)
424 _dbus_verbose ("SELinux denying due to security policy.\n");
430 #endif /* HAVE_SELINUX */
433 * Returns true if the given connection can acquire a service,
434 * assuming the given security ID is needed for that service.
436 * @param connection connection that wants to own the service
437 * @param service_sid the SID of the service from the table
438 * @returns #TRUE if acquire is permitted.
441 bus_selinux_allows_acquire_service (DBusConnection *connection,
442 BusSELinuxID *service_sid,
443 const char *service_name,
447 BusSELinuxID *connection_sid;
452 if (!selinux_enabled)
455 connection_sid = bus_connection_get_selinux_id (connection);
456 if (!dbus_connection_get_unix_process_id (connection, &spid))
459 if (!_dbus_string_init (&auxdata))
462 if (!_dbus_string_append (&auxdata, "service="))
465 if (!_dbus_string_append (&auxdata, service_name))
470 if (!_dbus_string_append (&auxdata, " spid="))
473 if (!_dbus_string_append_uint (&auxdata, spid))
477 ret = bus_selinux_check (connection_sid,
483 _dbus_string_free (&auxdata);
487 _dbus_string_free (&auxdata);
493 #endif /* HAVE_SELINUX */
497 * Check if SELinux security controls allow the message to be sent to a
498 * particular connection based on the security context of the sender and
499 * that of the receiver. The destination connection need not be the
500 * addressed recipient, it could be an "eavesdropper"
502 * @param sender the sender of the message.
503 * @param proposed_recipient the connection the message is to be sent to.
504 * @returns whether to allow the send
507 bus_selinux_allows_send (DBusConnection *sender,
508 DBusConnection *proposed_recipient,
510 const char *interface,
512 const char *error_name,
513 const char *destination,
517 BusSELinuxID *recipient_sid;
518 BusSELinuxID *sender_sid;
519 unsigned long spid, tpid;
522 dbus_bool_t string_alloced;
524 if (!selinux_enabled)
527 if (!sender || !dbus_connection_get_unix_process_id (sender, &spid))
529 if (!proposed_recipient || !dbus_connection_get_unix_process_id (proposed_recipient, &tpid))
532 string_alloced = FALSE;
533 if (!_dbus_string_init (&auxdata))
535 string_alloced = TRUE;
537 if (!_dbus_string_append (&auxdata, "msgtype="))
540 if (!_dbus_string_append (&auxdata, msgtype))
545 if (!_dbus_string_append (&auxdata, " interface="))
547 if (!_dbus_string_append (&auxdata, interface))
553 if (!_dbus_string_append (&auxdata, " member="))
555 if (!_dbus_string_append (&auxdata, member))
561 if (!_dbus_string_append (&auxdata, " error_name="))
563 if (!_dbus_string_append (&auxdata, error_name))
569 if (!_dbus_string_append (&auxdata, " dest="))
571 if (!_dbus_string_append (&auxdata, destination))
577 if (!_dbus_string_append (&auxdata, " spid="))
580 if (!_dbus_string_append_uint (&auxdata, spid))
586 if (!_dbus_string_append (&auxdata, " tpid="))
589 if (!_dbus_string_append_uint (&auxdata, tpid))
593 sender_sid = bus_connection_get_selinux_id (sender);
594 /* A NULL proposed_recipient means the bus itself. */
595 if (proposed_recipient)
596 recipient_sid = bus_connection_get_selinux_id (proposed_recipient);
598 recipient_sid = BUS_SID_FROM_SELINUX (bus_sid);
600 ret = bus_selinux_check (sender_sid,
606 _dbus_string_free (&auxdata);
612 _dbus_string_free (&auxdata);
618 #endif /* HAVE_SELINUX */
622 bus_selinux_append_context (DBusMessage *message,
629 if (avc_sid_to_context (SELINUX_SID_FROM_BUS (sid), &context) < 0)
634 dbus_set_error (error, DBUS_ERROR_FAILED,
635 "Error getting context from SID: %s\n",
636 _dbus_strerror (errno));
639 if (!dbus_message_append_args (message,
646 _DBUS_SET_OOM (error);
657 * Gets the security context of a connection to the bus. It is up to
658 * the caller to freecon() when they are done.
660 * @param connection the connection to get the context of.
661 * @param con the location to store the security context.
662 * @returns #TRUE if context is successfully obtained.
666 bus_connection_read_selinux_context (DBusConnection *connection,
671 if (!selinux_enabled)
674 _dbus_assert (connection != NULL);
676 if (!dbus_connection_get_unix_fd (connection, &fd))
678 _dbus_verbose ("Failed to get file descriptor of socket.\n");
682 if (getpeercon (fd, con) < 0)
684 _dbus_verbose ("Error getting context of socket peer: %s\n",
685 _dbus_strerror (errno));
689 _dbus_verbose ("Successfully read connection context.\n");
692 #endif /* HAVE_SELINUX */
695 * Read the SELinux ID from the connection.
697 * @param connection the connection to read from
698 * @returns the SID if successfully determined, #NULL otherwise.
701 bus_selinux_init_connection_id (DBusConnection *connection,
708 if (!selinux_enabled)
711 if (!bus_connection_read_selinux_context (connection, &con))
713 dbus_set_error (error, DBUS_ERROR_FAILED,
714 "Failed to read an SELinux context from connection");
715 _dbus_verbose ("Error getting peer context.\n");
719 _dbus_verbose ("Converting context to SID to store on connection\n");
721 if (avc_context_to_sid (con, &sid) < 0)
726 dbus_set_error (error, DBUS_ERROR_FAILED,
727 "Error getting SID from context \"%s\": %s\n",
728 con, _dbus_strerror (errno));
730 _dbus_warn ("Error getting SID from context \"%s\": %s\n",
731 con, _dbus_strerror (errno));
738 return BUS_SID_FROM_SELINUX (sid);
741 #endif /* HAVE_SELINUX */
746 * Function for freeing hash table data. These SIDs
747 * should no longer be referenced.
750 bus_selinux_id_table_free_value (BusSELinuxID *sid)
753 /* NULL sometimes due to how DBusHashTable works */
755 bus_selinux_id_unref (sid);
756 #endif /* HAVE_SELINUX */
760 * Creates a new table mapping service names to security ID.
761 * A security ID is a "compiled" security context, a security
762 * context is just a string.
764 * @returns the new table or #NULL if no memory
767 bus_selinux_id_table_new (void)
769 return _dbus_hash_table_new (DBUS_HASH_STRING,
770 (DBusFreeFunction) dbus_free,
771 (DBusFreeFunction) bus_selinux_id_table_free_value);
775 * Hashes a service name and service context into the service SID
776 * table as a string and a SID.
778 * @param service_name is the name of the service.
779 * @param service_context is the context of the service.
780 * @param service_table is the table to hash them into.
781 * @return #FALSE if not enough memory
784 bus_selinux_id_table_insert (DBusHashTable *service_table,
785 const char *service_name,
786 const char *service_context)
793 if (!selinux_enabled)
799 key = _dbus_strdup (service_name);
803 if (avc_context_to_sid ((char *) service_context, &sid) < 0)
811 _dbus_warn ("Error getting SID from context \"%s\": %s\n",
812 (char *) service_context,
813 _dbus_strerror (errno));
817 if (!_dbus_hash_table_insert_string (service_table,
819 BUS_SID_FROM_SELINUX (sid)))
822 _dbus_verbose ("Parsed \tservice: %s \n\t\tcontext: %s\n",
826 /* These are owned by the hash, so clear them to avoid unref */
833 if (sid != SECSID_WILD)
842 #endif /* HAVE_SELINUX */
847 * Find the security identifier associated with a particular service
848 * name. Return a pointer to this SID, or #NULL/SECSID_WILD if the
849 * service is not found in the hash table. This should be nearly a
850 * constant time operation. If SELinux support is not available,
851 * always return NULL.
853 * @param service_table the hash table to check for service name.
854 * @param service_name the name of the service to look for.
855 * @returns the SELinux ID associated with the service
858 bus_selinux_id_table_lookup (DBusHashTable *service_table,
859 const DBusString *service_name)
864 sid = SECSID_WILD; /* default context */
866 if (!selinux_enabled)
869 _dbus_verbose ("Looking up service SID for %s\n",
870 _dbus_string_get_const_data (service_name));
872 sid = _dbus_hash_table_lookup_string (service_table,
873 _dbus_string_get_const_data (service_name));
875 if (sid == SECSID_WILD)
876 _dbus_verbose ("Service %s not found\n",
877 _dbus_string_get_const_data (service_name));
879 _dbus_verbose ("Service %s found\n",
880 _dbus_string_get_const_data (service_name));
882 return BUS_SID_FROM_SELINUX (sid);
883 #endif /* HAVE_SELINUX */
888 * Get the SELinux policy root. This is used to find the D-Bus
889 * specific config file within the policy.
892 bus_selinux_get_policy_root (void)
895 return selinux_policy_root ();
898 #endif /* HAVE_SELINUX */
902 * For debugging: Print out the current hash table of service SIDs.
905 bus_selinux_id_table_print (DBusHashTable *service_table)
907 #ifdef DBUS_ENABLE_VERBOSE_MODE
911 if (!selinux_enabled)
914 _dbus_verbose ("Service SID Table:\n");
915 _dbus_hash_iter_init (service_table, &iter);
916 while (_dbus_hash_iter_next (&iter))
918 const char *key = _dbus_hash_iter_get_string_key (&iter);
919 security_id_t sid = _dbus_hash_iter_get_value (&iter);
920 _dbus_verbose ("The key is %s\n", key);
921 _dbus_verbose ("The context is %s\n", sid->ctx);
922 _dbus_verbose ("The refcount is %d\n", sid->refcnt);
924 #endif /* HAVE_SELINUX */
925 #endif /* DBUS_ENABLE_VERBOSE_MODE */
929 #ifdef DBUS_ENABLE_VERBOSE_MODE
932 * Print out some AVC statistics.
935 bus_avc_print_stats (void)
937 struct avc_cache_stats cstats;
939 if (!selinux_enabled)
942 _dbus_verbose ("AVC Statistics:\n");
943 avc_cache_stats (&cstats);
945 _dbus_verbose ("AVC Cache Statistics:\n");
946 _dbus_verbose ("Entry lookups: %d\n", cstats.entry_lookups);
947 _dbus_verbose ("Entry hits: %d\n", cstats.entry_hits);
948 _dbus_verbose ("Entry misses %d\n", cstats.entry_misses);
949 _dbus_verbose ("Entry discards: %d\n", cstats.entry_discards);
950 _dbus_verbose ("CAV lookups: %d\n", cstats.cav_lookups);
951 _dbus_verbose ("CAV hits: %d\n", cstats.cav_hits);
952 _dbus_verbose ("CAV probes: %d\n", cstats.cav_probes);
953 _dbus_verbose ("CAV misses: %d\n", cstats.cav_misses);
955 #endif /* HAVE_SELINUX */
956 #endif /* DBUS_ENABLE_VERBOSE_MODE */
960 * Destroy the AVC before we terminate.
963 bus_selinux_shutdown (void)
966 if (!selinux_enabled)
969 _dbus_verbose ("AVC shutdown\n");
971 if (bus_sid != SECSID_WILD)
974 bus_sid = SECSID_WILD;
976 #ifdef DBUS_ENABLE_VERBOSE_MODE
978 if (_dbus_is_verbose())
979 bus_avc_print_stats ();
981 #endif /* DBUS_ENABLE_VERBOSE_MODE */
985 audit_close (audit_fd);
986 #endif /* HAVE_LIBAUDIT */
988 #endif /* HAVE_SELINUX */