Skip to content

Instantly share code, notes, and snippets.

@ItsProfessional
Last active December 12, 2024 16:30
Show Gist options
  • Save ItsProfessional/63300b874cb317d14924ebd971c49c04 to your computer and use it in GitHub Desktop.
Save ItsProfessional/63300b874cb317d14924ebd971c49c04 to your computer and use it in GitHub Desktop.
Pkexec patch to pass-through ALL environment variables as-is (warning: this is insecure and introduces vulnerabilities via environment variables like LD_PRELOAD and LD_LIBRARY_PATH)
diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c
index 65c1309..51329c9 100644
--- a/src/programs/pkexec.c
+++ b/src/programs/pkexec.c
@@ -339,99 +339,6 @@ find_action_for_path (PolkitAuthority *authority,
return action_id;
}
-/* ---------------------------------------------------------------------------------------------------- */
-
-static gboolean
-is_valid_shell (const gchar *shell)
-{
- gboolean ret;
- gchar *contents;
- gchar **shells;
- GError *error;
- guint n;
-
- ret = FALSE;
-
- contents = NULL;
- shells = NULL;
-
- error = NULL;
- if (!g_file_get_contents ("/etc/shells",
- &contents,
- NULL, /* gsize *length */
- &error))
- {
- g_printerr ("Error getting contents of /etc/shells: %s\n", error->message);
- g_error_free (error);
- goto out;
- }
-
- shells = g_strsplit (contents, "\n", 0);
- for (n = 0; shells != NULL && shells[n] != NULL; n++)
- {
- if (shells[n][0] == '/' && g_strcmp0 (shell, shells[n]) == 0)
- {
- ret = TRUE;
- goto out;
- }
- }
-
- out:
- g_free (contents);
- g_strfreev (shells);
- return ret;
-}
-
-static gboolean
-validate_environment_variable (const gchar *key,
- const gchar *value)
-{
- gboolean ret;
-
- /* Generally we bail if any environment variable value contains
- *
- * - '/' characters
- * - '%' characters
- * - '..' substrings
- */
-
- g_return_val_if_fail (key != NULL, FALSE);
- g_return_val_if_fail (value != NULL, FALSE);
-
- ret = FALSE;
-
- /* special case $SHELL */
- if (g_strcmp0 (key, "SHELL") == 0)
- {
- /* check if it's in /etc/shells */
- if (!is_valid_shell (value))
- {
- log_message (LOG_CRIT, TRUE,
- "The value for the SHELL variable was not found in the /etc/shells file");
- g_printerr ("\n"
- "This incident has been reported.\n");
- goto out;
- }
- }
- else if ((g_strcmp0 (key, "XAUTHORITY") != 0 && strstr (value, "/") != NULL) ||
- strstr (value, "%") != NULL ||
- strstr (value, "..") != NULL)
- {
- log_message (LOG_CRIT, TRUE,
- "The value for environment variable %s contains suspicious content",
- key);
- g_printerr ("\n"
- "This incident has been reported.\n");
- goto out;
- }
-
- ret = TRUE;
-
- out:
- return ret;
-}
-
-
/* ---------------------------------------------------------------------------------------------------- */
int
@@ -456,37 +363,7 @@ main (int argc, char *argv[])
struct passwd pwstruct;
gchar pwbuf[8192];
gchar *s;
- const gchar *environment_variables_to_save[] = {
- "SHELL",
- "LANG",
- "LINGUAS",
- "LANGUAGE",
- "LC_COLLATE",
- "LC_CTYPE",
- "LC_MESSAGES",
- "LC_MONETARY",
- "LC_NUMERIC",
- "LC_TIME",
- "LC_ALL",
- "TERM",
- "COLORTERM",
-
- /* By default we don't allow running X11 apps, as it does not work in the
- * general case. See
- *
- * https://bugs.freedesktop.org/show_bug.cgi?id=17970#c26
- *
- * and surrounding comments for a lot of discussion about this.
- *
- * However, it can be enabled for some selected and tested legacy programs
- * which previously used e. g. gksu, by setting the
- * org.freedesktop.policykit.exec.allow_gui annotation to a nonempty value.
- * See https://bugs.freedesktop.org/show_bug.cgi?id=38769 for details.
- */
- "DISPLAY",
- "XAUTHORITY",
- NULL
- };
+ gchar** environment_variables_to_save = g_listenv();
GPtrArray *saved_env;
gchar *opt_user;
pid_t pid_of_caller;
@@ -690,13 +567,6 @@ main (int argc, char *argv[])
if (value == NULL)
continue;
- /* To qualify for the paranoia goldstar - we validate the value of each
- * environment variable passed through - this is to attempt to avoid
- * exploits in (potentially broken) programs launched via pkexec(1).
- */
- if (!validate_environment_variable (key, value))
- goto out;
-
g_ptr_array_add (saved_env, g_strdup (key));
g_ptr_array_add (saved_env, g_strdup (value));
}
@@ -924,20 +794,6 @@ main (int argc, char *argv[])
goto out;
}
- /* Set PATH to a safe list */
- g_ptr_array_add (saved_env, g_strdup ("PATH"));
- if (pw->pw_uid != 0)
- s = g_strdup_printf ("/usr/bin:/bin:/usr/sbin:/sbin:%s/bin", pw->pw_dir);
- else
- s = g_strdup_printf ("/usr/sbin:/usr/bin:/sbin:/bin:%s/bin", pw->pw_dir);
- g_ptr_array_add (saved_env, s);
- g_ptr_array_add (saved_env, g_strdup ("LOGNAME"));
- g_ptr_array_add (saved_env, g_strdup (pw->pw_name));
- g_ptr_array_add (saved_env, g_strdup ("USER"));
- g_ptr_array_add (saved_env, g_strdup (pw->pw_name));
- g_ptr_array_add (saved_env, g_strdup ("HOME"));
- g_ptr_array_add (saved_env, g_strdup (pw->pw_dir));
-
s = g_strdup_printf ("%d", getuid ());
g_ptr_array_add (saved_env, g_strdup ("PKEXEC_UID"));
g_ptr_array_add (saved_env, s);
@@ -948,11 +804,6 @@ main (int argc, char *argv[])
const gchar *key = saved_env->pdata[n];
const gchar *value = saved_env->pdata[n + 1];
- /* Only set $DISPLAY and $XAUTHORITY when explicitly allowed in the .policy */
- if (!allow_gui &&
- (strcmp (key, "DISPLAY") == 0 || strcmp (key, "XAUTHORITY") == 0))
- continue;
-
if (!g_setenv (key, value, TRUE))
{
g_printerr ("Error setting environment variable %s to '%s': %s\n",
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment