This is a simplistic fix: it resolves all symlinks and /./ and /../
references. Thank God, POSIX has a function for that.
--
vda
diff -x '*.po' -d -urpN abrt.3/lib/utils/dump_dir.c abrt.4/lib/utils/dump_dir.c
--- abrt.3/lib/utils/dump_dir.c 2010-10-14 11:05:43.883114773 +0200
+++ abrt.4/lib/utils/dump_dir.c 2010-10-14 12:02:09.921365132 +0200
@@ -28,10 +28,6 @@
// Perhaps dd_opendir should do some sanity checking like
// "if there is no "uid" file in the directory, it's not a crash
dump",
// and fail.
-//
-// Locking is broken wrt "funny" directory names.
-// dd_opendir(dd, ".") will create "..lock" istead of proper
"../DIRNAME.lock"
-// Similarly for dd_opendir(dd, "DIRNAME/."), dd_opendir(dd, "..")
etc.
static char *load_text_file(const char *path);
@@ -45,14 +41,6 @@ static bool isdigit_str(const char *str)
return true;
}
-static char* rm_trailing_slashes(const char *dir)
-{
- unsigned len = strlen(dir);
- while (len != 0 && dir[len-1] == '/')
- len--;
- return xstrndup(dir, len);
-}
-
static bool exist_file_dir(const char *path)
{
struct stat buf;
@@ -171,12 +159,27 @@ void dd_close(struct dump_dir *dd)
free(dd);
}
+#if 0 /* UNUSED */
+static char* rm_trailing_slashes(const char *dir)
+{
+ unsigned len = strlen(dir);
+ while (len != 0 && dir[len-1] == '/')
+ len--;
+ return xstrndup(dir, len);
+}
+#endif
+
int dd_opendir(struct dump_dir *dd, const char *dir, int flags)
{
if (dd->locked)
error_msg_and_die("dump_dir is already opened"); /* bug */
- dd->dd_dir = rm_trailing_slashes(dir);
+ /* Used to use rm_trailing_slashes(dir) here, but with dir = "."
+ * or "..", or if the last component is a symlink,
+ * then lock file is created in the wrong place.
+ * IOW: this breaks locking.
+ */
+ dd->dd_dir = realpath(dir, NULL);
dd_lock(dd);
@@ -222,7 +225,7 @@ int dd_create(struct dump_dir *dd, const
if (dd->locked)
error_msg_and_die("dump_dir is already opened"); /* bug */
- dd->dd_dir = rm_trailing_slashes(dir);
+ dd->dd_dir = realpath(dir, NULL);
dd_lock(dd);