From 014cc9ce0abeb4a78e16e482bef64cd39f7897fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=BCtz?= Date: Thu, 27 May 2021 21:40:32 +0200 Subject: [PATCH] samba: 4.13.7 -> 4.14.4 fixes https://www.samba.org/samba/security/CVE-2021-20254.html --- ...l-Standardize-use-of-st_-acm-time-ns.patch | 569 ------------------ pkgs/servers/samba/4.x.nix | 6 +- 2 files changed, 2 insertions(+), 573 deletions(-) delete mode 100644 pkgs/servers/samba/0001-lib-util-Standardize-use-of-st_-acm-time-ns.patch diff --git a/pkgs/servers/samba/0001-lib-util-Standardize-use-of-st_-acm-time-ns.patch b/pkgs/servers/samba/0001-lib-util-Standardize-use-of-st_-acm-time-ns.patch deleted file mode 100644 index 6de704cba285..000000000000 --- a/pkgs/servers/samba/0001-lib-util-Standardize-use-of-st_-acm-time-ns.patch +++ /dev/null @@ -1,569 +0,0 @@ -From 55a5b9c8254126d0acef8702526c92a31200a07c Mon Sep 17 00:00:00 2001 -From: Matthew DeVore -Date: Tue, 4 Aug 2020 17:49:42 -0700 -Subject: [PATCH] lib/util: Standardize use of st_[acm]time ns - -Commit 810397f89a10, and possibly others, broke the build for macOS and -other environments which don't have st_[acm]tim fields on 'struct stat'. - -Multiple places in the codebase used the config.h values to determine -how to access the nanosecond or microsecond values of the stat -timestamps, so rather than add more, centralize them all into -lib/util/time.c. - -Also allow pvfs_fileinfo.c to read nanosecond-granularity timestamps on -platforms where it didn't before, since its #if branches were not -complete. - -Signed-off-by: Matthew DeVore -Reviewed-by: Jeremy Allison -Reviewed-by: Volker Lendecke - -Autobuild-User(master): Volker Lendecke -Autobuild-Date(master): Sat Aug 15 08:51:09 UTC 2020 on sn-devel-184 ---- - lib/replace/wscript | 2 - - lib/util/time.c | 230 ++++++++++++++++++++ - lib/util/time.h | 18 ++ - source3/lib/system.c | 121 +--------- - source3/libsmb/libsmb_stat.c | 24 +- - source4/ntvfs/posix/pvfs_fileinfo.c | 11 +- - source4/torture/libsmbclient/libsmbclient.c | 7 +- - 7 files changed, 277 insertions(+), 136 deletions(-) - -diff --git a/lib/replace/wscript b/lib/replace/wscript -index 64f305d6df0..85bc11d2f01 100644 ---- a/lib/replace/wscript -+++ b/lib/replace/wscript -@@ -746,8 +746,6 @@ def configure(conf): - - conf.CHECK_CODE('mkdir("foo",0777)', define='HAVE_MKDIR_MODE', headers='sys/stat.h') - -- conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtim.tv_nsec', define='HAVE_STAT_TV_NSEC', -- headers='sys/stat.h') - # we need the st_rdev test under two names - conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_rdev', - define='HAVE_STRUCT_STAT_ST_RDEV', -diff --git a/lib/util/time.c b/lib/util/time.c -index 0fac5e2e397..b5c1d700b23 100644 ---- a/lib/util/time.c -+++ b/lib/util/time.c -@@ -26,6 +26,10 @@ - #include "byteorder.h" - #include "time_basic.h" - #include "lib/util/time.h" /* Avoid /usr/include/time.h */ -+#include -+#ifndef NO_CONFIG_H -+#include "config.h" -+#endif - - /** - * @file -@@ -1232,3 +1236,229 @@ struct timespec time_t_to_full_timespec(time_t t) - } - return (struct timespec){.tv_sec = t}; - } -+ -+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS) -+ -+/* Old system - no ns timestamp. */ -+time_t get_atimensec(const struct stat *st) -+{ -+ return 0; -+} -+ -+time_t get_mtimensec(const struct stat *st) -+{ -+ return 0; -+} -+ -+time_t get_ctimensec(const struct stat *st) -+{ -+ return 0; -+} -+ -+/* Set does nothing with no ns timestamp. */ -+void set_atimensec(struct stat *st, time_t ns) -+{ -+ return; -+} -+ -+void set_mtimensec(struct stat *st, time_t ns) -+{ -+ return; -+} -+ -+void set_ctimensec(struct stat *st, time_t ns) -+{ -+ return; -+} -+ -+#elif HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC -+ -+time_t get_atimensec(const struct stat *st) -+{ -+ return st->st_atimespec.tv_nsec; -+} -+ -+time_t get_mtimensec(const struct stat *st) -+{ -+ return st->st_mtimespec.tv_nsec; -+} -+ -+time_t get_ctimensec(const struct stat *st) -+{ -+ return st->st_ctimespec.tv_nsec; -+} -+ -+void set_atimensec(struct stat *st, time_t ns) -+{ -+ st->st_atimespec.tv_nsec = ns; -+} -+ -+void set_mtimensec(struct stat *st, time_t ns) -+{ -+ st->st_mtimespec.tv_nsec = ns; -+} -+ -+void set_ctimensec(struct stat *st, time_t ns) -+{ -+ st->st_ctimespec.tv_nsec = ns; -+} -+ -+#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC -+ -+time_t get_atimensec(const struct stat *st) -+{ -+ return st->st_atim.tv_nsec; -+} -+ -+time_t get_mtimensec(const struct stat *st) -+{ -+ return st->st_mtim.tv_nsec; -+} -+ -+time_t get_ctimensec(const struct stat *st) -+{ -+ return st->st_ctim.tv_nsec; -+} -+ -+void set_atimensec(struct stat *st, time_t ns) -+{ -+ st->st_atim.tv_nsec = ns; -+} -+ -+void set_mtimensec(struct stat *st, time_t ns) -+{ -+ st->st_mtim.tv_nsec = ns; -+} -+void set_ctimensec(struct stat *st, time_t ns) -+{ -+ st->st_ctim.tv_nsec = ns; -+} -+ -+#elif HAVE_STRUCT_STAT_ST_MTIMENSEC -+ -+time_t get_atimensec(const struct stat *st) -+{ -+ return st->st_atimensec; -+} -+ -+time_t get_mtimensec(const struct stat *st) -+{ -+ return st->st_mtimensec; -+} -+ -+time_t get_ctimensec(const struct stat *st) -+{ -+ return st->st_ctimensec; -+} -+ -+void set_atimensec(struct stat *st, time_t ns) -+{ -+ st->st_atimensec = ns; -+} -+ -+void set_mtimensec(struct stat *st, time_t ns) -+{ -+ st->st_mtimensec = ns; -+} -+ -+void set_ctimensec(struct stat *st, time_t ns) -+{ -+ st->st_ctimensec = ns; -+} -+ -+#elif HAVE_STRUCT_STAT_ST_MTIME_N -+ -+time_t get_atimensec(const struct stat *st) -+{ -+ return st->st_atime_n; -+} -+ -+time_t get_mtimensec(const struct stat *st) -+{ -+ return st->st_mtime_n; -+} -+ -+time_t get_ctimensec(const struct stat *st) -+{ -+ return st->st_ctime_n; -+} -+ -+void set_atimensec(struct stat *st, time_t ns) -+{ -+ st->st_atime_n = ns; -+} -+ -+void set_mtimensec(struct stat *st, time_t ns) -+{ -+ st->st_mtime_n = ns; -+} -+ -+void set_ctimensec(struct stat *st, time_t ns) -+{ -+ st->st_ctime_n = ns; -+} -+ -+#elif HAVE_STRUCT_STAT_ST_UMTIME -+ -+/* Only usec timestamps available. Convert to/from nsec. */ -+ -+time_t get_atimensec(const struct stat *st) -+{ -+ return st->st_uatime * 1000; -+} -+ -+time_t get_mtimensec(const struct stat *st) -+{ -+ return st->st_umtime * 1000; -+} -+ -+time_t get_ctimensec(const struct stat *st) -+{ -+ return st->st_uctime * 1000; -+} -+ -+void set_atimensec(struct stat *st, time_t ns) -+{ -+ st->st_uatime = ns / 1000; -+} -+ -+void set_mtimensec(struct stat *st, time_t ns) -+{ -+ st->st_umtime = ns / 1000; -+} -+ -+void set_ctimensec(struct stat *st, time_t ns) -+{ -+ st->st_uctime = ns / 1000; -+} -+ -+#else -+#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT -+#endif -+ -+struct timespec get_atimespec(const struct stat *pst) -+{ -+ struct timespec ret; -+ -+ ret.tv_sec = pst->st_atime; -+ ret.tv_nsec = get_atimensec(pst); -+ return ret; -+} -+ -+struct timespec get_mtimespec(const struct stat *pst) -+{ -+ struct timespec ret; -+ -+ ret.tv_sec = pst->st_mtime; -+ ret.tv_nsec = get_mtimensec(pst); -+ return ret; -+} -+ -+struct timespec get_ctimespec(const struct stat *pst) -+{ -+ struct timespec ret; -+ -+ ret.tv_sec = pst->st_mtime; -+ ret.tv_nsec = get_ctimensec(pst); -+ return ret; -+} -diff --git a/lib/util/time.h b/lib/util/time.h -index 4a90b40d5ce..04945b5f25f 100644 ---- a/lib/util/time.h -+++ b/lib/util/time.h -@@ -375,4 +375,22 @@ time_t full_timespec_to_time_t(const struct timespec *ts); - time_t nt_time_to_full_time_t(NTTIME nt); - struct timespec time_t_to_full_timespec(time_t t); - -+/* -+ * Functions to get and set the number of nanoseconds for times in a stat field. -+ * If the stat has timestamp granularity less than nanosecond, then the set_* -+ * operations will be lossy. -+ */ -+struct stat; -+time_t get_atimensec(const struct stat *); -+time_t get_mtimensec(const struct stat *); -+time_t get_ctimensec(const struct stat *); -+void set_atimensec(struct stat *, time_t); -+void set_mtimensec(struct stat *, time_t); -+void set_ctimensec(struct stat *, time_t); -+ -+/* These are convenience wrappers for the above getters. */ -+struct timespec get_atimespec(const struct stat *); -+struct timespec get_mtimespec(const struct stat *); -+struct timespec get_ctimespec(const struct stat *); -+ - #endif /* _SAMBA_TIME_H_ */ -diff --git a/source3/lib/system.c b/source3/lib/system.c -index f1265e0c43f..7c8cd19d11f 100644 ---- a/source3/lib/system.c -+++ b/source3/lib/system.c -@@ -25,7 +25,8 @@ - #include "system/capability.h" - #include "system/passwd.h" - #include "system/filesys.h" --#include "../lib/util/setid.h" -+#include "lib/util/setid.h" -+#include "lib/util/time.h" - - #ifdef HAVE_SYS_SYSCTL_H - #include -@@ -122,124 +123,6 @@ int sys_fcntl_int(int fd, int cmd, int arg) - return ret; - } - --/**************************************************************************** -- Get/Set all the possible time fields from a stat struct as a timespec. --****************************************************************************/ -- --static struct timespec get_atimespec(const struct stat *pst) --{ --#if !defined(HAVE_STAT_HIRES_TIMESTAMPS) -- struct timespec ret; -- -- /* Old system - no ns timestamp. */ -- ret.tv_sec = pst->st_atime; -- ret.tv_nsec = 0; -- return ret; --#else --#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) -- struct timespec ret; -- ret.tv_sec = pst->st_atim.tv_sec; -- ret.tv_nsec = pst->st_atim.tv_nsec; -- return ret; --#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) -- struct timespec ret; -- ret.tv_sec = pst->st_atime; -- ret.tv_nsec = pst->st_atimensec; -- return ret; --#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) -- struct timespec ret; -- ret.tv_sec = pst->st_atime; -- ret.tv_nsec = pst->st_atime_n; -- return ret; --#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) -- struct timespec ret; -- ret.tv_sec = pst->st_atime; -- ret.tv_nsec = pst->st_uatime * 1000; -- return ret; --#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) -- return pst->st_atimespec; --#else --#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT --#endif --#endif --} -- --static struct timespec get_mtimespec(const struct stat *pst) --{ --#if !defined(HAVE_STAT_HIRES_TIMESTAMPS) -- struct timespec ret; -- -- /* Old system - no ns timestamp. */ -- ret.tv_sec = pst->st_mtime; -- ret.tv_nsec = 0; -- return ret; --#else --#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) -- struct timespec ret; -- ret.tv_sec = pst->st_mtim.tv_sec; -- ret.tv_nsec = pst->st_mtim.tv_nsec; -- return ret; --#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) -- struct timespec ret; -- ret.tv_sec = pst->st_mtime; -- ret.tv_nsec = pst->st_mtimensec; -- return ret; --#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) -- struct timespec ret; -- ret.tv_sec = pst->st_mtime; -- ret.tv_nsec = pst->st_mtime_n; -- return ret; --#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) -- struct timespec ret; -- ret.tv_sec = pst->st_mtime; -- ret.tv_nsec = pst->st_umtime * 1000; -- return ret; --#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) -- return pst->st_mtimespec; --#else --#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT --#endif --#endif --} -- --static struct timespec get_ctimespec(const struct stat *pst) --{ --#if !defined(HAVE_STAT_HIRES_TIMESTAMPS) -- struct timespec ret; -- -- /* Old system - no ns timestamp. */ -- ret.tv_sec = pst->st_ctime; -- ret.tv_nsec = 0; -- return ret; --#else --#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) -- struct timespec ret; -- ret.tv_sec = pst->st_ctim.tv_sec; -- ret.tv_nsec = pst->st_ctim.tv_nsec; -- return ret; --#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) -- struct timespec ret; -- ret.tv_sec = pst->st_ctime; -- ret.tv_nsec = pst->st_ctimensec; -- return ret; --#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) -- struct timespec ret; -- ret.tv_sec = pst->st_ctime; -- ret.tv_nsec = pst->st_ctime_n; -- return ret; --#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) -- struct timespec ret; -- ret.tv_sec = pst->st_ctime; -- ret.tv_nsec = pst->st_uctime * 1000; -- return ret; --#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) -- return pst->st_ctimespec; --#else --#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT --#endif --#endif --} -- - /**************************************************************************** - Return the best approximation to a 'create time' under UNIX from a stat - structure. -diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c -index 790934bd565..b01aeb51ac1 100644 ---- a/source3/libsmb/libsmb_stat.c -+++ b/source3/libsmb/libsmb_stat.c -@@ -27,6 +27,7 @@ - #include "libsmbclient.h" - #include "libsmb_internal.h" - #include "../libcli/smb/smbXcli_base.h" -+#include "lib/util/time.h" - - /* - * Generate an inode number from file name for those things that need it -@@ -102,18 +103,29 @@ void setup_stat(struct stat *st, - } - - st->st_dev = dev; -- st->st_atim = access_time_ts; -- st->st_ctim = change_time_ts; -- st->st_mtim = write_time_ts; -+ -+ st->st_atime = access_time_ts.tv_sec; -+ set_atimensec(st, access_time_ts.tv_nsec); -+ -+ st->st_ctime = change_time_ts.tv_sec; -+ set_ctimensec(st, change_time_ts.tv_nsec); -+ -+ st->st_mtime = write_time_ts.tv_sec; -+ set_mtimensec(st, write_time_ts.tv_nsec); - } - - void setup_stat_from_stat_ex(const struct stat_ex *stex, - const char *fname, - struct stat *st) - { -- st->st_atim = stex->st_ex_atime; -- st->st_ctim = stex->st_ex_ctime; -- st->st_mtim = stex->st_ex_mtime; -+ st->st_atime = stex->st_ex_atime.tv_sec; -+ set_atimensec(st, stex->st_ex_atime.tv_nsec); -+ -+ st->st_ctime = stex->st_ex_ctime.tv_sec; -+ set_ctimensec(st, stex->st_ex_ctime.tv_nsec); -+ -+ st->st_mtime = stex->st_ex_mtime.tv_sec; -+ set_mtimensec(st, stex->st_ex_mtime.tv_nsec); - - st->st_mode = stex->st_ex_mode; - st->st_size = stex->st_ex_size; -diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c -index d2e2aeea265..977ea4fa3d5 100644 ---- a/source4/ntvfs/posix/pvfs_fileinfo.c -+++ b/source4/ntvfs/posix/pvfs_fileinfo.c -@@ -21,6 +21,7 @@ - - #include "includes.h" - #include "vfs_posix.h" -+#include "lib/util/time.h" - - /**************************************************************************** - Change a unix mode to a dos mode. -@@ -72,12 +73,10 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, - unix_to_nt_time(&name->dos.access_time, name->st.st_atime); - unix_to_nt_time(&name->dos.write_time, name->st.st_mtime); - unix_to_nt_time(&name->dos.change_time, name->st.st_ctime); --#ifdef HAVE_STAT_TV_NSEC -- name->dos.create_time += name->st.st_ctim.tv_nsec / 100; -- name->dos.access_time += name->st.st_atim.tv_nsec / 100; -- name->dos.write_time += name->st.st_mtim.tv_nsec / 100; -- name->dos.change_time += name->st.st_ctim.tv_nsec / 100; --#endif -+ name->dos.create_time += get_ctimensec(&name->st) / 100; -+ name->dos.access_time += get_atimensec(&name->st) / 100; -+ name->dos.write_time += get_mtimensec(&name->st) / 100; -+ name->dos.change_time += get_ctimensec(&name->st) / 100; - name->dos.attrib = dos_mode_from_stat(pvfs, &name->st); - name->dos.alloc_size = pvfs_round_alloc_size(pvfs, name->st.st_size); - name->dos.nlink = name->st.st_nlink; -diff --git a/source4/torture/libsmbclient/libsmbclient.c b/source4/torture/libsmbclient/libsmbclient.c -index 3f3992593f9..4fbd759487b 100644 ---- a/source4/torture/libsmbclient/libsmbclient.c -+++ b/source4/torture/libsmbclient/libsmbclient.c -@@ -27,6 +27,7 @@ - #include "lib/param/loadparm.h" - #include "lib/param/param_global.h" - #include "dynconfig.h" -+#include "lib/util/time.h" - - /* test string to compare with when debug_callback is called */ - #define TEST_STRING "smbc_setLogCallback test" -@@ -1231,8 +1232,8 @@ static bool torture_libsmbclient_utimes(struct torture_context *tctx) - ret = smbc_fstat(fhandle, &st); - torture_assert_int_not_equal(tctx, ret, -1, "smbc_fstat failed"); - -- tbuf[0] = convert_timespec_to_timeval(st.st_atim); -- tbuf[1] = convert_timespec_to_timeval(st.st_mtim); -+ tbuf[0] = convert_timespec_to_timeval(get_atimespec(&st)); -+ tbuf[1] = convert_timespec_to_timeval(get_mtimespec(&st)); - - tbuf[1] = timeval_add(&tbuf[1], 0, 100000); /* 100 msec */ - -@@ -1244,7 +1245,7 @@ static bool torture_libsmbclient_utimes(struct torture_context *tctx) - - torture_assert_int_equal( - tctx, -- st.st_mtim.tv_nsec / 1000, -+ get_mtimensec(&st) / 1000, - tbuf[1].tv_usec, - "smbc_utimes did not update msec"); - --- -2.29.2 - diff --git a/pkgs/servers/samba/4.x.nix b/pkgs/servers/samba/4.x.nix index c540fb20d448..7beaeb20943d 100644 --- a/pkgs/servers/samba/4.x.nix +++ b/pkgs/servers/samba/4.x.nix @@ -44,11 +44,11 @@ with lib; stdenv.mkDerivation rec { pname = "samba"; - version = "4.13.7"; + version = "4.14.4"; src = fetchurl { url = "mirror://samba/pub/samba/stable/${pname}-${version}.tar.gz"; - sha256 = "1ajvr5hzl9kmrf77hb9c71zvnm8j0xgy40nqfjz4f407cw470zaf"; + sha256 = "1fc9ix91hb1f35j69sk7rsi9pky2p0vsmw47s973bx801cm0kbw9"; }; outputs = [ "out" "dev" "man" ]; @@ -58,8 +58,6 @@ stdenv.mkDerivation rec { ./patch-source3__libads__kerberos_keytab.c.patch ./4.x-no-persistent-install-dynconfig.patch ./4.x-fix-makeflags-parsing.patch - # Backport, should be removed for version 4.14 - ./0001-lib-util-Standardize-use-of-st_-acm-time-ns.patch ]; nativeBuildInputs = [