diff --git a/quota-4.03-quotaops-check-return-code-of-ftruncate-and-lseek-ca.patch b/quota-4.03-quotaops-check-return-code-of-ftruncate-and-lseek-ca.patch new file mode 100644 index 0000000..6980c0e --- /dev/null +++ b/quota-4.03-quotaops-check-return-code-of-ftruncate-and-lseek-ca.patch @@ -0,0 +1,128 @@ +From 251c3931fedc9275bd57bc75c2153674a540bbce Mon Sep 17 00:00:00 2001 +From: "Dmitry V. Levin" +Date: Thu, 18 May 2017 17:19:25 +0300 +Subject: [PATCH] quotaops: check return code of ftruncate and lseek calls +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +ftruncate and lseek syscalls may fail for different reasons, +do not ignore these errors. Create a helper function and use it +instead of duplicating error checks and diagnostic messages. + +Signed-off-by: Dmitry V. Levin +Signed-off-by: Jan Kara +Signed-off-by: Petr Písař +--- + quotaops.c | 53 +++++++++++++++++++++++++++++------------------------ + 1 file changed, 29 insertions(+), 24 deletions(-) + +diff --git a/quotaops.c b/quotaops.c +index 6f245b7..81d7be0 100644 +--- a/quotaops.c ++++ b/quotaops.c +@@ -252,6 +252,28 @@ int editprivs(char *tmpfile) + } + + /* ++ * Duplicate a file descriptor, resetting the file offset. ++ * If it's a write descriptor, also truncate the file. ++ */ ++static FILE *dup_file(int fd, int is_write) ++{ ++ FILE *fp; ++ ++ if (is_write && ftruncate(fd, 0)) ++ die(1, _("Cannot truncate a file: %s\n"), strerror(errno)); ++ if (lseek(fd, 0, SEEK_SET)) ++ die(1, _("Cannot reset a file offset: %s\n"), strerror(errno)); ++ if ((fd = dup(fd)) < 0) ++ die(1, _("Cannot duplicate a file descriptor: %s\n"), strerror(errno)); ++ if (!(fp = fdopen(fd, is_write ? "w" : "r"))) ++ die(1, is_write ? _("Cannot open a stream to write to: %s\n") ++ : _("Cannot open a stream to read from: %s\n"), ++ strerror(errno)); ++ ++ return fp; ++} ++ ++/* + * Convert a dquot list to an ASCII file. + */ + int writeprivs(struct dquot *qlist, int outfd, char *name, int quotatype) +@@ -259,10 +281,7 @@ int writeprivs(struct dquot *qlist, int outfd, char *name, int quotatype) + struct dquot *q; + FILE *fd; + +- ftruncate(outfd, 0); +- lseek(outfd, 0, SEEK_SET); +- if (!(fd = fdopen(dup(outfd), "w"))) +- die(1, _("Cannot duplicate descriptor of file to write to: %s\n"), strerror(errno)); ++ fd = dup_file(outfd, 1); + + fprintf(fd, _("Disk quotas for %s %s (%cid %d):\n"), + _(type2name(quotatype)), name, *type2name(quotatype), qlist->dq_id); +@@ -323,9 +342,7 @@ int readprivs(struct dquot *qlist, int infd) + char inodesstring[BUFSIZ], isoftstring[BUFSIZ], ihardstring[BUFSIZ]; + const char *error; + +- lseek(infd, 0, SEEK_SET); +- if (!(fd = fdopen(dup(infd), "r"))) +- die(1, _("Cannot duplicate descriptor of temp file: %s\n"), strerror(errno)); ++ fd = dup_file(infd, 0); + + /* + * Discard title lines, then read lines to process. +@@ -435,10 +452,7 @@ int writeindividualtimes(struct dquot *qlist, int outfd, char *name, int quotaty + time_t now; + char btimestr[MAXTIMELEN], itimestr[MAXTIMELEN]; + +- ftruncate(outfd, 0); +- lseek(outfd, 0, SEEK_SET); +- if (!(fd = fdopen(dup(outfd), "w"))) +- die(1, _("Cannot duplicate descriptor of file to write to: %s\n"), strerror(errno)); ++ fd = dup_file(outfd, 1); + + fprintf(fd, _("Times to enforce softlimit for %s %s (%cid %d):\n"), + _(type2name(quotatype)), name, *type2name(quotatype), qlist->dq_id); +@@ -478,9 +492,7 @@ int readindividualtimes(struct dquot *qlist, int infd) + char iunits[BUFSIZ], bunits[BUFSIZ]; + time_t now, bseconds, iseconds; + +- lseek(infd, 0, SEEK_SET); +- if (!(fd = fdopen(dup(infd), "r"))) +- die(1, _("Cannot duplicate descriptor of temp file: %s\n"), strerror(errno)); ++ fd = dup_file(infd, 0); + + /* + * Discard title lines, then read lines to process. +@@ -543,10 +555,7 @@ int writetimes(struct quota_handle **handles, int outfd) + if (!handles[0]) + return 0; + +- ftruncate(outfd, 0); +- lseek(outfd, 0, SEEK_SET); +- if ((fd = fdopen(dup(outfd), "w")) == NULL) +- die(1, _("Cannot duplicate descriptor of file to edit: %s\n"), strerror(errno)); ++ fd = dup_file(outfd, 1); + + fprintf(fd, _("Grace period before enforcing soft limits for %ss:\n"), + _(type2name(handles[0]->qh_type))); +@@ -575,12 +584,8 @@ int readtimes(struct quota_handle **handles, int infd) + + if (!handles[0]) + return 0; +- lseek(infd, 0, SEEK_SET); +- if (!(fd = fdopen(dup(infd), "r"))) { +- errstr(_("Cannot reopen temp file: %s\n"), +- strerror(errno)); +- return -1; +- } ++ ++ fd = dup_file(infd, 0); + + /* Set all grace times to default values */ + for (i = 0; handles[i]; i++) { +-- +2.9.4 + diff --git a/quota.spec b/quota.spec index f2de8f8..589f0aa 100644 --- a/quota.spec +++ b/quota.spec @@ -64,6 +64,8 @@ Patch10: quota-4.03-quotacheck-fix-ask_yn-UB-when-fgets-returns-NULL.patch Patch11: quota-4.03-quotaops-check-setgid-setuid-return-code.patch # Check for failures when reading edquota input, in upstream after 4.03 Patch12: quota-4.03-quotaops-check-return-code-of-fgets-calls.patch +# Check for failures when duplicating a file handle, in upstream after 4.03 +Patch13: quota-4.03-quotaops-check-return-code-of-ftruncate-and-lseek-ca.patch BuildRequires: autoconf BuildRequires: automake BuildRequires: bash @@ -183,6 +185,7 @@ Linux/UNIX environment. %patch10 -p1 %patch11 -p1 %patch12 -p1 +%patch13 -p1 # Unpack forgotten LDAP scripts tar -xzkf %{SOURCE5} # Regenerate build scripts, also because of Respect-enviroment-CFLAGS.patch @@ -301,6 +304,7 @@ make check - Fix an undefined behavior on parsing yes-no answer - Check for setuid and setgid calls failure in edquota tool - Check for failures when reading edquota input +- Check for failures when duplicating a file handle * Thu Nov 10 2016 Petr Pisar - 1:4.03-4 - Fix checking a block read error (upstream bug #123)