diff options
author | CoprDistGit <infra@openeuler.org> | 2024-07-15 09:01:07 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2024-07-15 09:01:07 +0000 |
commit | a69ae46c92199effdb2f0903e5416af42fd8ad69 (patch) | |
tree | 3700124d2256f460e93567fa6f3cfa6ec0d44787 /0001-Fix-timestamp-handling-in-MDTM.patch | |
parent | 908f6497506278a654656b2ed78b9cf08a892218 (diff) |
automatic import of vsftpdopeneuler24.03_LTSopeneuler22.03_LTS_SP4openeuler22.03_LTS_SP3openeuler20.03_LTS_SP4openeuler20.03
Diffstat (limited to '0001-Fix-timestamp-handling-in-MDTM.patch')
-rw-r--r-- | 0001-Fix-timestamp-handling-in-MDTM.patch | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/0001-Fix-timestamp-handling-in-MDTM.patch b/0001-Fix-timestamp-handling-in-MDTM.patch new file mode 100644 index 0000000..3975bf3 --- /dev/null +++ b/0001-Fix-timestamp-handling-in-MDTM.patch @@ -0,0 +1,151 @@ +From 6a4dc470e569df38b8a7ea09ee6aace3c73b7353 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= <olysonek@redhat.com> +Date: Wed, 28 Mar 2018 09:06:34 +0200 +Subject: [PATCH 1/2] Fix timestamp handling in MDTM + +There were two problems with the timestamp handling with MDTM: + +1. In vsf_sysutil_parse_time(), the `the_time.tm_isdst` attribute was + always set to 0, regardless of whether DST (daylight saving time) + is active on the given date or not. + + This made glibc shift the timestamp when DST was in fact active on + the given date, in an attempt to correct the discrepancy between + the given timestamp and the `tm_isdst` attribute. The shifting + produced incorrect results however. + + We fix this by setting `tm_isdst` to -1 to let glibc decide if DST + is active or not at the time of the timestamp. glibc won't touch + the timestamp then. + +2. vsftpd used to record the offset from UTC of the current timezone + in the global variable `s_timezone`. This variable was then + subtracted from the variable `the_time` in vsf_sysutil_setmodtime() + when the config option use_localtime=NO was set. This was done to + compensate for the fact that mktime(), used in + vsf_sysutil_parse_time(), expects a timestamp expressed as local + time, whereas vsftpd is dealing with universal time. + + However, this did not work in the case when the offset stored in + `s_timezone` did not match the timezone of the timestamp given to + mktime() - this happens when DST is active at the current time, but + DST is not active at the time of the timestamp, or vice versa. + + We fix this by subtracting the real timezone offset directly in + vsf_sysutil_parse_time(). + + Note that the `tm_gmtoff` attribute, used in this fix, is a + BSD/glic extension. However, using `tm_gmtoff` seems like the + simplest solution and we need to make this work only with glibc + anyway. + +The fix was tested in the following way. We checked that the timestamp +given to the MDTM command when setting modification time exactly +matches the timestamp received as response from MDTM when reading back +the modification time. Additionally, we checked that the modification +time was set correctly on the given file on disk. + +These two checks were performed under various conditions - all the +combinations of DST/non-DST system time, DST/non-DST modification +time, use_localtime=YES/NO. + +Note that (I think) this will still not work if the rules for when DST +is active change. For example, if DST is ever completely cancelled in +the Europe/Prague timezone, and vsftpd is dealing with a timestamp +from a time when DST was active, it will produce incorrect results. I +think we would need the full zone file to fix this, but the zone file +is hard to provide when we're chroot-ed. + +Resolves: rhbz#1567855 +--- + postlogin.c | 5 +++-- + sysutil.c | 17 ++++++++++------- + sysutil.h | 4 ++-- + 3 files changed, 15 insertions(+), 11 deletions(-) + +diff --git a/postlogin.c b/postlogin.c +index 7c749ef..8a3d9d2 100644 +--- a/postlogin.c ++++ b/postlogin.c +@@ -1788,7 +1788,8 @@ handle_mdtm(struct vsf_session* p_sess) + if (do_write != 0) + { + str_split_char(&p_sess->ftp_arg_str, &s_filename_str, ' '); +- modtime = vsf_sysutil_parse_time(str_getbuf(&p_sess->ftp_arg_str)); ++ modtime = vsf_sysutil_parse_time( ++ str_getbuf(&p_sess->ftp_arg_str), tunable_use_localtime); + str_copy(&p_sess->ftp_arg_str, &s_filename_str); + } + resolve_tilde(&p_sess->ftp_arg_str, p_sess); +@@ -1809,7 +1810,7 @@ handle_mdtm(struct vsf_session* p_sess) + else + { + retval = vsf_sysutil_setmodtime( +- str_getbuf(&p_sess->ftp_arg_str), modtime, tunable_use_localtime); ++ str_getbuf(&p_sess->ftp_arg_str), modtime); + if (retval != 0) + { + vsf_cmdio_write(p_sess, FTP_FILEFAIL, +diff --git a/sysutil.c b/sysutil.c +index e847650..66d4c5e 100644 +--- a/sysutil.c ++++ b/sysutil.c +@@ -2819,11 +2819,13 @@ vsf_sysutil_syslog(const char* p_text, int severe) + } + + long +-vsf_sysutil_parse_time(const char* p_text) ++vsf_sysutil_parse_time(const char* p_text, int is_localtime) + { ++ long res; + struct tm the_time; + unsigned int len = vsf_sysutil_strlen(p_text); + vsf_sysutil_memclr(&the_time, sizeof(the_time)); ++ the_time.tm_isdst = -1; + if (len >= 8) + { + char yr[5]; +@@ -2848,17 +2850,18 @@ vsf_sysutil_parse_time(const char* p_text) + the_time.tm_min = vsf_sysutil_atoi(mins); + the_time.tm_sec = vsf_sysutil_atoi(sec); + } +- return mktime(&the_time); ++ res = mktime(&the_time); ++ if (!is_localtime) ++ { ++ res += the_time.tm_gmtoff; ++ } ++ return res; + } + + int +-vsf_sysutil_setmodtime(const char* p_file, long the_time, int is_localtime) ++vsf_sysutil_setmodtime(const char* p_file, long the_time) + { + struct utimbuf new_times; +- if (!is_localtime) +- { +- the_time -= s_timezone; +- } + vsf_sysutil_memclr(&new_times, sizeof(new_times)); + new_times.actime = the_time; + new_times.modtime = the_time; +diff --git a/sysutil.h b/sysutil.h +index 7a59f13..b90f6ca 100644 +--- a/sysutil.h ++++ b/sysutil.h +@@ -349,9 +349,9 @@ void vsf_sysutil_chroot(const char* p_root_path); + */ + long vsf_sysutil_get_time_sec(void); + long vsf_sysutil_get_time_usec(void); +-long vsf_sysutil_parse_time(const char* p_text); ++long vsf_sysutil_parse_time(const char* p_text, int is_localtime); + void vsf_sysutil_sleep(double seconds); +-int vsf_sysutil_setmodtime(const char* p_file, long the_time, int is_localtime); ++int vsf_sysutil_setmodtime(const char* p_file, long the_time); + + /* Limits */ + void vsf_sysutil_set_address_space_limit(unsigned long bytes); +-- +2.24.1 + |