mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-02 13:08:04 +02:00
2004-11-09 Colin Walters <walters@verbum.org>
* dbus/dbus-string.c (_dbus_string_get_length): New function, writes DBusString to C buffer. * dbus/dbus-string.h: Prototype it. * dbus/dbus-message.c (dbus_message_type_to_string): New function, converts message type into C string. * dbus/dbus-message.h: Prototype it. * bus/selinux.c (bus_selinux_check): Take source pid, target pid, and audit data. Pass audit data to avc_has_perm. (log_audit_callback): New function, appends extra audit information. (bus_selinux_allows_acquire_service): Also take service name, add it to audit data. (bus_selinux_allows_send): Also take message type, interface, method member, error name, and destination, and add them to audit data. (log_cb): Initialize func_audit. * bus/selinux.h (bus_selinux_allows_acquire_service) (bus_selinux_allows_send): Update prototypes * bus/services.c (bus_registry_acquire_service): Pass service name to bus_selinux_allows_acquire_service. * bus/bus.c (bus_context_check_security_policy): Pass additional audit data. Move assignment of dest to its own line.
This commit is contained in:
parent
2f5e949851
commit
935a41a04c
9 changed files with 211 additions and 19 deletions
34
ChangeLog
34
ChangeLog
|
|
@ -1,3 +1,37 @@
|
|||
2004-11-09 Colin Walters <walters@verbum.org>
|
||||
|
||||
* dbus/dbus-string.c (_dbus_string_get_length): New
|
||||
function, writes DBusString to C buffer.
|
||||
|
||||
* dbus/dbus-string.h: Prototype it.
|
||||
|
||||
* dbus/dbus-message.c (dbus_message_type_to_string): New
|
||||
function, converts message type into C string.
|
||||
|
||||
* dbus/dbus-message.h: Prototype it.
|
||||
|
||||
* bus/selinux.c (bus_selinux_check): Take source pid,
|
||||
target pid, and audit data. Pass audit data to
|
||||
avc_has_perm.
|
||||
(log_audit_callback): New function, appends extra
|
||||
audit information.
|
||||
(bus_selinux_allows_acquire_service): Also take
|
||||
service name, add it to audit data.
|
||||
(bus_selinux_allows_send): Also take message
|
||||
type, interface, method member, error name,
|
||||
and destination, and add them to audit data.
|
||||
(log_cb): Initialize func_audit.
|
||||
|
||||
* bus/selinux.h (bus_selinux_allows_acquire_service)
|
||||
(bus_selinux_allows_send): Update prototypes
|
||||
|
||||
* bus/services.c (bus_registry_acquire_service): Pass
|
||||
service name to bus_selinux_allows_acquire_service.
|
||||
|
||||
* bus/bus.c (bus_context_check_security_policy): Pass
|
||||
additional audit data. Move assignment of dest
|
||||
to its own line.
|
||||
|
||||
2004-11-07 Colin Walters <walters@verbum.org>
|
||||
|
||||
* dbus/dbus-transport-unix.c (do_authentication): Always
|
||||
|
|
|
|||
24
bus/bus.c
24
bus/bus.c
|
|
@ -1127,12 +1127,20 @@ bus_context_check_security_policy (BusContext *context,
|
|||
|
||||
if (sender != NULL)
|
||||
{
|
||||
const char *dest;
|
||||
|
||||
dest = dbus_message_get_destination (message);
|
||||
|
||||
/* First verify the SELinux access controls. If allowed then
|
||||
* go on with the standard checks.
|
||||
*/
|
||||
if (!bus_selinux_allows_send (sender, proposed_recipient))
|
||||
if (!bus_selinux_allows_send (sender, proposed_recipient,
|
||||
dbus_message_type_to_string (dbus_message_get_type (message)),
|
||||
dbus_message_get_interface (message),
|
||||
dbus_message_get_member (message),
|
||||
dbus_message_get_error_name (message),
|
||||
dest ? dest : DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
|
||||
{
|
||||
const char *dest = dbus_message_get_destination (message);
|
||||
dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
|
||||
"An SELinux policy prevents this sender "
|
||||
"from sending this message to this recipient "
|
||||
|
|
@ -1255,7 +1263,9 @@ bus_context_check_security_policy (BusContext *context,
|
|||
proposed_recipient,
|
||||
message))
|
||||
{
|
||||
const char *dest = dbus_message_get_destination (message);
|
||||
const char *dest;
|
||||
|
||||
dest = dbus_message_get_destination (message);
|
||||
dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
|
||||
"A security policy in place prevents this sender "
|
||||
"from sending this message to this recipient, "
|
||||
|
|
@ -1280,7 +1290,9 @@ bus_context_check_security_policy (BusContext *context,
|
|||
addressed_recipient, proposed_recipient,
|
||||
message))
|
||||
{
|
||||
const char *dest = dbus_message_get_destination (message);
|
||||
const char *dest;
|
||||
|
||||
dest = dbus_message_get_destination (message);
|
||||
dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
|
||||
"A security policy in place prevents this recipient "
|
||||
"from receiving this message from this sender, "
|
||||
|
|
@ -1304,7 +1316,9 @@ bus_context_check_security_policy (BusContext *context,
|
|||
dbus_connection_get_outgoing_size (proposed_recipient) >
|
||||
context->limits.max_outgoing_bytes)
|
||||
{
|
||||
const char *dest = dbus_message_get_destination (message);
|
||||
const char *dest;
|
||||
|
||||
dest = dbus_message_get_destination (message);
|
||||
dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
|
||||
"The destination service \"%s\" has a full message queue",
|
||||
dest ? dest : (proposed_recipient ?
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ static pthread_t avc_notify_thread;
|
|||
|
||||
/* Prototypes for AVC callback functions. */
|
||||
static void log_callback (const char *fmt, ...);
|
||||
static void log_audit_callback (void *data, security_class_t class, char *buf, size_t bufleft);
|
||||
static void *avc_create_thread (void (*run) (void));
|
||||
static void avc_stop_thread (void *thread);
|
||||
static void *avc_alloc_lock (void);
|
||||
|
|
@ -73,7 +74,7 @@ static const struct avc_memory_callback mem_cb =
|
|||
static const struct avc_log_callback log_cb =
|
||||
{
|
||||
.func_log = log_callback,
|
||||
.func_audit = NULL
|
||||
.func_audit = log_audit_callback
|
||||
};
|
||||
static const struct avc_thread_callback thread_cb =
|
||||
{
|
||||
|
|
@ -122,6 +123,18 @@ policy_reload_callback (u_int32_t event, security_id_t ssid,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log any auxiliary data
|
||||
*/
|
||||
static void
|
||||
log_audit_callback (void *data, security_class_t class, char *buf, size_t bufleft)
|
||||
{
|
||||
DBusString *audmsg = data;
|
||||
_dbus_string_copy_to_buffer (audmsg, buf, bufleft);
|
||||
_dbus_string_free (audmsg);
|
||||
dbus_free (audmsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create thread to notify the AVC of enforcing and policy reload
|
||||
* changes via netlink.
|
||||
|
|
@ -349,17 +362,28 @@ static dbus_bool_t
|
|||
bus_selinux_check (BusSELinuxID *sender_sid,
|
||||
BusSELinuxID *override_sid,
|
||||
security_class_t target_class,
|
||||
access_vector_t requested)
|
||||
access_vector_t requested,
|
||||
unsigned long spid,
|
||||
unsigned long tpid,
|
||||
DBusString *auxdata)
|
||||
{
|
||||
if (!selinux_enabled)
|
||||
return TRUE;
|
||||
|
||||
if (auxdata)
|
||||
{
|
||||
if (spid && _dbus_string_append (auxdata, " spid="))
|
||||
_dbus_string_append_uint (auxdata, spid);
|
||||
if (tpid && _dbus_string_append (auxdata, " tpid="))
|
||||
_dbus_string_append_uint (auxdata, tpid);
|
||||
}
|
||||
|
||||
/* Make the security check. AVC checks enforcing mode here as well. */
|
||||
if (avc_has_perm (SELINUX_SID_FROM_BUS (sender_sid),
|
||||
override_sid ?
|
||||
SELINUX_SID_FROM_BUS (override_sid) :
|
||||
SELINUX_SID_FROM_BUS (bus_sid),
|
||||
target_class, requested, &aeref, NULL) < 0)
|
||||
target_class, requested, &aeref, auxdata) < 0)
|
||||
{
|
||||
_dbus_verbose ("SELinux denying due to security policy.\n");
|
||||
return FALSE;
|
||||
|
|
@ -379,20 +403,40 @@ bus_selinux_check (BusSELinuxID *sender_sid,
|
|||
*/
|
||||
dbus_bool_t
|
||||
bus_selinux_allows_acquire_service (DBusConnection *connection,
|
||||
BusSELinuxID *service_sid)
|
||||
BusSELinuxID *service_sid,
|
||||
const char *service_name)
|
||||
{
|
||||
#ifdef HAVE_SELINUX
|
||||
BusSELinuxID *connection_sid;
|
||||
unsigned long spid;
|
||||
DBusString *auxdata;
|
||||
|
||||
if (!selinux_enabled)
|
||||
return TRUE;
|
||||
|
||||
connection_sid = bus_connection_get_selinux_id (connection);
|
||||
if (!dbus_connection_get_unix_process_id (connection, &spid))
|
||||
spid = 0;
|
||||
|
||||
auxdata = dbus_new0 (DBusString, 1);
|
||||
if (auxdata)
|
||||
{
|
||||
if (!_dbus_string_init (auxdata))
|
||||
{
|
||||
dbus_free (auxdata);
|
||||
auxdata = NULL;
|
||||
}
|
||||
else if (_dbus_string_append (auxdata, "service="))
|
||||
_dbus_string_append (auxdata, service_name);
|
||||
}
|
||||
|
||||
return bus_selinux_check (connection_sid,
|
||||
service_sid,
|
||||
SECCLASS_DBUS,
|
||||
DBUS__ACQUIRE_SVC);
|
||||
service_sid,
|
||||
SECCLASS_DBUS,
|
||||
DBUS__ACQUIRE_SVC,
|
||||
spid,
|
||||
0,
|
||||
auxdata);
|
||||
#else
|
||||
return TRUE;
|
||||
#endif /* HAVE_SELINUX */
|
||||
|
|
@ -410,15 +454,50 @@ bus_selinux_allows_acquire_service (DBusConnection *connection,
|
|||
*/
|
||||
dbus_bool_t
|
||||
bus_selinux_allows_send (DBusConnection *sender,
|
||||
DBusConnection *proposed_recipient)
|
||||
DBusConnection *proposed_recipient,
|
||||
const char *msgtype,
|
||||
const char *interface,
|
||||
const char *member,
|
||||
const char *error_name,
|
||||
const char *destination)
|
||||
{
|
||||
#ifdef HAVE_SELINUX
|
||||
BusSELinuxID *recipient_sid;
|
||||
BusSELinuxID *sender_sid;
|
||||
unsigned long spid, tpid;
|
||||
DBusString *auxdata;
|
||||
|
||||
if (!selinux_enabled)
|
||||
return TRUE;
|
||||
|
||||
if (!dbus_connection_get_unix_process_id (sender, &spid))
|
||||
spid = 0;
|
||||
if (!dbus_connection_get_unix_process_id (proposed_recipient, &tpid))
|
||||
tpid = 0;
|
||||
|
||||
auxdata = dbus_new0 (DBusString, 1);
|
||||
if (auxdata)
|
||||
{
|
||||
if (!_dbus_string_init (auxdata))
|
||||
{
|
||||
dbus_free (auxdata);
|
||||
auxdata = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_dbus_string_append (auxdata, "msgtype="))
|
||||
_dbus_string_append (auxdata, msgtype);
|
||||
if (interface && _dbus_string_append (auxdata, " interface="))
|
||||
_dbus_string_append (auxdata, interface);
|
||||
if (member && _dbus_string_append (auxdata, " member="))
|
||||
_dbus_string_append (auxdata, member);
|
||||
if (error_name && _dbus_string_append (auxdata, " error_name="))
|
||||
_dbus_string_append (auxdata, error_name);
|
||||
if (destination && _dbus_string_append (auxdata, " dest="))
|
||||
_dbus_string_append (auxdata, destination);
|
||||
}
|
||||
}
|
||||
|
||||
sender_sid = bus_connection_get_selinux_id (sender);
|
||||
/* A NULL proposed_recipient means the bus itself. */
|
||||
if (proposed_recipient)
|
||||
|
|
@ -427,7 +506,8 @@ bus_selinux_allows_send (DBusConnection *sender,
|
|||
recipient_sid = BUS_SID_FROM_SELINUX (bus_sid);
|
||||
|
||||
return bus_selinux_check (sender_sid, recipient_sid,
|
||||
SECCLASS_DBUS, DBUS__SEND_MSG);
|
||||
SECCLASS_DBUS, DBUS__SEND_MSG,
|
||||
spid, tpid, auxdata);
|
||||
#else
|
||||
return TRUE;
|
||||
#endif /* HAVE_SELINUX */
|
||||
|
|
|
|||
|
|
@ -47,11 +47,15 @@ const char* bus_selinux_get_policy_root (void);
|
|||
|
||||
|
||||
dbus_bool_t bus_selinux_allows_acquire_service (DBusConnection *connection,
|
||||
BusSELinuxID *service_sid);
|
||||
BusSELinuxID *service_sid,
|
||||
const char *service_name);
|
||||
dbus_bool_t bus_selinux_allows_send (DBusConnection *sender,
|
||||
DBusConnection *proposed_recipient);
|
||||
|
||||
|
||||
DBusConnection *proposed_recipient,
|
||||
const char *msgtype, /* Supplementary audit data */
|
||||
const char *interface,
|
||||
const char *member,
|
||||
const char *error_name,
|
||||
const char *destination);
|
||||
|
||||
BusSELinuxID* bus_selinux_init_connection_id (DBusConnection *connection,
|
||||
DBusError *error);
|
||||
|
|
|
|||
|
|
@ -310,7 +310,8 @@ bus_registry_acquire_service (BusRegistry *registry,
|
|||
sid = bus_selinux_id_table_lookup (registry->service_sid_table,
|
||||
service_name);
|
||||
|
||||
if (!bus_selinux_allows_acquire_service (connection, sid))
|
||||
if (!bus_selinux_allows_acquire_service (connection, sid,
|
||||
_dbus_string_get_const_data (service_name)))
|
||||
{
|
||||
dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
|
||||
"Connection \"%s\" is not allowed to own the service \"%s\" due "
|
||||
|
|
|
|||
|
|
@ -5778,6 +5778,37 @@ dbus_message_type_from_string (const char *type_str)
|
|||
return DBUS_MESSAGE_TYPE_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to convert a D-BUS message type into a
|
||||
* machine-readable string (not translated).
|
||||
*
|
||||
* @code
|
||||
* DBUS_MESSAGE_TYPE_METHOD_CALL -> "method_call"
|
||||
* DBUS_MESSAGE_TYPE_METHOD_RETURN -> "method_return"
|
||||
* DBUS_MESSAGE_TYPE_SIGNAL -> "signal"
|
||||
* DBUS_MESSAGE_TYPE_ERROR -> "error"
|
||||
* DBUS_MESSAGE_TYPE_INVALID -> "invalid"
|
||||
* @endcode
|
||||
*
|
||||
*/
|
||||
const char *
|
||||
dbus_message_type_to_string (int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DBUS_MESSAGE_TYPE_METHOD_CALL:
|
||||
return "method_call";
|
||||
case DBUS_MESSAGE_TYPE_METHOD_RETURN:
|
||||
return "method_return";
|
||||
case DBUS_MESSAGE_TYPE_SIGNAL:
|
||||
return "signal";
|
||||
case DBUS_MESSAGE_TYPE_ERROR:
|
||||
return "error";
|
||||
default:
|
||||
return "invalid";
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
#include "dbus-test.h"
|
||||
|
|
|
|||
|
|
@ -295,6 +295,7 @@ void* dbus_message_get_data (DBusMessage *message,
|
|||
dbus_int32_t slot);
|
||||
|
||||
int dbus_message_type_from_string (const char *type_str);
|
||||
const char * dbus_message_type_to_string (int type);
|
||||
|
||||
DBUS_END_DECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -756,6 +756,30 @@ _dbus_string_copy_data_len (const DBusString *str,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the contents of a DBusString into a different
|
||||
* buffer. The resulting buffer will be nul-terminated.
|
||||
*
|
||||
* @param str a string
|
||||
* @param buffer a C buffer to copy data to
|
||||
* @param len maximum length of C buffer
|
||||
*/
|
||||
void
|
||||
_dbus_string_copy_to_buffer (const DBusString *str,
|
||||
char *buffer,
|
||||
int avail_len)
|
||||
{
|
||||
int copy_len;
|
||||
DBUS_CONST_STRING_PREAMBLE (str);
|
||||
|
||||
_dbus_assert (avail_len >= 0);
|
||||
|
||||
copy_len = MIN (avail_len, real->len+1);
|
||||
memcpy (buffer, real->str, copy_len);
|
||||
if (avail_len > 0 && avail_len == copy_len)
|
||||
buffer[avail_len-1] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the length of a string (not including nul termination).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -88,6 +88,9 @@ dbus_bool_t _dbus_string_copy_data_len (const DBusString *str,
|
|||
char **data_return,
|
||||
int start,
|
||||
int len);
|
||||
void _dbus_string_copy_to_buffer (const DBusString *str,
|
||||
char *buffer,
|
||||
int len);
|
||||
int _dbus_string_get_length (const DBusString *str);
|
||||
dbus_bool_t _dbus_string_lengthen (DBusString *str,
|
||||
int additional_length);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue