Skip to content

Commit

Permalink
[dbus] Check sender uid for mode restrictions. Fixes JB#48441
Browse files Browse the repository at this point in the history
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 37 additions and 2 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
1 change: 1 addition & 0 deletions src/usb_moded-dbus.h
Expand Up @@ -75,6 +75,7 @@
# 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 */

/**
Expand Down

0 comments on commit 6e98e56

Please sign in to comment.