]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
epgdb: Resolve symlinks before using file location
authorDavid Kalnischkies <david@kalnischkies.de>
Mon, 24 Oct 2022 11:44:29 +0000 (13:44 +0200)
committerFlole998 <Flole998@users.noreply.github.com>
Sun, 20 Nov 2022 01:09:49 +0000 (02:09 +0100)
The new epgdb is written to a temporary file and later renamed to
override the old epgdb file atomically. If you diverted the epgdb
to a different place away from your usual configuration (e.g. for
space and/or disk usage reasons like on an OpenWrt router) this
leads to overriding the symlink with a real file defeating the point.

By applying realpath on the path first we can resolve any symlink
along the path, while not considering it a failure if the epgdb
file doesn't exist yet. If on the other hand the path up to the file
doesn't exist we default to the old way of just taking the path
verbatim and let them be created by hts_settings_makedirs as before.

Note that this relies on the paths being sized PATH_MAX, which as the
manpage notes is POSIX.1-2001 conform, but broken by design as PATH_MAX
can't be relied upon, but the entire codebase makes heavy use of PATH_MAX
and there is a pre-existing usage of realpath() in this way so lets
pretend its okay for now.

References: b23686a55323625b15d4f99fd7af55259fa21828

src/epgdb.c

index 9e79631eddd660816c938a7fe4fcce4476819be5..054f35d32efa0221eadcd48301a237fad1c34c2e 100644 (file)
@@ -302,7 +302,9 @@ static void epg_save_tsk_callback ( void *p, int dearmed )
   int fd, r;
 
   tvhinfo(LS_EPGDB, "save start");
-  hts_settings_buildpath(path, sizeof(path), "epgdb.v%d", EPG_DB_VERSION);
+  hts_settings_buildpath(tmppath, sizeof(path), "epgdb.v%d", EPG_DB_VERSION);
+  if (!realpath(tmppath, path))
+    strlcpy(path, tmppath, sizeof(path));
   snprintf(tmppath, sizeof(tmppath), "%s.tmp", path);
   if (hts_settings_makedirs(tmppath))
     fd = -1;