|
Matej Habrnal |
fa1950 |
From 0bfb03ea68eb745172feccfc0f01b2ad13ff33bb Mon Sep 17 00:00:00 2001
|
|
Matej Habrnal |
fa1950 |
From: Jakub Filak <jfilak@redhat.com>
|
|
Matej Habrnal |
fa1950 |
Date: Fri, 24 Apr 2015 13:48:32 +0200
|
|
Matej Habrnal |
fa1950 |
Subject: [PATCH] dbus: avoid race-conditions in tests for dum dir availability
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
Florian Weimer <fweimer@redhat.com>
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
dump_dir_accessible_by_uid() is fundamentally insecure because it
|
|
Matej Habrnal |
fa1950 |
opens up a classic time-of-check-time-of-use race between this
|
|
Matej Habrnal |
fa1950 |
function and and dd_opendir().
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
Related: #1214745
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
Signed-off-by: Jakub Filak <jfilak@redhat.com>
|
|
Matej Habrnal |
fa1950 |
---
|
|
Matej Habrnal |
fa1950 |
src/dbus/abrt-dbus.c | 225 +++++++++++++++++++++-----------------------------
|
|
Matej Habrnal |
fa1950 |
src/lib/problem_api.c | 21 +++--
|
|
Matej Habrnal |
fa1950 |
2 files changed, 109 insertions(+), 137 deletions(-)
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
diff --git a/src/dbus/abrt-dbus.c b/src/dbus/abrt-dbus.c
|
|
Matej Habrnal |
fa1950 |
index 585fcd7..0f7ac2d 100644
|
|
Matej Habrnal |
fa1950 |
--- a/src/dbus/abrt-dbus.c
|
|
Matej Habrnal |
fa1950 |
+++ b/src/dbus/abrt-dbus.c
|
|
Matej Habrnal |
fa1950 |
@@ -201,6 +201,69 @@ static void return_InvalidProblemDir_error(GDBusMethodInvocation *invocation, co
|
|
Matej Habrnal |
fa1950 |
free(msg);
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
+enum {
|
|
Matej Habrnal |
fa1950 |
+ OPEN_FAIL_NO_REPLY = 1 << 0,
|
|
Matej Habrnal |
fa1950 |
+ OPEN_AUTH_ASK = 1 << 1,
|
|
Matej Habrnal |
fa1950 |
+ OPEN_AUTH_FAIL = 1 << 2,
|
|
Matej Habrnal |
fa1950 |
+};
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+static struct dump_dir *open_dump_directory(GDBusMethodInvocation *invocation,
|
|
Matej Habrnal |
fa1950 |
+ const gchar *caller, uid_t caller_uid, const char *problem_dir, int dd_flags, int flags)
|
|
Matej Habrnal |
fa1950 |
+{
|
|
Matej Habrnal |
fa1950 |
+ if (!allowed_problem_dir(problem_dir))
|
|
Matej Habrnal |
fa1950 |
+ {
|
|
Matej Habrnal |
fa1950 |
+ log("UID=%d attempted to access not allowed problem directory '%s'",
|
|
Matej Habrnal |
fa1950 |
+ caller_uid, problem_dir);
|
|
Matej Habrnal |
fa1950 |
+ if (!(flags & OPEN_FAIL_NO_REPLY))
|
|
Matej Habrnal |
fa1950 |
+ return_InvalidProblemDir_error(invocation, problem_dir);
|
|
Matej Habrnal |
fa1950 |
+ return NULL;
|
|
Matej Habrnal |
fa1950 |
+ }
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+ struct dump_dir *dd = dd_opendir(problem_dir, DD_OPEN_FD_ONLY);
|
|
Matej Habrnal |
fa1950 |
+ if (dd == NULL)
|
|
Matej Habrnal |
fa1950 |
+ {
|
|
Matej Habrnal |
fa1950 |
+ perror_msg("can't open problem directory '%s'", problem_dir);
|
|
Matej Habrnal |
fa1950 |
+ if (!(flags & OPEN_FAIL_NO_REPLY))
|
|
Matej Habrnal |
fa1950 |
+ return_InvalidProblemDir_error(invocation, problem_dir);
|
|
Matej Habrnal |
fa1950 |
+ return NULL;
|
|
Matej Habrnal |
fa1950 |
+ }
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+ if (!dd_accessible_by_uid(dd, caller_uid))
|
|
Matej Habrnal |
fa1950 |
+ {
|
|
Matej Habrnal |
fa1950 |
+ if (errno == ENOTDIR)
|
|
Matej Habrnal |
fa1950 |
+ {
|
|
Matej Habrnal |
fa1950 |
+ log_notice("Requested directory does not exist '%s'", problem_dir);
|
|
Matej Habrnal |
fa1950 |
+ if (!(flags & OPEN_FAIL_NO_REPLY))
|
|
Matej Habrnal |
fa1950 |
+ return_InvalidProblemDir_error(invocation, problem_dir);
|
|
Matej Habrnal |
fa1950 |
+ dd_close(dd);
|
|
Matej Habrnal |
fa1950 |
+ return NULL;
|
|
Matej Habrnal |
fa1950 |
+ }
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+ if ( !(flags & OPEN_AUTH_ASK)
|
|
Matej Habrnal |
fa1950 |
+ || polkit_check_authorization_dname(caller, "org.freedesktop.problems.getall") != PolkitYes)
|
|
Matej Habrnal |
fa1950 |
+ {
|
|
Matej Habrnal |
fa1950 |
+ log_notice("not authorized");
|
|
Matej Habrnal |
fa1950 |
+ if (!(flags & OPEN_FAIL_NO_REPLY))
|
|
Matej Habrnal |
fa1950 |
+ g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Matej Habrnal |
fa1950 |
+ "org.freedesktop.problems.AuthFailure",
|
|
Matej Habrnal |
fa1950 |
+ _("Not Authorized"));
|
|
Matej Habrnal |
fa1950 |
+ dd_close(dd);
|
|
Matej Habrnal |
fa1950 |
+ return NULL;
|
|
Matej Habrnal |
fa1950 |
+ }
|
|
Matej Habrnal |
fa1950 |
+ }
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+ dd = dd_fdopendir(dd, dd_flags);
|
|
Matej Habrnal |
fa1950 |
+ if (dd == NULL)
|
|
Matej Habrnal |
fa1950 |
+ {
|
|
Matej Habrnal |
fa1950 |
+ log_notice("Can't open the problem '%s' with flags %x0", problem_dir, dd_flags);
|
|
Matej Habrnal |
fa1950 |
+ if (!(flags & OPEN_FAIL_NO_REPLY))
|
|
Matej Habrnal |
fa1950 |
+ g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Matej Habrnal |
fa1950 |
+ "org.freedesktop.problems.Failure",
|
|
Matej Habrnal |
fa1950 |
+ _("Can't open the problem"));
|
|
Matej Habrnal |
fa1950 |
+ }
|
|
Matej Habrnal |
fa1950 |
+ return dd;
|
|
Matej Habrnal |
fa1950 |
+}
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
/*
|
|
Matej Habrnal |
fa1950 |
* Checks element's rights and does not open directory if element is protected.
|
|
Matej Habrnal |
fa1950 |
* Checks problem's rights and does not open directory if user hasn't got
|
|
Matej Habrnal |
fa1950 |
@@ -237,35 +300,8 @@ static struct dump_dir *open_directory_for_modification_of_element(
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
- if (!dump_dir_accessible_by_uid(problem_id, caller_uid))
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- if (errno == ENOTDIR)
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- log_notice("'%s' is not a valid problem directory", problem_id);
|
|
Matej Habrnal |
fa1950 |
- return_InvalidProblemDir_error(invocation, problem_id);
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
- else
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- log_notice("UID(%d) is not Authorized to access '%s'", caller_uid, problem_id);
|
|
Matej Habrnal |
fa1950 |
- g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Matej Habrnal |
fa1950 |
- "org.freedesktop.problems.AuthFailure",
|
|
Matej Habrnal |
fa1950 |
- _("Not Authorized"));
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
-
|
|
Matej Habrnal |
fa1950 |
- return NULL;
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
-
|
|
Matej Habrnal |
fa1950 |
- struct dump_dir *dd = dd_opendir(problem_id, /* flags : */ 0);
|
|
Matej Habrnal |
fa1950 |
- if (!dd)
|
|
Matej Habrnal |
fa1950 |
- { /* This should not happen because of the access check above */
|
|
Matej Habrnal |
fa1950 |
- log_notice("Can't access the problem '%s' for modification", problem_id);
|
|
Matej Habrnal |
fa1950 |
- g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Matej Habrnal |
fa1950 |
- "org.freedesktop.problems.Failure",
|
|
Matej Habrnal |
fa1950 |
- _("Can't access the problem for modification"));
|
|
Matej Habrnal |
fa1950 |
- return NULL;
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
-
|
|
Matej Habrnal |
fa1950 |
- return dd;
|
|
Matej Habrnal |
fa1950 |
+ return open_dump_directory(invocation, /*caller*/NULL, caller_uid, problem_id, /*Read/Write*/0,
|
|
Matej Habrnal |
fa1950 |
+ OPEN_AUTH_FAIL);
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
@@ -421,7 +457,15 @@ static void handle_method_call(GDBusConnection *connection,
|
|
Matej Habrnal |
fa1950 |
return;
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
- int ddstat = dump_dir_stat_for_uid(problem_dir, caller_uid);
|
|
Matej Habrnal |
fa1950 |
+ struct dump_dir *dd = dd_opendir(problem_dir, DD_OPEN_FD_ONLY);
|
|
Matej Habrnal |
fa1950 |
+ if (dd == NULL)
|
|
Matej Habrnal |
fa1950 |
+ {
|
|
Matej Habrnal |
fa1950 |
+ perror_msg("can't open problem directory '%s'", problem_dir);
|
|
Matej Habrnal |
fa1950 |
+ return_InvalidProblemDir_error(invocation, problem_dir);
|
|
Matej Habrnal |
fa1950 |
+ return;
|
|
Matej Habrnal |
fa1950 |
+ }
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+ int ddstat = dd_stat_for_uid(dd, caller_uid);
|
|
Matej Habrnal |
fa1950 |
if (ddstat < 0)
|
|
Matej Habrnal |
fa1950 |
{
|
|
Matej Habrnal |
fa1950 |
if (errno == ENOTDIR)
|
|
Matej Habrnal |
fa1950 |
@@ -435,6 +479,7 @@ static void handle_method_call(GDBusConnection *connection,
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
return_InvalidProblemDir_error(invocation, problem_dir);
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
+ dd_close(dd);
|
|
Matej Habrnal |
fa1950 |
return;
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
@@ -442,6 +487,7 @@ static void handle_method_call(GDBusConnection *connection,
|
|
Matej Habrnal |
fa1950 |
{ //caller seems to be in group with access to this dir, so no action needed
|
|
Matej Habrnal |
fa1950 |
log_notice("caller has access to the requested directory %s", problem_dir);
|
|
Matej Habrnal |
fa1950 |
g_dbus_method_invocation_return_value(invocation, NULL);
|
|
Matej Habrnal |
fa1950 |
+ dd_close(dd);
|
|
Matej Habrnal |
fa1950 |
return;
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
@@ -452,10 +498,11 @@ static void handle_method_call(GDBusConnection *connection,
|
|
Matej Habrnal |
fa1950 |
g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Matej Habrnal |
fa1950 |
"org.freedesktop.problems.AuthFailure",
|
|
Matej Habrnal |
fa1950 |
_("Not Authorized"));
|
|
Matej Habrnal |
fa1950 |
+ dd_close(dd);
|
|
Matej Habrnal |
fa1950 |
return;
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
- struct dump_dir *dd = dd_opendir(problem_dir, DD_OPEN_READONLY | DD_FAIL_QUIETLY_EACCES);
|
|
Matej Habrnal |
fa1950 |
+ dd = dd_fdopendir(dd, DD_OPEN_READONLY | DD_FAIL_QUIETLY_EACCES);
|
|
Matej Habrnal |
fa1950 |
if (!dd)
|
|
Matej Habrnal |
fa1950 |
{
|
|
Matej Habrnal |
fa1950 |
return_InvalidProblemDir_error(invocation, problem_dir);
|
|
Matej Habrnal |
fa1950 |
@@ -483,37 +530,10 @@ static void handle_method_call(GDBusConnection *connection,
|
|
Matej Habrnal |
fa1950 |
g_variant_get_child(parameters, 0, "&s", &problem_dir);
|
|
Matej Habrnal |
fa1950 |
log_notice("problem_dir:'%s'", problem_dir);
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
- if (!allowed_problem_dir(problem_dir))
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- return_InvalidProblemDir_error(invocation, problem_dir);
|
|
Matej Habrnal |
fa1950 |
- return;
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
-
|
|
Matej Habrnal |
fa1950 |
- if (!dump_dir_accessible_by_uid(problem_dir, caller_uid))
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- if (errno == ENOTDIR)
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- log_notice("Requested directory does not exist '%s'", problem_dir);
|
|
Matej Habrnal |
fa1950 |
- return_InvalidProblemDir_error(invocation, problem_dir);
|
|
Matej Habrnal |
fa1950 |
- return;
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
-
|
|
Matej Habrnal |
fa1950 |
- if (polkit_check_authorization_dname(caller, "org.freedesktop.problems.getall") != PolkitYes)
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- log_notice("not authorized");
|
|
Matej Habrnal |
fa1950 |
- g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Matej Habrnal |
fa1950 |
- "org.freedesktop.problems.AuthFailure",
|
|
Matej Habrnal |
fa1950 |
- _("Not Authorized"));
|
|
Matej Habrnal |
fa1950 |
- return;
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
-
|
|
Matej Habrnal |
fa1950 |
- struct dump_dir *dd = dd_opendir(problem_dir, DD_OPEN_READONLY | DD_FAIL_QUIETLY_EACCES);
|
|
Matej Habrnal |
fa1950 |
+ struct dump_dir *dd = open_dump_directory(invocation, caller, caller_uid,
|
|
Matej Habrnal |
fa1950 |
+ problem_dir, DD_OPEN_READONLY | DD_FAIL_QUIETLY_EACCES , OPEN_AUTH_ASK);
|
|
Matej Habrnal |
fa1950 |
if (!dd)
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- return_InvalidProblemDir_error(invocation, problem_dir);
|
|
Matej Habrnal |
fa1950 |
return;
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
/* Get 2nd param - vector of element names */
|
|
Matej Habrnal |
fa1950 |
GVariant *array = g_variant_get_child_value(parameters, 1);
|
|
Matej Habrnal |
fa1950 |
@@ -560,32 +580,10 @@ static void handle_method_call(GDBusConnection *connection,
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
g_variant_get(parameters, "(&s)", &problem_id);
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
- if (!allowed_problem_dir(problem_id))
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- return_InvalidProblemDir_error(invocation, problem_id);
|
|
Matej Habrnal |
fa1950 |
- return;
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
-
|
|
Matej Habrnal |
fa1950 |
- int ddstat = dump_dir_stat_for_uid(problem_id, caller_uid);
|
|
Matej Habrnal |
fa1950 |
- if ((ddstat & DD_STAT_ACCESSIBLE_BY_UID) == 0 &&
|
|
Matej Habrnal |
fa1950 |
- polkit_check_authorization_dname(caller, "org.freedesktop.problems.getall") != PolkitYes)
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- log_notice("Unauthorized access : '%s'", problem_id);
|
|
Matej Habrnal |
fa1950 |
- g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Matej Habrnal |
fa1950 |
- "org.freedesktop.problems.AuthFailure",
|
|
Matej Habrnal |
fa1950 |
- _("Not Authorized"));
|
|
Matej Habrnal |
fa1950 |
- return;
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
-
|
|
Matej Habrnal |
fa1950 |
- struct dump_dir *dd = dd_opendir(problem_id, DD_OPEN_READONLY);
|
|
Matej Habrnal |
fa1950 |
- if (dd == NULL)
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- log_notice("Can't access the problem '%s' for reading", problem_id);
|
|
Matej Habrnal |
fa1950 |
- g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Matej Habrnal |
fa1950 |
- "org.freedesktop.problems.Failure",
|
|
Matej Habrnal |
fa1950 |
- _("Can't access the problem for reading"));
|
|
Matej Habrnal |
fa1950 |
+ struct dump_dir *dd = open_dump_directory(invocation, caller, caller_uid,
|
|
Matej Habrnal |
fa1950 |
+ problem_id, DD_OPEN_READONLY, OPEN_AUTH_ASK);
|
|
Matej Habrnal |
fa1950 |
+ if (!dd)
|
|
Matej Habrnal |
fa1950 |
return;
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
problem_data_t *pd = create_problem_data_from_dump_dir(dd);
|
|
Matej Habrnal |
fa1950 |
dd_close(dd);
|
|
Matej Habrnal |
fa1950 |
@@ -629,12 +627,6 @@ static void handle_method_call(GDBusConnection *connection,
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
g_variant_get(parameters, "(&s&s&s)", &problem_id, &element, &value);
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
- if (!allowed_problem_dir(problem_id))
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- return_InvalidProblemDir_error(invocation, problem_id);
|
|
Matej Habrnal |
fa1950 |
- return;
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
-
|
|
Matej Habrnal |
fa1950 |
if (element == NULL || element[0] == '\0' || strlen(element) > 64)
|
|
Matej Habrnal |
fa1950 |
{
|
|
Matej Habrnal |
fa1950 |
log_notice("'%s' is not a valid element name of '%s'", element, problem_id);
|
|
Matej Habrnal |
fa1950 |
@@ -694,12 +686,6 @@ static void handle_method_call(GDBusConnection *connection,
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
g_variant_get(parameters, "(&s&s)", &problem_id, &element);
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
- if (!allowed_problem_dir(problem_id))
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- return_InvalidProblemDir_error(invocation, problem_id);
|
|
Matej Habrnal |
fa1950 |
- return;
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
-
|
|
Matej Habrnal |
fa1950 |
struct dump_dir *dd = open_directory_for_modification_of_element(
|
|
Matej Habrnal |
fa1950 |
invocation, caller_uid, problem_id, element);
|
|
Matej Habrnal |
fa1950 |
if (!dd)
|
|
Matej Habrnal |
fa1950 |
@@ -732,33 +718,10 @@ static void handle_method_call(GDBusConnection *connection,
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
g_variant_get(parameters, "(&s&s)", &problem_id, &element);
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
- if (!allowed_problem_dir(problem_id))
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- return_InvalidProblemDir_error(invocation, problem_id);
|
|
Matej Habrnal |
fa1950 |
- return;
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
-
|
|
Matej Habrnal |
fa1950 |
- struct dump_dir *dd = dd_opendir(problem_id, DD_OPEN_READONLY);
|
|
Matej Habrnal |
fa1950 |
+ struct dump_dir *dd = open_dump_directory(invocation, caller, caller_uid,
|
|
Matej Habrnal |
fa1950 |
+ problem_id, DD_OPEN_READONLY, OPEN_AUTH_ASK);
|
|
Matej Habrnal |
fa1950 |
if (!dd)
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- log_notice("Can't access the problem '%s'", problem_id);
|
|
Matej Habrnal |
fa1950 |
- g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Matej Habrnal |
fa1950 |
- "org.freedesktop.problems.Failure",
|
|
Matej Habrnal |
fa1950 |
- _("Can't access the problem"));
|
|
Matej Habrnal |
fa1950 |
- return;
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
-
|
|
Matej Habrnal |
fa1950 |
- int ddstat = dump_dir_stat_for_uid(problem_id, caller_uid);
|
|
Matej Habrnal |
fa1950 |
- if ((ddstat & DD_STAT_ACCESSIBLE_BY_UID) == 0 &&
|
|
Matej Habrnal |
fa1950 |
- polkit_check_authorization_dname(caller, "org.freedesktop.problems.getall") != PolkitYes)
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- dd_close(dd);
|
|
Matej Habrnal |
fa1950 |
- log_notice("Unauthorized access : '%s'", problem_id);
|
|
Matej Habrnal |
fa1950 |
- g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Matej Habrnal |
fa1950 |
- "org.freedesktop.problems.AuthFailure",
|
|
Matej Habrnal |
fa1950 |
- _("Not Authorized"));
|
|
Matej Habrnal |
fa1950 |
return;
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
int ret = dd_exist(dd, element);
|
|
Matej Habrnal |
fa1950 |
dd_close(dd);
|
|
Matej Habrnal |
fa1950 |
@@ -793,20 +756,18 @@ static void handle_method_call(GDBusConnection *connection,
|
|
Matej Habrnal |
fa1950 |
for (GList *l = problem_dirs; l; l = l->next)
|
|
Matej Habrnal |
fa1950 |
{
|
|
Matej Habrnal |
fa1950 |
const char *dir_name = (const char*)l->data;
|
|
Matej Habrnal |
fa1950 |
- if (!dump_dir_accessible_by_uid(dir_name, caller_uid))
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+ struct dump_dir *dd = open_dump_directory(invocation, caller, caller_uid,
|
|
Matej Habrnal |
fa1950 |
+ dir_name, /*Read/Write*/0, OPEN_FAIL_NO_REPLY | OPEN_AUTH_ASK);
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+ if (dd)
|
|
Matej Habrnal |
fa1950 |
{
|
|
Matej Habrnal |
fa1950 |
- if (errno == ENOTDIR)
|
|
Matej Habrnal |
fa1950 |
+ if (dd_delete(dd) != 0)
|
|
Matej Habrnal |
fa1950 |
{
|
|
Matej Habrnal |
fa1950 |
- log_notice("Requested directory does not exist '%s'", dir_name);
|
|
Matej Habrnal |
fa1950 |
- continue;
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
-
|
|
Matej Habrnal |
fa1950 |
- if (polkit_check_authorization_dname(caller, "org.freedesktop.problems.getall") != PolkitYes)
|
|
Matej Habrnal |
fa1950 |
- { // if user didn't provide correct credentials, just move to the next dir
|
|
Matej Habrnal |
fa1950 |
- continue;
|
|
Matej Habrnal |
fa1950 |
+ error_msg("Failed to delete problem directory '%s'", dir_name);
|
|
Matej Habrnal |
fa1950 |
+ dd_close(dd);
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
- delete_dump_dir(dir_name);
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
g_dbus_method_invocation_return_value(invocation, NULL);
|
|
Matej Habrnal |
fa1950 |
diff --git a/src/lib/problem_api.c b/src/lib/problem_api.c
|
|
Matej Habrnal |
fa1950 |
index 86222cf..96a49fc 100644
|
|
Matej Habrnal |
fa1950 |
--- a/src/lib/problem_api.c
|
|
Matej Habrnal |
fa1950 |
+++ b/src/lib/problem_api.c
|
|
Matej Habrnal |
fa1950 |
@@ -46,7 +46,17 @@ int for_each_problem_in_dir(const char *path,
|
|
Matej Habrnal |
fa1950 |
continue; /* skip "." and ".." */
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
char *full_name = concat_path_file(path, dent->d_name);
|
|
Matej Habrnal |
fa1950 |
- if (caller_uid == -1 || dump_dir_accessible_by_uid(full_name, caller_uid))
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+ struct dump_dir *dd = dd_opendir(full_name, DD_OPEN_FD_ONLY
|
|
Matej Habrnal |
fa1950 |
+ | DD_FAIL_QUIETLY_ENOENT
|
|
Matej Habrnal |
fa1950 |
+ | DD_FAIL_QUIETLY_EACCES);
|
|
Matej Habrnal |
fa1950 |
+ if (dd == NULL)
|
|
Matej Habrnal |
fa1950 |
+ {
|
|
Matej Habrnal |
fa1950 |
+ VERB2 perror_msg("can't open problem directory '%s'", full_name);
|
|
Matej Habrnal |
fa1950 |
+ continue;
|
|
Matej Habrnal |
fa1950 |
+ }
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+ if (caller_uid == -1 || dd_accessible_by_uid(dd, caller_uid))
|
|
Matej Habrnal |
fa1950 |
{
|
|
Matej Habrnal |
fa1950 |
/* Silently ignore *any* errors, not only EACCES.
|
|
Matej Habrnal |
fa1950 |
* We saw "lock file is locked by process PID" error
|
|
Matej Habrnal |
fa1950 |
@@ -55,14 +65,15 @@ int for_each_problem_in_dir(const char *path,
|
|
Matej Habrnal |
fa1950 |
int sv_logmode = logmode;
|
|
Matej Habrnal |
fa1950 |
/* Silently ignore errors only in the silent log level. */
|
|
Matej Habrnal |
fa1950 |
logmode = g_verbose == 0 ? 0: sv_logmode;
|
|
Matej Habrnal |
fa1950 |
- struct dump_dir *dd = dd_opendir(full_name, DD_OPEN_READONLY | DD_FAIL_QUIETLY_EACCES | DD_DONT_WAIT_FOR_LOCK);
|
|
Matej Habrnal |
fa1950 |
+ dd = dd_fdopendir(dd, DD_OPEN_READONLY | DD_DONT_WAIT_FOR_LOCK);
|
|
Matej Habrnal |
fa1950 |
logmode = sv_logmode;
|
|
Matej Habrnal |
fa1950 |
if (dd)
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
brk = callback ? callback(dd, arg) : 0;
|
|
Matej Habrnal |
fa1950 |
- dd_close(dd);
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+ if (dd)
|
|
Matej Habrnal |
fa1950 |
+ dd_close(dd);
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
free(full_name);
|
|
Matej Habrnal |
fa1950 |
if (brk)
|
|
Matej Habrnal |
fa1950 |
break;
|
|
Matej Habrnal |
fa1950 |
--
|
|
Matej Habrnal |
fa1950 |
2.1.0
|
|
Matej Habrnal |
fa1950 |
|