1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 * apparmor.c AppArmor security checks for D-Bus
6 * Copyright © 2014-2015 Canonical, Ltd.
8 * Licensed under the Academic Free License version 2.1
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
31 #include <dbus/dbus-internals.h>
32 #include <dbus/dbus-string.h>
39 #include <sys/apparmor.h>
41 #include <sys/types.h>
47 #endif /* HAVE_LIBAUDIT */
50 #include "connection.h"
53 /* Store the value telling us if AppArmor D-Bus mediation is enabled. */
54 static dbus_bool_t apparmor_enabled = FALSE;
62 /* Store the value of the AppArmor mediation mode in the bus configuration */
63 static AppArmorConfigMode apparmor_config_mode = APPARMOR_ENABLED;
65 /* The AppArmor context, consisting of a label and a mode. */
66 struct BusAppArmorConfinement
68 int refcount; /* Reference count */
70 char *label; /* AppArmor confinement label */
71 const char *mode; /* AppArmor confinement mode (freed by freeing *label) */
74 static BusAppArmorConfinement *bus_con = NULL;
77 * Callers of this function give up ownership of the *label and *mode
80 * Additionally, the responsibility of freeing *label and *mode becomes the
81 * responsibility of the bus_apparmor_confinement_unref() function. However, it
82 * does not free *mode because libapparmor's aa_getcon(), and libapparmor's
83 * other related functions, allocate a single buffer for *label and *mode and
84 * then separate the two char arrays with a NUL char. See the aa_getcon(2) man
85 * page for more details.
87 static BusAppArmorConfinement*
88 bus_apparmor_confinement_new (char *label,
91 BusAppArmorConfinement *confinement;
93 confinement = dbus_new0 (BusAppArmorConfinement, 1);
94 if (confinement != NULL)
96 confinement->refcount = 1;
97 confinement->label = label;
98 confinement->mode = mode;
105 * Return TRUE on successful check, FALSE on OOM.
106 * Set *is_supported to whether AA has D-Bus features.
109 _bus_apparmor_detect_aa_dbus_support (dbus_bool_t *is_supported)
113 char *aa_securityfs = NULL;
114 dbus_bool_t retval = FALSE;
116 *is_supported = FALSE;
118 if (!_dbus_string_init (&aa_dbus))
121 if (aa_find_mountpoint (&aa_securityfs) != 0)
125 * John Johansen has confirmed that the mainline kernel will not have
126 * the apparmorfs/features/dbus/mask file until the mainline kernel
127 * has AppArmor getpeersec support.
129 if (!_dbus_string_append (&aa_dbus, aa_securityfs) ||
130 !_dbus_string_append (&aa_dbus, "/features/dbus/mask"))
133 /* We need to open() the flag file, not just stat() it, because AppArmor
134 * does not mediate stat() in the apparmorfs. If you have a
135 * dbus-daemon inside an LXC container, with insufficiently broad
136 * AppArmor privileges to do its own AppArmor mediation, the desired
137 * result is that it behaves as if AppArmor was not present; but a stat()
138 * here would succeed, and result in it trying and failing to do full
139 * mediation. https://bugs.launchpad.net/ubuntu/+source/dbus/+bug/1238267 */
140 mask_file = open (_dbus_string_get_const_data (&aa_dbus),
141 O_RDONLY | O_CLOEXEC);
144 *is_supported = TRUE;
151 free (aa_securityfs);
152 _dbus_string_free (&aa_dbus);
158 modestr_is_complain (const char *mode)
160 if (mode && strcmp (mode, "complain") == 0)
166 log_message (dbus_bool_t allow, const char *op, DBusString *data)
179 audit_fd = bus_audit_get_fd ();
185 if (!_dbus_string_init (&avc))
188 if (!_dbus_string_append_printf (&avc,
189 "apparmor=\"%s\" operation=\"dbus_%s\" %s\n",
190 mstr, op, _dbus_string_get_const_data (data)))
192 _dbus_string_free (&avc);
196 /* FIXME: need to change this to show real user */
197 audit_log_user_avc_message (audit_fd, AUDIT_USER_AVC,
198 _dbus_string_get_const_data (&avc),
199 NULL, NULL, NULL, getuid ());
200 _dbus_string_free (&avc);
205 #endif /* HAVE_LIBAUDIT */
207 syslog (LOG_USER | LOG_NOTICE, "apparmor=\"%s\" operation=\"dbus_%s\" %s\n",
208 mstr, op, _dbus_string_get_const_data (data));
212 _dbus_append_pair_uint (DBusString *auxdata, const char *name,
215 return _dbus_string_append (auxdata, " ") &&
216 _dbus_string_append (auxdata, name) &&
217 _dbus_string_append (auxdata, "=") &&
218 _dbus_string_append_uint (auxdata, value);
222 _dbus_append_pair_str (DBusString *auxdata, const char *name, const char *value)
224 return _dbus_string_append (auxdata, " ") &&
225 _dbus_string_append (auxdata, name) &&
226 _dbus_string_append (auxdata, "=\"") &&
227 _dbus_string_append (auxdata, value) &&
228 _dbus_string_append (auxdata, "\"");
232 _dbus_append_mask (DBusString *auxdata, uint32_t mask)
234 const char *mask_str;
236 /* Only one permission bit can be set */
237 if (mask == AA_DBUS_SEND)
239 else if (mask == AA_DBUS_RECEIVE)
240 mask_str = "receive";
241 else if (mask == AA_DBUS_BIND)
246 return _dbus_append_pair_str (auxdata, "mask", mask_str);
250 is_unconfined (const char *con, const char *mode)
252 /* treat con == NULL as confined as it is going to result in a denial */
253 if ((!mode && con && strcmp (con, "unconfined") == 0) ||
254 strcmp (mode, "unconfined") == 0)
263 query_append (DBusString *query, const char *buffer)
265 if (!_dbus_string_append_byte (query, '\0'))
268 if (buffer && !_dbus_string_append (query, buffer))
275 build_common_query (DBusString *query, const char *con, const char *bustype)
278 * libapparmor's aa_query_label() function scribbles over the first
279 * AA_QUERY_CMD_LABEL_SIZE bytes of the query string with a private value.
281 return _dbus_string_insert_bytes (query, 0, AA_QUERY_CMD_LABEL_SIZE, 0) &&
282 _dbus_string_append (query, con) &&
283 _dbus_string_append_byte (query, '\0') &&
284 _dbus_string_append_byte (query, AA_CLASS_DBUS) &&
285 _dbus_string_append (query, bustype ? bustype : "");
289 build_service_query (DBusString *query,
294 return build_common_query (query, con, bustype) &&
295 query_append (query, name);
299 build_message_query (DBusString *query,
305 const char *interface,
308 return build_common_query (query, src_con, bustype) &&
309 query_append (query, name) &&
310 query_append (query, dst_con) &&
311 query_append (query, path) &&
312 query_append (query, interface) &&
313 query_append (query, member);
317 build_eavesdrop_query (DBusString *query, const char *con, const char *bustype)
319 return build_common_query (query, con, bustype);
323 set_error_from_query_errno (DBusError *error, int error_number)
325 dbus_set_error (error, _dbus_error_from_errno (error_number),
326 "Failed to query AppArmor policy: %s",
327 _dbus_strerror (error_number));
331 set_error_from_denied_message (DBusError *error,
332 DBusConnection *sender,
333 DBusConnection *proposed_recipient,
334 dbus_bool_t requested_reply,
337 const char *interface,
339 const char *error_name,
340 const char *destination)
342 const char *proposed_recipient_loginfo;
343 const char *unset = "(unset)";
345 proposed_recipient_loginfo = proposed_recipient ?
346 bus_connection_get_loginfo (proposed_recipient) :
349 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
350 "An AppArmor policy prevents this sender from sending this "
351 "message to this recipient; type=\"%s\", "
352 "sender=\"%s\" (%s) interface=\"%s\" member=\"%s\" "
353 "error name=\"%s\" requested_reply=\"%d\" "
354 "destination=\"%s\" (%s)",
356 bus_connection_get_name (sender),
357 bus_connection_get_loginfo (sender),
358 interface ? interface : unset,
359 member ? member : unset,
360 error_name ? error_name : unset,
363 proposed_recipient_loginfo);
365 #endif /* HAVE_APPARMOR */
368 * Do early initialization; determine whether AppArmor is enabled.
369 * Return TRUE on successful check (whether AppArmor is actually
370 * enabled or not) or FALSE on OOM.
373 bus_apparmor_pre_init (void)
376 apparmor_enabled = FALSE;
378 if (!aa_is_enabled ())
381 if (!_bus_apparmor_detect_aa_dbus_support (&apparmor_enabled))
389 bus_apparmor_set_mode_from_config (const char *mode, DBusError *error)
394 if (strcmp (mode, "disabled") == 0)
395 apparmor_config_mode = APPARMOR_DISABLED;
396 else if (strcmp (mode, "enabled") == 0)
397 apparmor_config_mode = APPARMOR_ENABLED;
398 else if (strcmp (mode, "required") == 0)
399 apparmor_config_mode = APPARMOR_REQUIRED;
402 dbus_set_error (error, DBUS_ERROR_FAILED,
403 "Mode attribute on <apparmor> must have value "
404 "\"required\", \"enabled\" or \"disabled\", "
412 if (mode == NULL || strcmp (mode, "disabled") == 0 ||
413 strcmp (mode, "enabled") == 0)
416 dbus_set_error (error, DBUS_ERROR_FAILED,
417 "Mode attribute on <apparmor> must have value \"enabled\" or "
418 "\"disabled\" but cannot be \"%s\" when D-Bus is built "
419 "without AppArmor support", mode);
425 * Verify that the config mode is compatible with the kernel's AppArmor
426 * support. If AppArmor mediation will be enabled, determine the bus
430 bus_apparmor_full_init (DBusError *error)
435 if (apparmor_enabled)
437 if (apparmor_config_mode == APPARMOR_DISABLED)
439 apparmor_enabled = FALSE;
445 if (aa_getcon (&label, &mode) == -1)
447 dbus_set_error (error, DBUS_ERROR_FAILED,
448 "Error getting AppArmor context of bus: %s",
449 _dbus_strerror (errno));
453 bus_con = bus_apparmor_confinement_new (label, mode);
464 if (apparmor_config_mode == APPARMOR_REQUIRED)
466 dbus_set_error (error, DBUS_ERROR_FAILED,
467 "AppArmor mediation required but not present");
470 else if (apparmor_config_mode == APPARMOR_ENABLED)
481 bus_apparmor_shutdown (void)
484 if (!apparmor_enabled)
487 _dbus_verbose ("AppArmor shutdown\n");
489 bus_apparmor_confinement_unref (bus_con);
491 #endif /* HAVE_APPARMOR */
495 bus_apparmor_enabled (void)
498 return apparmor_enabled;
505 bus_apparmor_confinement_unref (BusAppArmorConfinement *confinement)
508 if (!apparmor_enabled)
511 _dbus_assert (confinement != NULL);
512 _dbus_assert (confinement->refcount > 0);
514 confinement->refcount -= 1;
516 if (confinement->refcount == 0)
519 * Do not free confinement->mode, as libapparmor does a single malloc for
520 * both confinement->label and confinement->mode.
522 free (confinement->label);
523 dbus_free (confinement);
529 bus_apparmor_confinement_ref (BusAppArmorConfinement *confinement)
532 if (!apparmor_enabled)
535 _dbus_assert (confinement != NULL);
536 _dbus_assert (confinement->refcount > 0);
538 confinement->refcount += 1;
539 #endif /* HAVE_APPARMOR */
542 BusAppArmorConfinement*
543 bus_apparmor_init_connection_confinement (DBusConnection *connection,
547 BusAppArmorConfinement *confinement;
551 if (!apparmor_enabled)
554 _dbus_assert (connection != NULL);
556 if (!dbus_connection_get_socket (connection, &fd))
558 dbus_set_error (error, DBUS_ERROR_FAILED,
559 "Failed to get socket file descriptor of connection");
563 if (aa_getpeercon (fd, &label, &mode) == -1)
568 dbus_set_error (error, _dbus_error_from_errno (errno),
569 "Failed to get AppArmor confinement information of socket peer: %s",
570 _dbus_strerror (errno));
574 confinement = bus_apparmor_confinement_new (label, mode);
575 if (confinement == NULL)
585 #endif /* HAVE_APPARMOR */
589 * Returns true if the given connection can acquire a service,
590 * using the tasks security context
592 * @param connection connection that wants to own the service
593 * @param bustype name of the bus
594 * @param service_name the name of the service to acquire
595 * @param error the reason for failure when FALSE is returned
596 * @returns TRUE if acquire is permitted
599 bus_apparmor_allows_acquire_service (DBusConnection *connection,
601 const char *service_name,
606 BusAppArmorConfinement *con = NULL;
607 DBusString qstr, auxdata;
608 dbus_bool_t free_auxdata = FALSE;
609 dbus_bool_t allow = FALSE, audit = TRUE;
613 if (!apparmor_enabled)
616 _dbus_assert (connection != NULL);
618 con = bus_connection_dup_apparmor_confinement (connection);
620 if (is_unconfined (con->label, con->mode))
627 if (!_dbus_string_init (&qstr))
630 if (!build_service_query (&qstr, con->label, bustype, service_name))
632 _dbus_string_free (&qstr);
636 res = aa_query_label (AA_DBUS_BIND,
637 _dbus_string_get_data (&qstr),
638 _dbus_string_get_length (&qstr),
640 _dbus_string_free (&qstr);
644 set_error_from_query_errno (error, serrno);
648 /* Don't fail operations on profiles in complain mode */
649 if (modestr_is_complain (con->mode))
653 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
654 "Connection \"%s\" is not allowed to own the service "
655 "\"%s\" due to AppArmor policy",
656 bus_connection_is_active (connection) ?
657 bus_connection_get_name (connection) : "(inactive)",
664 if (!_dbus_string_init (&auxdata))
668 if (!_dbus_append_pair_str (&auxdata, "bus", bustype ? bustype : "unknown"))
671 if (!_dbus_append_pair_str (&auxdata, "name", service_name))
674 if (serrno && !_dbus_append_pair_str (&auxdata, "info", strerror (serrno)))
677 if (!_dbus_append_mask (&auxdata, AA_DBUS_BIND))
680 if (connection && dbus_connection_get_unix_process_id (connection, &pid) &&
681 !_dbus_append_pair_uint (&auxdata, "pid", pid))
684 if (con->label && !_dbus_append_pair_str (&auxdata, "label", con->label))
687 log_message (allow, "bind", &auxdata);
691 bus_apparmor_confinement_unref (con);
693 _dbus_string_free (&auxdata);
697 if (error != NULL && !dbus_error_is_set (error))
704 #endif /* HAVE_APPARMOR */
708 * Check if Apparmor security controls allow the message to be sent to a
709 * particular connection based on the security context of the sender and
710 * that of the receiver. The destination connection need not be the
711 * addressed recipient, it could be an "eavesdropper"
713 * @param sender the sender of the message.
714 * @param proposed_recipient the connection the message is to be sent to.
715 * @param requested_reply TRUE if the message is a reply requested by
717 * @param bustype name of the bus
718 * @param msgtype message type (DBUS_MESSAGE_TYPE_METHOD_CALL, etc.)
719 * @param path object path the message should be sent to
720 * @param interface the type of the object instance
721 * @param member the member of the object
722 * @param error_name the name of the error if the message type is error
723 * @param destination name that the message should be sent to
724 * @param source name that the message should be sent from
725 * @param error the reason for failure when FALSE is returned
726 * @returns TRUE if the message is permitted
729 bus_apparmor_allows_send (DBusConnection *sender,
730 DBusConnection *proposed_recipient,
731 dbus_bool_t requested_reply,
735 const char *interface,
737 const char *error_name,
738 const char *destination,
743 BusAppArmorConfinement *src_con = NULL, *dst_con = NULL;
744 DBusString qstr, auxdata;
745 dbus_bool_t src_allow = FALSE, dst_allow = FALSE;
746 dbus_bool_t src_audit = TRUE, dst_audit = TRUE;
747 dbus_bool_t free_auxdata = FALSE;
749 int len, res, src_errno = 0, dst_errno = 0;
750 uint32_t src_perm = AA_DBUS_SEND, dst_perm = AA_DBUS_RECEIVE;
751 const char *msgtypestr = dbus_message_type_to_string(msgtype);
753 if (!apparmor_enabled)
756 _dbus_assert (sender != NULL);
758 src_con = bus_connection_dup_apparmor_confinement (sender);
760 if (proposed_recipient)
762 dst_con = bus_connection_dup_apparmor_confinement (proposed_recipient);
767 bus_apparmor_confinement_ref (dst_con);
770 /* map reply messages to initial send and receive permission. That is
771 * permission to receive a message from X grants permission to reply to X.
772 * And permission to send a message to Y grants permission to receive a reply
773 * from Y. Note that this only applies to requested replies. Unrequested
774 * replies still require a policy query.
778 /* ignore requested reply messages and let dbus reply mapping handle them
779 * as the send was already allowed
786 if (is_unconfined (src_con->label, src_con->mode))
793 if (!_dbus_string_init (&qstr))
796 if (!build_message_query (&qstr, src_con->label, bustype, destination,
797 dst_con->label, path, interface, member))
799 _dbus_string_free (&qstr);
803 res = aa_query_label (src_perm,
804 _dbus_string_get_data (&qstr),
805 _dbus_string_get_length (&qstr),
806 &src_allow, &src_audit);
807 _dbus_string_free (&qstr);
811 set_error_from_query_errno (error, src_errno);
816 if (is_unconfined (dst_con->label, dst_con->mode))
823 if (!_dbus_string_init (&qstr))
826 if (!build_message_query (&qstr, dst_con->label, bustype, source,
827 src_con->label, path, interface, member))
829 _dbus_string_free (&qstr);
833 res = aa_query_label (dst_perm,
834 _dbus_string_get_data (&qstr),
835 _dbus_string_get_length (&qstr),
836 &dst_allow, &dst_audit);
837 _dbus_string_free (&qstr);
841 set_error_from_query_errno (error, dst_errno);
846 /* Don't fail operations on profiles in complain mode */
847 if (modestr_is_complain (src_con->mode))
849 if (modestr_is_complain (dst_con->mode))
852 if (!src_allow || !dst_allow)
853 set_error_from_denied_message (error,
864 /* Don't audit the message if one of the following conditions is true:
865 * 1) The AppArmor query indicates that auditing should not happen.
866 * 2) The message is a reply type. Reply message are not audited because
867 * the AppArmor policy language does not have the notion of a reply
868 * message. Unrequested replies will be silently discarded if the sender
869 * does not have permission to send to the receiver or if the receiver
870 * does not have permission to receive from the sender.
872 if ((!src_audit && !dst_audit) ||
873 (msgtype == DBUS_MESSAGE_TYPE_METHOD_RETURN ||
874 msgtype == DBUS_MESSAGE_TYPE_ERROR))
878 if (!_dbus_string_init (&auxdata))
882 if (!_dbus_append_pair_str (&auxdata, "bus", bustype ? bustype : "unknown"))
885 if (path && !_dbus_append_pair_str (&auxdata, "path", path))
888 if (interface && !_dbus_append_pair_str (&auxdata, "interface", interface))
891 if (member && !_dbus_append_pair_str (&auxdata, "member", member))
894 if (error_name && !_dbus_append_pair_str (&auxdata, "error_name", error_name))
897 len = _dbus_string_get_length (&auxdata);
901 if (!_dbus_append_mask (&auxdata, src_perm))
904 if (destination && !_dbus_append_pair_str (&auxdata, "name", destination))
907 if (sender && dbus_connection_get_unix_process_id (sender, &pid) &&
908 !_dbus_append_pair_uint (&auxdata, "pid", pid))
911 if (src_con->label &&
912 !_dbus_append_pair_str (&auxdata, "label", src_con->label))
915 if (proposed_recipient &&
916 dbus_connection_get_unix_process_id (proposed_recipient, &pid) &&
917 !_dbus_append_pair_uint (&auxdata, "peer_pid", pid))
920 if (dst_con->label &&
921 !_dbus_append_pair_str (&auxdata, "peer_label", dst_con->label))
924 if (src_errno && !_dbus_append_pair_str (&auxdata, "info", strerror (src_errno)))
928 !_dbus_append_pair_str (&auxdata, "peer_info", strerror (dst_errno)))
931 log_message (src_allow, msgtypestr, &auxdata);
935 _dbus_string_set_length (&auxdata, len);
937 if (source && !_dbus_append_pair_str (&auxdata, "name", source))
940 if (!_dbus_append_mask (&auxdata, dst_perm))
943 if (proposed_recipient &&
944 dbus_connection_get_unix_process_id (proposed_recipient, &pid) &&
945 !_dbus_append_pair_uint (&auxdata, "pid", pid))
948 if (dst_con->label &&
949 !_dbus_append_pair_str (&auxdata, "label", dst_con->label))
952 if (sender && dbus_connection_get_unix_process_id (sender, &pid) &&
953 !_dbus_append_pair_uint (&auxdata, "peer_pid", pid))
956 if (src_con->label &&
957 !_dbus_append_pair_str (&auxdata, "peer_label", src_con->label))
960 if (dst_errno && !_dbus_append_pair_str (&auxdata, "info", strerror (dst_errno)))
964 !_dbus_append_pair_str (&auxdata, "peer_info", strerror (src_errno)))
967 log_message (dst_allow, msgtypestr, &auxdata);
972 bus_apparmor_confinement_unref (src_con);
974 bus_apparmor_confinement_unref (dst_con);
976 _dbus_string_free (&auxdata);
978 return src_allow && dst_allow;
981 if (error != NULL && !dbus_error_is_set (error))
989 #endif /* HAVE_APPARMOR */
993 * Check if Apparmor security controls allow the connection to eavesdrop on
996 * @param connection the connection attempting to eavesdrop.
997 * @param bustype name of the bus
998 * @param error the reason for failure when FALSE is returned
999 * @returns TRUE if eavesdropping is permitted
1002 bus_apparmor_allows_eavesdropping (DBusConnection *connection,
1003 const char *bustype,
1006 #ifdef HAVE_APPARMOR
1007 BusAppArmorConfinement *con = NULL;
1008 DBusString qstr, auxdata;
1009 dbus_bool_t allow = FALSE, audit = TRUE;
1010 dbus_bool_t free_auxdata = FALSE;
1012 int res, serrno = 0;
1014 if (!apparmor_enabled)
1017 con = bus_connection_dup_apparmor_confinement (connection);
1019 if (is_unconfined (con->label, con->mode))
1026 if (!_dbus_string_init (&qstr))
1029 if (!build_eavesdrop_query (&qstr, con->label, bustype))
1031 _dbus_string_free (&qstr);
1035 res = aa_query_label (AA_DBUS_EAVESDROP,
1036 _dbus_string_get_data (&qstr),
1037 _dbus_string_get_length (&qstr),
1039 _dbus_string_free (&qstr);
1043 set_error_from_query_errno (error, serrno);
1047 /* Don't fail operations on profiles in complain mode */
1048 if (modestr_is_complain (con->mode))
1052 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
1053 "Connection \"%s\" is not allowed to eavesdrop due to "
1055 bus_connection_is_active (connection) ?
1056 bus_connection_get_name (connection) : "(inactive)");
1062 if (!_dbus_string_init (&auxdata))
1064 free_auxdata = TRUE;
1066 if (!_dbus_append_pair_str (&auxdata, "bus", bustype ? bustype : "unknown"))
1069 if (serrno && !_dbus_append_pair_str (&auxdata, "info", strerror (serrno)))
1072 if (!_dbus_append_pair_str (&auxdata, "mask", "eavesdrop"))
1075 if (connection && dbus_connection_get_unix_process_id (connection, &pid) &&
1076 !_dbus_append_pair_uint (&auxdata, "pid", pid))
1079 if (con->label && !_dbus_append_pair_str (&auxdata, "label", con->label))
1082 log_message (allow, "eavesdrop", &auxdata);
1086 bus_apparmor_confinement_unref (con);
1088 _dbus_string_free (&auxdata);
1093 if (error != NULL && !dbus_error_is_set (error))
1094 BUS_SET_OOM (error);
1100 #endif /* HAVE_APPARMOR */