From 6e98e56b7e3ccfc2e85330daec03485a2ab7f10b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomi=20Lepp=C3=A4nen?= Date: Tue, 31 Dec 2019 16:50:25 +0200 Subject: [PATCH] [dbus] Check sender uid for mode restrictions. Fixes JB#48441 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/com.meego.usb_moded.xml | 3 +++ src/usb_moded-dbus.c | 35 +++++++++++++++++++++++++++++++++-- src/usb_moded-dbus.h | 35 ++++++++++++++++++----------------- 3 files changed, 54 insertions(+), 19 deletions(-) diff --git a/src/com.meego.usb_moded.xml b/src/com.meego.usb_moded.xml index 32d04e4..513e375 100644 --- a/src/com.meego.usb_moded.xml +++ b/src/com.meego.usb_moded.xml @@ -36,6 +36,9 @@ + + + diff --git a/src/usb_moded-dbus.c b/src/usb_moded-dbus.c index e17dce4..24c27b7 100644 --- a/src/usb_moded-dbus.c +++ b/src/usb_moded-dbus.c @@ -163,6 +163,9 @@ static const char umdbus_introspect_usbmoded[] = " \n" " \n" " \n" +" \n" +" \n" +" \n" " \n" " \n" " \n" @@ -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; @@ -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); @@ -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 */ @@ -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 */ @@ -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); @@ -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; } @@ -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; } diff --git a/src/usb_moded-dbus.h b/src/usb_moded-dbus.h index d03e37e..0e0fd8c 100644 --- a/src/usb_moded-dbus.h +++ b/src/usb_moded-dbus.h @@ -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.