From: Mike Gorse Date: Tue, 8 Mar 2011 21:45:09 +0000 (-0600) Subject: Fix accessibility of root apps on Linux X-Git-Tag: AT_SPI2_ATK_2_12_0~266 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git;a=commitdiff_plain;h=3e6cf48cd7a24303324f10039b63bd916a8aa49e;ds=sidebyside Fix accessibility of root apps on Linux For an application running as root, check the uid of its parent, and, if necessary, the parent's parent and so on, to find the user that initially launched the application, and permit dbus connections from this uid. Note that this will likely only work under Linux. --- diff --git a/atk-adaptor/bridge.c b/atk-adaptor/bridge.c index da844d8..940d244 100644 --- a/atk-adaptor/bridge.c +++ b/atk-adaptor/bridge.c @@ -22,6 +22,7 @@ * Boston, MA 02111-1307, USA. */ +#define _GNU_SOURCE #include "config.h" #include "dbus/dbus-glib-lowlevel.h" @@ -509,11 +510,54 @@ install_plug_hooks () socket_class->embed = socket_embed_hook; } +static uint +get_ancestral_uid (uint pid) +{ + FILE *fp; + char buf [80]; + int ppid = 0; + int uid = 0; + gboolean got_ppid = 0; + gboolean got_uid = 0; + + sprintf (buf, "/proc/%d/status", pid); + fp = fopen (buf, "r"); + if (!fp) + return 0; + while ((!got_ppid || !got_uid) && fgets (buf, sizeof (buf), fp)) + { + if (sscanf (buf, "PPid:\t%d", &ppid) == 1) + got_ppid = TRUE; + else if (sscanf (buf, "Uid:\t%d", &uid) == 1) + got_uid = TRUE; + } + fclose (fp); + + if (!got_ppid || !got_uid) + return 0; + if (uid != 0) + return uid; + if (ppid == 0 || ppid == 1) + return 0; + return get_ancestral_uid (ppid); +} + +static dbus_bool_t +user_check (DBusConnection *bus, unsigned long uid) +{ + if (uid == getuid () || uid == geteuid ()) + return TRUE; + if (getuid () == 0) + return get_ancestral_uid (getpid ()) == uid; + return FALSE; +} + static void new_connection_cb (DBusServer *server, DBusConnection *con, void *data) { GList *new_list; + dbus_connection_set_unix_user_function (con, user_check, NULL, NULL); dbus_connection_ref(con); dbus_connection_setup_with_g_main(con, NULL); droute_intercept_dbus (con);