From 280fac351f20baeb6efb03d9c8d9d6bd36310d96 Mon Sep 17 00:00:00 2001 From: yang_zhuang_zhuang <1162011203@qq.com> Date: Mon, 20 Dec 2021 10:03:24 +0800 Subject: [PATCH] Fix the issue that the pid file cannot be rewritten --- ...-to-not-fail-on-a-left-over-pid-file.patch | 136 ++++++++++++++++++ rsync.spec | 9 +- 2 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 backport-Use-a-lock-to-not-fail-on-a-left-over-pid-file.patch diff --git a/backport-Use-a-lock-to-not-fail-on-a-left-over-pid-file.patch b/backport-Use-a-lock-to-not-fail-on-a-left-over-pid-file.patch new file mode 100644 index 0000000..543bf4a --- /dev/null +++ b/backport-Use-a-lock-to-not-fail-on-a-left-over-pid-file.patch @@ -0,0 +1,136 @@ +From b177311aee0b3cf17af0e1760e18dfb60d99e024 Mon Sep 17 00:00:00 2001 +From: Wayne Davison +Date: Thu, 4 Jun 2020 17:55:20 -0700 +Subject: [PATCH] Use a lock to not fail on a left-over pid file. + +--- + clientserver.c | 62 ++++++++++++++++++++++++++++++++++++++------------ + rsyncd.conf.yo | 7 +++--- + socket.c | 3 +++ + 3 files changed, 55 insertions(+), 17 deletions(-) + +diff --git a/clientserver.c b/clientserver.c +index 3af97d84..d56f5d52 100644 +--- a/clientserver.c ++++ b/clientserver.c +@@ -66,6 +66,7 @@ extern gid_t our_gid; + char *auth_user; + int read_only = 0; + int module_id = -1; ++int pid_file_fd = -1; + struct chmod_mode_struct *daemon_chmod_modes; + + /* module_dirlen is the length of the module_dir string when in daemon +@@ -1149,26 +1150,59 @@ int start_daemon(int f_in, int f_out) + static void create_pid_file(void) + { + char *pid_file = lp_pid_file(); +- char pidbuf[16]; +- pid_t pid = getpid(); +- int fd, len; ++ char pidbuf[32]; ++ STRUCT_STAT st1, st2; ++ char *fail = NULL; + + if (!pid_file || !*pid_file) + return; + +- cleanup_set_pid(pid); +- if ((fd = do_open(pid_file, O_WRONLY|O_CREAT|O_EXCL, 0666)) == -1) { +- failure: +- cleanup_set_pid(0); +- fprintf(stderr, "failed to create pid file %s: %s\n", pid_file, strerror(errno)); +- rsyserr(FLOG, errno, "failed to create pid file %s", pid_file); ++ /* These tests make sure that a temp-style lock dir is handled safely. */ ++ st1.st_mode = 0; ++ if (do_lstat(pid_file, &st1) == 0 && !S_ISREG(st1.st_mode) && unlink(pid_file) < 0) ++ fail = "unlink"; ++ else if ((pid_file_fd = do_open(pid_file, O_RDWR|O_CREAT, 0664)) < 0) ++ fail = S_ISREG(st1.st_mode) ? "open" : "create"; ++ else if (!lock_range(pid_file_fd, 0, 4)) ++ fail = "lock"; ++ else if (do_fstat(pid_file_fd, &st1) < 0) ++ fail = "fstat opened"; ++ else if (st1.st_size >= (int)sizeof pidbuf) ++ fail = "find small"; ++ else if (do_lstat(pid_file, &st2) < 0) ++ fail = "lstat"; ++ else if (!S_ISREG(st1.st_mode)) ++ fail = "avoid file overwrite race for"; ++ else if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) ++ fail = "verify stat info for"; ++#ifdef HAVE_FTRUNCATE ++ else if (do_ftruncate(pid_file_fd, 0) < 0) ++ fail = "truncate"; ++#endif ++ else { ++ pid_t pid = getpid(); ++ int len = snprintf(pidbuf, sizeof pidbuf, "%d\n", (int)pid); ++#ifndef HAVE_FTRUNCATE ++ /* What can we do with a too-long file and no truncate? I guess we'll add extra newlines. */ ++ while (len < st1.st_size) /* We already verfified that size+1 chars fits in the buffer. */ ++ pidbuf[len++] = '\n'; ++ /* We don't need the buffer to end in a '\0' (and we may not have room to add it). */ ++#endif ++ if (write(pid_file_fd, pidbuf, len) != len) ++ fail = "write"; ++ cleanup_set_pid(pid); /* Mark the file for removal on exit, even if the write failed. */ ++ } ++ ++ if (fail) { ++ char msg[1024]; ++ snprintf(msg, sizeof msg, "failed to %s pid file %s: %s\n", ++ fail, pid_file, strerror(errno)); ++ fputs(msg, stderr); ++ rprintf(FLOG, "%s", msg); + exit_cleanup(RERR_FILEIO); + } +- snprintf(pidbuf, sizeof pidbuf, "%d\n", (int)pid); +- len = strlen(pidbuf); +- if (write(fd, pidbuf, len) != len) +- goto failure; +- close(fd); ++ ++ /* The file is left open so that the lock remains valid. It is closed in our forked child procs. */ + } + + /* Become a daemon, discarding the controlling terminal. */ +diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo +index aac4a7f2..c8338664 100644 +--- a/rsyncd.conf.yo ++++ b/rsyncd.conf.yo +@@ -103,9 +103,10 @@ This can be overridden by the bf(--dparam=motdfile=FILE) + command-line option when starting the daemon. + + dit(bf(pid file)) This parameter tells the rsync daemon to write +-its process ID to that file. If the file already exists, the rsync +-daemon will abort rather than overwrite the file. +-This can be overridden by the bf(--dparam=pidfile=FILE) ++its process ID to that file. The rsync keeps the file locked so that ++it can know when it is safe to overwrite an existing file. ++ ++The filename can be overridden by the bf(--dparam=pidfile=FILE) + command-line option when starting the daemon. + + dit(bf(port)) You can override the default port the daemon will listen on +diff --git a/socket.c b/socket.c +index 70fb1695..11ab4a83 100644 +--- a/socket.c ++++ b/socket.c +@@ -38,6 +38,7 @@ extern char *bind_address; + extern char *sockopts; + extern int default_af_hint; + extern int connect_timeout; ++extern int pid_file_fd; + + #ifdef HAVE_SIGACTION + static struct sigaction sigact; +@@ -609,6 +610,8 @@ void start_accept_loop(int port, int (*fn)(int, int)) + + if ((pid = fork()) == 0) { + int ret; ++ if (pid_file_fd >= 0) ++ close(pid_file_fd); + for (i = 0; sp[i] >= 0; i++) + close(sp[i]); + /* Re-open log file in child before possibly giving diff --git a/rsync.spec b/rsync.spec index a8ded3f..4a0f687 100644 --- a/rsync.spec +++ b/rsync.spec @@ -1,6 +1,6 @@ Name: rsync Version: 3.1.3 -Release: 6 +Release: 7 Summary: Fast incremental file transfer utility License: GPLv3+ URL: http://rsync.samba.org/ @@ -32,6 +32,7 @@ Patch6009: Fix-zlib-CVE-2016-9843.patch Patch6010: Fix-bug-in-try_dests_reg-that-Florian-Zumbiehl-point.patch Patch6011: Try-to-fix-the-iconv-crash-in-bug-11338.patch Patch6012: CVE-2017-17433.patch +Patch6013: backport-Use-a-lock-to-not-fail-on-a-left-over-pid-file.patch %description Rsync is an open source utility that provides fast incremental file transfer. @@ -90,6 +91,12 @@ install -D -m644 %{SOURCE6} %{buildroot}/%{_unitdir}/rsyncd@.service %{_mandir}/man5/rsyncd.conf.5* %changelog +* Mon Dec 20 2021 yangzhuangzhuang - 3.1.3-7 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:Fix the issue that the pid file cannot be rewritten + * Fri Sep 27 2019 chengquan - 3.1.3-6 - Type:bugfix - ID:NA -- Gitee