From aa74292e24a20f8f3f8ab49bc338233b2bc7542f Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 1 Jul 2016 10:43:48 +0200 Subject: [PATCH] new upstream release - properly lock the lock files to be able to safely remove stale ones --- .gitignore | 1 + at-3.1.20-lock-locks.patch | 108 ++++++++++++++++++ at-3.1.18-pam.patch => at-3.1.20-pam.patch | 54 ++++----- ....1.14-shell.patch => at-3.1.20-shell.patch | 12 +- at.spec | 17 ++- sources | 2 +- 6 files changed, 155 insertions(+), 39 deletions(-) create mode 100644 at-3.1.20-lock-locks.patch rename at-3.1.18-pam.patch => at-3.1.20-pam.patch (87%) rename at-3.1.14-shell.patch => at-3.1.20-shell.patch (76%) diff --git a/.gitignore b/.gitignore index f2cb27c..89de2f8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ at_3.1.12.orig.tar.gz /at_3.1.14.orig.tar.gz /at_3.1.16.orig.tar.gz /at_3.1.18.orig.tar.gz +/at_3.1.20.orig.tar.gz diff --git a/at-3.1.20-lock-locks.patch b/at-3.1.20-lock-locks.patch new file mode 100644 index 0000000..17d6ad4 --- /dev/null +++ b/at-3.1.20-lock-locks.patch @@ -0,0 +1,108 @@ +diff -up at-3.1.20/atd.c.lock-locks at-3.1.20/atd.c +--- at-3.1.20/atd.c.lock-locks 2016-07-01 10:41:50.640867692 +0200 ++++ at-3.1.20/atd.c 2016-07-01 10:42:32.345844967 +0200 +@@ -74,6 +74,9 @@ + #include + #endif + ++#include ++#include ++ + /* Local headers */ + + #include "privs.h" +@@ -288,7 +291,7 @@ run_file(const char *filename, uid_t uid + * mail to the user. + */ + pid_t pid; +- int fd_out, fd_in; ++ int fd_out, fd_in, fd_std; + char jobbuf[9]; + char *mailname = NULL; + int mailsize = 128; +@@ -410,6 +413,10 @@ run_file(const char *filename, uid_t uid + + fcntl(fd_in, F_SETFD, fflags & ~FD_CLOEXEC); + ++ if (flock(fd_in, LOCK_EX | LOCK_NB) != 0) ++ perr("Somebody already locked the job %8lu (%.500s) - " ++ "aborting", jobno, filename); ++ + /* + * If the spool directory is mounted via NFS `atd' isn't able to + * read from the job file and will bump out here. The file is +@@ -553,10 +560,7 @@ run_file(const char *filename, uid_t uid + PRIV_END + } + /* We're the parent. Let's wait. +- */ +- close(fd_in); +- +- /* We inherited the master's SIGCHLD handler, which does a ++ We inherited the master's SIGCHLD handler, which does a + non-blocking waitpid. So this blocking one will eventually + return with an ECHILD error. + */ +@@ -573,14 +577,14 @@ run_file(const char *filename, uid_t uid + /* some sendmail implementations are confused if stdout, stderr are + * not available, so let them point to /dev/null + */ +- if ((fd_in = open("/dev/null", O_WRONLY)) < 0) ++ if ((fd_std = open("/dev/null", O_WRONLY)) < 0) + perr("Could not open /dev/null."); +- if (dup2(fd_in, STDOUT_FILENO) < 0) ++ if (dup2(fd_std, STDOUT_FILENO) < 0) + perr("Could not use /dev/null as standard output."); +- if (dup2(fd_in, STDERR_FILENO) < 0) ++ if (dup2(fd_std, STDERR_FILENO) < 0) + perr("Could not use /dev/null as standard error."); +- if (fd_in != STDOUT_FILENO && fd_in != STDERR_FILENO) +- close(fd_in); ++ if (fd_std != STDOUT_FILENO && fd_std != STDERR_FILENO) ++ close(fd_std); + + if (unlink(filename) == -1) + syslog(LOG_WARNING, "Warning: removing output file for job %li failed: %s", +@@ -588,7 +592,12 @@ run_file(const char *filename, uid_t uid + + /* The job is now finished. We can delete its input file. + */ +- chdir(ATJOB_DIR); ++ if (chdir(ATJOB_DIR) != 0) ++ perr("Somebody removed %s directory from under us.", ATJOB_DIR); ++ ++ /* This also removes the flock */ ++ (void)close(fd_in); ++ + unlink(newname); + free(newname); + +@@ -723,16 +732,18 @@ run_loop() + + /* Skip lock files */ + if (queue == '=') { +- /* FIXME: calhariz */ +- /* I think the following code is broken, but commenting +- may haven unknow side effects. Make a release and see +- in the wild how it works. For more information see: +- https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=818508/* +- +- /* if ((buf.st_nlink == 1) && (run_time + CHECK_INTERVAL <= now)) { */ +- /* /\* Remove stale lockfile FIXME: lock the lockfile, if you fail, it's still in use. *\/ */ +- /* unlink(dirent->d_name); */ +- /* } */ ++ if ((buf.st_nlink == 1) && (run_time + CHECK_INTERVAL <= now)) { ++ int fd; ++ ++ fd = open(dirent->d_name, O_RDONLY); ++ if (fd != -1) { ++ if (flock(fd, LOCK_EX | LOCK_NB) == 0) { ++ unlink(dirent->d_name); ++ syslog(LOG_NOTICE, "removing stale lock file %s\n", dirent->d_name); ++ } ++ (void)close(fd); ++ } ++ } + continue; + } + /* Skip any other file types which may have been invented in diff --git a/at-3.1.18-pam.patch b/at-3.1.20-pam.patch similarity index 87% rename from at-3.1.18-pam.patch rename to at-3.1.20-pam.patch index 7658767..418fa84 100644 --- a/at-3.1.18-pam.patch +++ b/at-3.1.20-pam.patch @@ -1,6 +1,6 @@ -diff -up at-3.1.18/at.c.pam at-3.1.18/at.c ---- at-3.1.18/at.c.pam 2015-12-06 16:45:10.000000000 +0100 -+++ at-3.1.18/at.c 2016-03-23 12:40:10.694447117 +0100 +diff -up at-3.1.20/at.c.pam at-3.1.20/at.c +--- at-3.1.20/at.c.pam 2016-06-28 22:18:00.000000000 +0200 ++++ at-3.1.20/at.c 2016-07-01 09:44:22.251683924 +0200 @@ -144,18 +144,13 @@ sigc(int signo) /* If the user presses ^C, remove the spool file and exit */ @@ -52,7 +52,7 @@ diff -up at-3.1.18/at.c.pam at-3.1.18/at.c /* We've successfully created the file; let's set the flag so it * gets removed in case of an interrupt or error. */ -@@ -670,7 +658,7 @@ process_jobs(int argc, char **argv, int +@@ -673,7 +661,7 @@ process_jobs(int argc, char **argv, int We need the unprivileged uid here since the file is owned by the real (not effective) uid. */ @@ -61,7 +61,7 @@ diff -up at-3.1.18/at.c.pam at-3.1.18/at.c if (queue == '=') { fprintf(stderr, "Warning: deleting running job\n"); -@@ -679,8 +667,8 @@ process_jobs(int argc, char **argv, int +@@ -682,8 +670,8 @@ process_jobs(int argc, char **argv, int perr("Cannot unlink %.500s", dirent->d_name); rc = EXIT_FAILURE; } @@ -71,7 +71,7 @@ diff -up at-3.1.18/at.c.pam at-3.1.18/at.c done = 1; break; -@@ -690,7 +678,7 @@ process_jobs(int argc, char **argv, int +@@ -693,7 +681,7 @@ process_jobs(int argc, char **argv, int FILE *fp; int ch; @@ -80,7 +80,7 @@ diff -up at-3.1.18/at.c.pam at-3.1.18/at.c fp = fopen(dirent->d_name, "r"); if (fp) { -@@ -703,7 +691,7 @@ process_jobs(int argc, char **argv, int +@@ -706,7 +694,7 @@ process_jobs(int argc, char **argv, int perr("Cannot open %.500s", dirent->d_name); rc = EXIT_FAILURE; } @@ -89,9 +89,9 @@ diff -up at-3.1.18/at.c.pam at-3.1.18/at.c } break; -diff -up at-3.1.18/atd.c.pam at-3.1.18/atd.c ---- at-3.1.18/atd.c.pam 2015-12-06 16:45:10.000000000 +0100 -+++ at-3.1.18/atd.c 2016-03-23 12:43:31.990906478 +0100 +diff -up at-3.1.20/atd.c.pam at-3.1.20/atd.c +--- at-3.1.20/atd.c.pam 2016-06-28 22:14:39.000000000 +0200 ++++ at-3.1.20/atd.c 2016-07-01 09:44:22.251683924 +0200 @@ -91,6 +91,10 @@ int selinux_enabled = 0; /* Macros */ @@ -248,9 +248,9 @@ diff -up at-3.1.18/atd.c.pam at-3.1.18/atd.c exit(EXIT_SUCCESS); } -diff -up at-3.1.18/config.h.in.pam at-3.1.18/config.h.in ---- at-3.1.18/config.h.in.pam 2015-12-06 16:45:10.000000000 +0100 -+++ at-3.1.18/config.h.in 2016-03-23 12:40:10.695447139 +0100 +diff -up at-3.1.20/config.h.in.pam at-3.1.20/config.h.in +--- at-3.1.20/config.h.in.pam 2015-12-18 21:29:24.000000000 +0100 ++++ at-3.1.20/config.h.in 2016-07-01 09:44:22.251683924 +0200 @@ -68,8 +68,8 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NLIST_H @@ -262,9 +262,9 @@ diff -up at-3.1.18/config.h.in.pam at-3.1.18/config.h.in /* Define to 1 if you have the `pstat_getdynamic' function. */ #undef HAVE_PSTAT_GETDYNAMIC -diff -up at-3.1.18/configure.ac.pam at-3.1.18/configure.ac ---- at-3.1.18/configure.ac.pam 2015-12-06 16:45:10.000000000 +0100 -+++ at-3.1.18/configure.ac 2016-03-23 12:45:27.885473913 +0100 +diff -up at-3.1.20/configure.ac.pam at-3.1.20/configure.ac +--- at-3.1.20/configure.ac.pam 2016-06-28 22:55:52.000000000 +0200 ++++ at-3.1.20/configure.ac 2016-07-01 09:45:23.268092527 +0200 @@ -78,7 +78,7 @@ AC_FUNC_GETLOADAVG AC_CHECK_FUNCS(getcwd mktime strftime setreuid setresuid sigaction waitpid) AC_CHECK_HEADERS(security/pam_appl.h, [ @@ -286,11 +286,11 @@ diff -up at-3.1.18/configure.ac.pam at-3.1.18/configure.ac +AC_SUBST(PAMLIB) + AC_ARG_WITH(selinux, - [ --with-selinux Define to run with selinux], - AC_DEFINE(WITH_SELINUX, 1, [Define if you are building with_selinux]), -diff -up at-3.1.18/Makefile.in.pam at-3.1.18/Makefile.in ---- at-3.1.18/Makefile.in.pam 2016-03-23 12:55:30.000000000 +0100 -+++ at-3.1.18/Makefile.in 2016-03-23 12:57:58.347145148 +0100 + [ --with-selinux Define to run with selinux (default=check)], + [], +diff -up at-3.1.20/Makefile.in.pam at-3.1.20/Makefile.in +--- at-3.1.20/Makefile.in.pam 2016-07-01 09:44:22.250683901 +0200 ++++ at-3.1.20/Makefile.in 2016-07-01 09:44:22.252683947 +0200 @@ -68,7 +68,7 @@ LIST = Filelist Filelist.asc all: at atd atd.service atrun @@ -300,9 +300,9 @@ diff -up at-3.1.18/Makefile.in.pam at-3.1.18/Makefile.in rm -f $(CLONES) $(LN_S) -f at atq $(LN_S) -f at atrm -diff -up at-3.1.18/perm.c.pam at-3.1.18/perm.c ---- at-3.1.18/perm.c.pam 2015-12-06 16:45:10.000000000 +0100 -+++ at-3.1.18/perm.c 2016-03-23 12:40:10.695447139 +0100 +diff -up at-3.1.20/perm.c.pam at-3.1.20/perm.c +--- at-3.1.20/perm.c.pam 2015-08-22 00:09:22.000000000 +0200 ++++ at-3.1.20/perm.c 2016-07-01 09:44:22.252683947 +0200 @@ -51,6 +51,14 @@ #define PRIV_END while(0) #endif @@ -367,9 +367,9 @@ diff -up at-3.1.18/perm.c.pam at-3.1.18/perm.c allow = user_in_file(ETCDIR "/at.allow", pentry->pw_name); if (allow==0 || allow==1) return allow; -diff -up at-3.1.18/privs.h.pam at-3.1.18/privs.h ---- at-3.1.18/privs.h.pam 2015-12-06 16:45:10.000000000 +0100 -+++ at-3.1.18/privs.h 2016-03-23 12:40:10.695447139 +0100 +diff -up at-3.1.20/privs.h.pam at-3.1.20/privs.h +--- at-3.1.20/privs.h.pam 2015-08-22 00:09:22.000000000 +0200 ++++ at-3.1.20/privs.h 2016-07-01 09:44:22.252683947 +0200 @@ -144,3 +144,63 @@ extern gid_t real_gid, effective_gid, da #error "Cannot implement user ID swapping without setreuid or setresuid" #endif diff --git a/at-3.1.14-shell.patch b/at-3.1.20-shell.patch similarity index 76% rename from at-3.1.14-shell.patch rename to at-3.1.20-shell.patch index 49f66f1..ac9586c 100644 --- a/at-3.1.14-shell.patch +++ b/at-3.1.20-shell.patch @@ -1,6 +1,6 @@ -diff -up at-3.1.14/at.c.shell at-3.1.14/at.c ---- at-3.1.14/at.c.shell 2014-01-06 17:58:17.555564746 +0100 -+++ at-3.1.14/at.c 2014-01-06 17:59:17.699720002 +0100 +diff -up at-3.1.20/at.c.shell at-3.1.20/at.c +--- at-3.1.20/at.c.shell 2016-07-01 09:47:13.392684445 +0200 ++++ at-3.1.20/at.c 2016-07-01 09:48:47.679931959 +0200 @@ -62,11 +62,8 @@ #include #include @@ -26,7 +26,7 @@ diff -up at-3.1.14/at.c.shell at-3.1.14/at.c /* Install the signal handler for SIGINT; terminate after removing the * spool file if necessary -@@ -449,6 +452,9 @@ writefile(time_t runtimer, char queue) +@@ -465,6 +468,9 @@ writefile(time_t runtimer, char queue) fprintf(fp, " || {\n\t echo 'Execution directory " "inaccessible' >&2\n\t exit 1\n}\n"); @@ -36,7 +36,7 @@ diff -up at-3.1.14/at.c.shell at-3.1.14/at.c istty = isatty(fileno(stdin)); if (istty) { fprintf(stderr, "at> "); -@@ -464,7 +470,7 @@ writefile(time_t runtimer, char queue) +@@ -480,7 +486,7 @@ writefile(time_t runtimer, char queue) if (istty) { fprintf(stderr, "\n"); } @@ -44,4 +44,4 @@ diff -up at-3.1.14/at.c.shell at-3.1.14/at.c + fprintf(fp, "marcinDELIMITER%08lx\n", i); if (ferror(fp)) panic("Output error"); - + fflush(fp); diff --git a/at.spec b/at.spec index a0dcb74..560bea0 100644 --- a/at.spec +++ b/at.spec @@ -2,8 +2,8 @@ Summary: Job spooling tools Name: at -Version: 3.1.18 -Release: 2%{?dist} +Version: 3.1.20 +Release: 1%{?dist} # http://packages.debian.org/changelogs/pool/main/a/at/current/copyright # + install-sh is MIT license with changes under Public Domain License: GPLv3+ and GPLv2+ and ISC and MIT and Public Domain @@ -18,9 +18,9 @@ Source5: atd.systemd Patch0: at-aarch64.patch Patch1: at-3.1.18-make.patch -Patch2: at-3.1.18-pam.patch +Patch2: at-3.1.20-pam.patch Patch4: at-3.1.14-opt_V.patch -Patch5: at-3.1.14-shell.patch +Patch5: at-3.1.20-shell.patch Patch6: at-3.1.18-nitpicks.patch Patch8: at-3.1.14-fix_no_export.patch Patch9: at-3.1.14-mailwithhostname.patch @@ -30,6 +30,7 @@ Patch13: at-3.1.18-noabort.patch Patch14: at-3.1.16-fclose-error.patch Patch15: at-3.1.16-clear-nonjobs.patch Patch16: at-3.1.18-utc-dst.patch +Patch17: at-3.1.20-lock-locks.patch BuildRequires: fileutils /etc/init.d BuildRequires: flex flex-static bison autoconf @@ -63,7 +64,7 @@ need to be repeated at the same time every day/week, etc. you should use crontab instead. %prep -%setup -c -q +%setup -q cp %{SOURCE1} . %patch0 -p1 -b .arm %patch1 -p1 -b .make @@ -79,6 +80,7 @@ cp %{SOURCE1} . %patch14 -p1 -b .fclose %patch15 -p1 -b .clear-nojobs %patch16 -p1 -b .dst +%patch17 -p1 -b .lock-locks %build # patch9 touches configure.in @@ -176,6 +178,11 @@ chown daemon:daemon %{_localstatedir}/spool/at/.SEQ %attr(0644,root,root) /%{_unitdir}/atd.service %changelog +* Fri Jul 1 2016 Tomáš Mráz - 3.1.20-1 +- new upstream release +- properly lock the lock files to be able to safely remove + stale ones + * Mon May 23 2016 Tomáš Mráz - 3.1.18-2 - SIGPIPE should not be ignored in atd (#1338039) diff --git a/sources b/sources index 16baf64..67f3292 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -f67a7aab557cd5b4a1311079a08acebe at_3.1.18.orig.tar.gz +e7bd7b785b2cbb17e133d6bdc0fb099e at_3.1.20.orig.tar.gz