[glib/glib-2-74: 1/2] gtimezone: Reject weird /etc/localtime configurations
- From: Marco Trevisan <marcotrevi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/glib-2-74: 1/2] gtimezone: Reject weird /etc/localtime configurations
- Date: Tue, 18 Oct 2022 14:51:18 +0000 (UTC)
commit 1143a8a666037f4baac878418311035c426d26c8
Author: Ray Strode <rstrode redhat com>
Date: Fri Oct 14 13:18:50 2022 -0400
gtimezone: Reject weird /etc/localtime configurations
At the moment, glib assumes that if /etc/localtime is a symlink,
that it's a symlink to zoneinfo file.
Toolbx containers add an extra layer of indirection though, making
it a symlink to a symlink to a zoneinfo file.
This commit deals with the problem, by performing additional checks
on /etc/localtime and ignoring it if those check fail, falling back
instead to reading /etc/timezone.
glib/gtimezone.c | 57 +++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 44 insertions(+), 13 deletions(-)
---
diff --git a/glib/gtimezone.c b/glib/gtimezone.c
index ef0b628904..1e07cf6f0b 100644
--- a/glib/gtimezone.c
+++ b/glib/gtimezone.c
@@ -41,6 +41,10 @@
#include "gdate.h"
#include "genviron.h"
+#ifdef G_OS_UNIX
+#include "gstdio.h"
+#endif
+
#ifdef G_OS_WIN32
#define STRICT
@@ -532,16 +536,43 @@ zone_identifier_unix (void)
gchar *canonical_path = NULL;
GError *read_link_err = NULL;
const gchar *tzdir;
+ gboolean not_a_symlink_to_zoneinfo = FALSE;
+ struct stat file_status;
/* Resolve the actual timezone pointed to by /etc/localtime. */
resolved_identifier = g_file_read_link ("/etc/localtime", &read_link_err);
- if (resolved_identifier == NULL)
+
+ if (resolved_identifier != NULL)
+ {
+ if (g_lstat (resolved_identifier, &file_status) == 0)
+ {
+ if ((file_status.st_mode & S_IFMT) != S_IFREG)
+ {
+ /* Some systems (e.g. toolbox containers) make /etc/localtime be a symlink
+ * to a symlink.
+ *
+ * Rather than try to cope with that, just ignore /etc/localtime and use
+ * the fallback code to read timezone from /etc/timezone
+ */
+ g_clear_pointer (&resolved_identifier, g_free);
+ not_a_symlink_to_zoneinfo = TRUE;
+ }
+ }
+ else
+ {
+ g_clear_pointer (&resolved_identifier, g_free);
+ }
+ }
+ else
{
- gboolean not_a_symlink = g_error_matches (read_link_err,
- G_FILE_ERROR,
- G_FILE_ERROR_INVAL);
+ not_a_symlink_to_zoneinfo = g_error_matches (read_link_err,
+ G_FILE_ERROR,
+ G_FILE_ERROR_INVAL);
g_clear_error (&read_link_err);
+ }
+ if (resolved_identifier == NULL)
+ {
/* if /etc/localtime is not a symlink, try:
* - /var/db/zoneinfo : 'tzsetup' program on FreeBSD and
* DragonflyBSD stores the timezone chosen by the user there.
@@ -551,17 +582,17 @@ zone_identifier_unix (void)
* as a last-ditch effort to parse the TZ= setting from within
* /etc/default/init
*/
- if (not_a_symlink && (g_file_get_contents ("/var/db/zoneinfo",
- &resolved_identifier,
- NULL, NULL) ||
- g_file_get_contents ("/etc/timezone",
- &resolved_identifier,
- NULL, NULL)
+ if (not_a_symlink_to_zoneinfo && (g_file_get_contents ("/var/db/zoneinfo",
+ &resolved_identifier,
+ NULL, NULL) ||
+ g_file_get_contents ("/etc/timezone",
+ &resolved_identifier,
+ NULL, NULL)
#if defined(__sun) && defined(__SVR4)
- ||
- (resolved_identifier = zone_identifier_illumos ())
+ ||
+ (resolved_identifier = zone_identifier_illumos ())
#endif
- ))
+ ))
g_strchomp (resolved_identifier);
else
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]