mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-05 02:58:01 +02:00
policy: Add max_fds, min_fds qualifiers for send, receive rules
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=101848 Reviewed-by: Thiago Macieira <thiago@kde.org> [smcv: Revert an incorrect comment change] Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
parent
f876edd342
commit
b22bdc39fd
6 changed files with 146 additions and 4 deletions
|
|
@ -1276,6 +1276,43 @@ start_busconfig_child (BusConfigParser *parser,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse an attribute named name, whose content is content, or NULL if
|
||||
* missing. It is meant to be a (long) integer between min and max inclusive.
|
||||
* If it is missing, use def as the default value (which does not
|
||||
* necessarily need to be between min and max).
|
||||
*/
|
||||
static dbus_bool_t
|
||||
parse_int_attribute (const char *name,
|
||||
const char *content,
|
||||
long min,
|
||||
long max,
|
||||
long def,
|
||||
long *value,
|
||||
DBusError *error)
|
||||
{
|
||||
DBusString parse_string;
|
||||
|
||||
*value = def;
|
||||
|
||||
if (content == NULL)
|
||||
return TRUE;
|
||||
|
||||
_dbus_string_init_const (&parse_string, content);
|
||||
|
||||
if (!_dbus_string_parse_int (&parse_string, 0, value, NULL) ||
|
||||
*value < min || *value > max)
|
||||
{
|
||||
dbus_set_error (error, DBUS_ERROR_FAILED,
|
||||
"Bad value \"%s\" for %s attribute, must be an "
|
||||
"integer in range %ld to %ld inclusive",
|
||||
content, name, min, max);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
append_rule_from_element (BusConfigParser *parser,
|
||||
const char *element_name,
|
||||
|
|
@ -1311,6 +1348,10 @@ append_rule_from_element (BusConfigParser *parser,
|
|||
|
||||
/* Group: message-matching modifiers that can go on send_ or receive_ */
|
||||
const char *eavesdrop;
|
||||
const char *max_fds_attr;
|
||||
long max_fds = DBUS_MAXIMUM_MESSAGE_UNIX_FDS;
|
||||
const char *min_fds_attr;
|
||||
long min_fds = 0;
|
||||
/* TRUE if any message-matching modifier is present */
|
||||
dbus_bool_t any_message_attribute;
|
||||
|
||||
|
|
@ -1340,6 +1381,8 @@ append_rule_from_element (BusConfigParser *parser,
|
|||
"receive_path", &receive_path,
|
||||
"receive_type", &receive_type,
|
||||
"eavesdrop", &eavesdrop,
|
||||
"max_fds", &max_fds_attr,
|
||||
"min_fds", &min_fds_attr,
|
||||
"send_requested_reply", &send_requested_reply,
|
||||
"receive_requested_reply", &receive_requested_reply,
|
||||
"own", &own,
|
||||
|
|
@ -1373,7 +1416,9 @@ append_rule_from_element (BusConfigParser *parser,
|
|||
(!any_send_attribute && eavesdrop != NULL));
|
||||
any_message_attribute = (any_send_attribute ||
|
||||
any_receive_attribute ||
|
||||
eavesdrop != NULL);
|
||||
eavesdrop != NULL ||
|
||||
max_fds_attr != NULL ||
|
||||
min_fds_attr != NULL);
|
||||
|
||||
if (!(any_send_attribute ||
|
||||
any_receive_attribute ||
|
||||
|
|
@ -1518,7 +1563,19 @@ append_rule_from_element (BusConfigParser *parser,
|
|||
"send_requested_reply", send_requested_reply);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Matching only messages with DBUS_MAXIMUM_MESSAGE_UNIX_FDS or fewer
|
||||
* fds is the same as matching all messages, so we always set a maximum,
|
||||
* but perhaps an unrealistically high one. */
|
||||
if (!parse_int_attribute ("max_fds", max_fds_attr,
|
||||
0, DBUS_MAXIMUM_MESSAGE_UNIX_FDS,
|
||||
DBUS_MAXIMUM_MESSAGE_UNIX_FDS, &max_fds,
|
||||
error) ||
|
||||
!parse_int_attribute ("min_fds", min_fds_attr,
|
||||
0, DBUS_MAXIMUM_MESSAGE_UNIX_FDS, 0, &min_fds,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
rule = bus_policy_rule_new (BUS_POLICY_RULE_SEND, allow);
|
||||
if (rule == NULL)
|
||||
goto nomem;
|
||||
|
|
@ -1550,6 +1607,9 @@ append_rule_from_element (BusConfigParser *parser,
|
|||
rule->d.send.member = _dbus_strdup (send_member);
|
||||
rule->d.send.error = _dbus_strdup (send_error);
|
||||
rule->d.send.destination = _dbus_strdup (send_destination);
|
||||
rule->d.send.max_fds = max_fds;
|
||||
rule->d.send.min_fds = min_fds;
|
||||
|
||||
if (send_path && rule->d.send.path == NULL)
|
||||
goto nomem;
|
||||
if (send_interface && rule->d.send.interface == NULL)
|
||||
|
|
@ -1611,7 +1671,16 @@ append_rule_from_element (BusConfigParser *parser,
|
|||
"receive_requested_reply", receive_requested_reply);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (!parse_int_attribute ("max_fds", max_fds_attr,
|
||||
0, DBUS_MAXIMUM_MESSAGE_UNIX_FDS,
|
||||
DBUS_MAXIMUM_MESSAGE_UNIX_FDS, &max_fds,
|
||||
error) ||
|
||||
!parse_int_attribute ("min_fds", min_fds_attr,
|
||||
0, DBUS_MAXIMUM_MESSAGE_UNIX_FDS, 0, &min_fds,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
rule = bus_policy_rule_new (BUS_POLICY_RULE_RECEIVE, allow);
|
||||
if (rule == NULL)
|
||||
goto nomem;
|
||||
|
|
@ -1628,6 +1697,8 @@ append_rule_from_element (BusConfigParser *parser,
|
|||
rule->d.receive.member = _dbus_strdup (receive_member);
|
||||
rule->d.receive.error = _dbus_strdup (receive_error);
|
||||
rule->d.receive.origin = _dbus_strdup (receive_sender);
|
||||
rule->d.receive.max_fds = max_fds;
|
||||
rule->d.receive.min_fds = min_fds;
|
||||
|
||||
if (receive_path && rule->d.receive.path == NULL)
|
||||
goto nomem;
|
||||
|
|
|
|||
32
bus/policy.c
32
bus/policy.c
|
|
@ -29,6 +29,7 @@
|
|||
#include <dbus/dbus-list.h>
|
||||
#include <dbus/dbus-hash.h>
|
||||
#include <dbus/dbus-internals.h>
|
||||
#include <dbus/dbus-message-internal.h>
|
||||
|
||||
BusPolicyRule*
|
||||
bus_policy_rule_new (BusPolicyRuleType type,
|
||||
|
|
@ -1063,6 +1064,20 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
|
|||
}
|
||||
}
|
||||
|
||||
if (rule->d.send.min_fds > 0 ||
|
||||
rule->d.send.max_fds < DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
|
||||
{
|
||||
unsigned int n_fds = _dbus_message_get_n_unix_fds (message);
|
||||
|
||||
if (n_fds < rule->d.send.min_fds || n_fds > rule->d.send.max_fds)
|
||||
{
|
||||
_dbus_verbose (" (policy) skipping rule because message has %u fds "
|
||||
"and that is outside range [%u,%u]",
|
||||
n_fds, rule->d.send.min_fds, rule->d.send.max_fds);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use this rule */
|
||||
allowed = rule->allow;
|
||||
*log = rule->d.send.log;
|
||||
|
|
@ -1263,7 +1278,22 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (rule->d.receive.min_fds > 0 ||
|
||||
rule->d.receive.max_fds < DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
|
||||
{
|
||||
unsigned int n_fds = _dbus_message_get_n_unix_fds (message);
|
||||
|
||||
if (n_fds < rule->d.receive.min_fds || n_fds > rule->d.receive.max_fds)
|
||||
{
|
||||
_dbus_verbose (" (policy) skipping rule because message has %u fds "
|
||||
"and that is outside range [%u,%u]",
|
||||
n_fds, rule->d.receive.min_fds,
|
||||
rule->d.receive.max_fds);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use this rule */
|
||||
allowed = rule->allow;
|
||||
(*toggles)++;
|
||||
|
|
|
|||
|
|
@ -70,6 +70,8 @@ struct BusPolicyRule
|
|||
char *member;
|
||||
char *error;
|
||||
char *destination;
|
||||
unsigned int max_fds;
|
||||
unsigned int min_fds;
|
||||
unsigned int eavesdrop : 1;
|
||||
unsigned int requested_reply : 1;
|
||||
unsigned int log : 1;
|
||||
|
|
@ -86,6 +88,8 @@ struct BusPolicyRule
|
|||
char *member;
|
||||
char *error;
|
||||
char *origin;
|
||||
unsigned int max_fds;
|
||||
unsigned int min_fds;
|
||||
unsigned int eavesdrop : 1;
|
||||
unsigned int requested_reply : 1;
|
||||
} receive;
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ void _dbus_message_get_unix_fds (DBusMessage *message,
|
|||
const int **fds,
|
||||
unsigned *n_fds);
|
||||
|
||||
unsigned int _dbus_message_get_n_unix_fds (DBusMessage *message);
|
||||
void _dbus_message_lock (DBusMessage *message);
|
||||
void _dbus_message_unlock (DBusMessage *message);
|
||||
dbus_bool_t _dbus_message_add_counter (DBusMessage *message,
|
||||
|
|
|
|||
|
|
@ -45,6 +45,22 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets the number of unix fds attached to this message.
|
||||
*
|
||||
* @param message the message
|
||||
* @returns the number of file descriptors
|
||||
*/
|
||||
unsigned int
|
||||
_dbus_message_get_n_unix_fds (DBusMessage *message)
|
||||
{
|
||||
#ifdef HAVE_UNIX_FD_PASSING
|
||||
return message->n_unix_fds;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DBUS_ENABLE_EMBEDDED_TESTS
|
||||
/**
|
||||
* Reads arguments from a message iterator given a variable argument
|
||||
|
|
|
|||
|
|
@ -906,6 +906,13 @@ rules in the config file allow it).</para>
|
|||
recipient, and any broadcast message).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <literal>eavesdrop</literal>, <literal>min_fds</literal> and
|
||||
<literal>max_fds</literal> attributes are modifiers that can be applied
|
||||
to either <literal>send_</literal>* or <literal>receive_</literal>*
|
||||
rules, and are documented below.
|
||||
</para>
|
||||
|
||||
<para>send_destination and receive_sender rules mean that messages may not be
|
||||
sent to or received from the *owner* of the given name, not that
|
||||
they may not be sent *to that name*. That is, if a connection
|
||||
|
|
@ -969,6 +976,19 @@ the rule matches only when the reply was not
|
|||
requested. [send|receive]_requested_reply="true" indicates that the rule applies
|
||||
always, regardless of pending reply state.</para>
|
||||
|
||||
<para>
|
||||
The <literal>min_fds</literal> and <literal>max_fds</literal> attributes
|
||||
modify either <literal>send_</literal>* or <literal>receive_</literal>*
|
||||
rules. A rule with the <literal>min_fds</literal> attribute only matches
|
||||
messages if they have at least that many Unix file descriptors attached.
|
||||
Conversely, a rule with the <literal>max_fds</literal> attribute only
|
||||
matches messages if they have no more than that many file descriptors
|
||||
attached. In practice, rules with these attributes will most commonly
|
||||
take the form
|
||||
<literal><allow send_destination="…" max_fds="0"/></literal>,
|
||||
<literal><deny send_destination="…" min_fds="1"/></literal> or
|
||||
<literal><deny receive_sender="*" min_fds="1"/></literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Rules with the <literal>user</literal> or <literal>group</literal>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue