Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[dbus] Check sender uid for mode restrictions. Fixes JB#48441
Check sender uid to deny access for modes that are restricted. Prevent
non-owner users from hiding or unhiding modes. Add
get_allowed_modes_for_user method that lists only those methods that
user may choose.

Set last seen user based on uid that has called
get_allowed_modes_for_user last. This is not a perfect solution by any
means since it can be easily confused by calling it from command line as
root but generally no user other than the active one should call it.
Later when there is a proper way to get the active user this can be
improved.

Signed-off-by: Tomi Leppänen <tomi.leppanen@jolla.com>
  • Loading branch information
Tomin1 committed Jan 16, 2020
1 parent 8abafa0 commit 6e98e56
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 19 deletions.
3 changes: 3 additions & 0 deletions src/com.meego.usb_moded.xml
Expand Up @@ -36,6 +36,9 @@
<method name="get_available_modes">
<arg name="modes" type="s" direction="out"/>
</method>
<method name="get_available_modes_for_user">
<arg name="modes" type="s" direction="out"/>
</method>
<method name="hide_mode">
<arg name="mode" type="s" direction="in"/>
<arg name="mode" type="s" direction="out"/>
Expand Down
35 changes: 33 additions & 2 deletions src/usb_moded-dbus.c
Expand Up @@ -163,6 +163,9 @@ static const char umdbus_introspect_usbmoded[] =
" <method name=\"" USB_MODE_AVAILABLE_MODES_GET "\">\n"
" <arg name=\"modes\" type=\"s\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"" USB_MODE_AVAILABLE_MODES_FOR_USER "\">\n"
" <arg name=\"modes\" type=\"s\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"" USB_MODE_HIDE "\">\n"
" <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"
" <arg name=\"mode\" type=\"s\" direction=\"out\"/>\n"
Expand Down Expand Up @@ -286,6 +289,7 @@ static DBusHandlerResult umdbus_msg_handler(DBusConnection *const connection, DB
const char *member = dbus_message_get_member(msg);
const char *object = dbus_message_get_path(msg);
int type = dbus_message_get_type(msg);
const char *sender = dbus_message_get_sender(msg);

(void)user_data;

Expand Down Expand Up @@ -342,11 +346,17 @@ static DBusHandlerResult umdbus_msg_handler(DBusConnection *const connection, DB
const char *mode = control_get_external_mode();
char *use = 0;
DBusError err = DBUS_ERROR_INIT;
uid_t uid = umdbus_get_sender_uid(sender);

if(!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &use, DBUS_TYPE_INVALID)) {
log_err("parse error: %s: %s", err.name, err.message);
reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member);
}
else if( !usbmoded_is_mode_permitted(use, uid) ) {
/* Insufficient permissions */
log_warning("Mode '%s' is not allowed for uid %d", use, uid);
reply = dbus_message_new_error(msg, DBUS_ERROR_ACCESS_DENIED, member);
}
else if( control_get_cable_state() != CABLE_STATE_PC_CONNECTED ) {
/* Mode change makes no sence unless we have a PC connection */
log_warning("Mode '%s' requested while not connected to pc", use);
Expand Down Expand Up @@ -403,6 +413,11 @@ static DBusHandlerResult umdbus_msg_handler(DBusConnection *const connection, DB

if(!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID))
reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member);
#ifdef SAILFISH_ACCESS_CONTROL
/* do not let non-owner user hide modes */
else if (!sailfish_access_control_hasgroup(umdbus_get_sender_uid(sender), "sailfish-system"))
reply = dbus_message_new_error(msg, DBUS_ERROR_ACCESS_DENIED, member);
#endif
else
{
/* error checking is done when setting configuration */
Expand All @@ -424,6 +439,11 @@ static DBusHandlerResult umdbus_msg_handler(DBusConnection *const connection, DB

if(!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID))
reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member);
#ifdef SAILFISH_ACCESS_CONTROL
/* do not let non-owner user unhide modes */
else if (!sailfish_access_control_hasgroup(umdbus_get_sender_uid(sender), "sailfish-system"))
reply = dbus_message_new_error(msg, DBUS_ERROR_ACCESS_DENIED, member);
#endif
else
{
/* error checking is done when setting configuration */
Expand Down Expand Up @@ -516,6 +536,17 @@ static DBusHandlerResult umdbus_msg_handler(DBusConnection *const connection, DB
dbus_message_append_args (reply, DBUS_TYPE_STRING, (const char *) &mode_list, DBUS_TYPE_INVALID);
g_free(mode_list);
}
else if(!strcmp(member, USB_MODE_AVAILABLE_MODES_FOR_USER))
{
uid_t uid = umdbus_get_sender_uid(sender);
gchar *mode_list = common_get_mode_list(AVAILABLE_MODES_LIST, uid);

if((reply = dbus_message_new_method_return(msg)))
dbus_message_append_args (reply, DBUS_TYPE_STRING, (const char *) &mode_list, DBUS_TYPE_INVALID);
g_free(mode_list);

control_set_last_seen_user(uid);
}
else if(!strcmp(member, USB_MODE_RESCUE_OFF))
{
usbmoded_set_rescue_mode(false);
Expand Down Expand Up @@ -1366,7 +1397,7 @@ uid_t umdbus_get_sender_uid(const char *name)
/* Synchronous D-Bus call */
rsp = dbus_connection_send_with_reply_and_block(umdbus_connection, req, -1, &err);

if( rsp == NULL && dbus_error_is_set(&err) ) {
if( !rsp && dbus_error_is_set(&err) ) {
log_err("could not get sender pid for %s: %s: %s", name, err.name, err.message);
goto EXIT;
}
Expand All @@ -1380,7 +1411,7 @@ uid_t umdbus_get_sender_uid(const char *name)

snprintf(path, sizeof path, "/proc/%d", (int)pid);
memset(&st, 0, sizeof st);
if( stat(path, &st) == 0 ) {
if( stat(path, &st) != -1 ) {
uid = st.st_uid;
}

Expand Down
35 changes: 18 additions & 17 deletions src/usb_moded-dbus.h
Expand Up @@ -59,23 +59,24 @@
# define USB_MODE_TARGET_CONFIG_SIGNAL_NAME "sig_usb_taget_mode_config_ind"

/* supported methods */
# define USB_MODE_STATE_REQUEST "mode_request" /* returns the current mode */
# define USB_MODE_TARGET_STATE_GET "get_target_state" /* returns the target mode */
# define USB_MODE_RESCUE_OFF "rescue_off" /* turns rescue mode off so normal mode selection is restored */
# define USB_MODE_CONFIG_GET "get_config" /* returns the mode set in the config */
# define USB_MODE_LIST "get_modes" /* returns a comma-separated list of supported modes for ui's */
# define USB_MODE_HIDE "hide_mode" /* hide a mode */
# define USB_MODE_UNHIDE "unhide_mode" /* unhide a mode */
# define USB_MODE_HIDDEN_GET "get_hidden" /* return the hidden modes */
# define USB_MODE_STATE_SET "set_mode" /* set a mode (only works when connected) */
# define USB_MODE_CONFIG_SET "set_config" /* set the mode that needs to be activated in the config file */
# define USB_MODE_NETWORK_SET "net_config" /* set the network config in the config file */
# define USB_MODE_NETWORK_GET "get_net_config" /* get the network config from the config file */
# define USB_MODE_WHITELISTED_MODES_GET "get_whitelisted_modes" /* get the list of whitelisted modes */
# define USB_MODE_WHITELISTED_MODES_SET "set_whitelisted_modes" /* set the list of whitelisted modes */
# define USB_MODE_WHITELISTED_SET "set_whitelisted" /* sets whether an specific mode is in the whitelist */
# define USB_MODE_AVAILABLE_MODES_GET "get_available_modes" /* returns a comma separated list of modes which are currently available for selection */
# define USB_MODE_TARGET_CONFIG_GET "get_target_mode_config" /* returns current target mode configuration */
# define USB_MODE_STATE_REQUEST "mode_request" /* returns the current mode */
# define USB_MODE_TARGET_STATE_GET "get_target_state" /* returns the target mode */
# define USB_MODE_RESCUE_OFF "rescue_off" /* turns rescue mode off so normal mode selection is restored */
# define USB_MODE_CONFIG_GET "get_config" /* returns the mode set in the config */
# define USB_MODE_LIST "get_modes" /* returns a comma-separated list of supported modes for ui's */
# define USB_MODE_HIDE "hide_mode" /* hide a mode */
# define USB_MODE_UNHIDE "unhide_mode" /* unhide a mode */
# define USB_MODE_HIDDEN_GET "get_hidden" /* return the hidden modes */
# define USB_MODE_STATE_SET "set_mode" /* set a mode (only works when connected) */
# define USB_MODE_CONFIG_SET "set_config" /* set the mode that needs to be activated in the config file */
# define USB_MODE_NETWORK_SET "net_config" /* set the network config in the config file */
# define USB_MODE_NETWORK_GET "get_net_config" /* get the network config from the config file */
# define USB_MODE_WHITELISTED_MODES_GET "get_whitelisted_modes" /* get the list of whitelisted modes */
# define USB_MODE_WHITELISTED_MODES_SET "set_whitelisted_modes" /* set the list of whitelisted modes */
# define USB_MODE_WHITELISTED_SET "set_whitelisted" /* sets whether an specific mode is in the whitelist */
# define USB_MODE_AVAILABLE_MODES_GET "get_available_modes" /* returns a comma separated list of modes which are currently available for selection */
# define USB_MODE_AVAILABLE_MODES_FOR_USER "get_available_modes_for_user" /* returns a comma separated list of modes which are currently available and permitted for user to select */
# define USB_MODE_TARGET_CONFIG_GET "get_target_mode_config" /* returns current target mode configuration */

/**
* (Transient) states reported by "sig_usb_state_ind" that are not modes.
Expand Down

0 comments on commit 6e98e56

Please sign in to comment.