File bsc1179191_CVE-2020-28935_19f8f4d9.patch of Package libunbound-devel-mini.32015

commit 19f8f4d9f99a44906ab9dcc46d44da299fde3506
Author: W.C.A. Wijngaards <wouter@nlnetlabs.nl>
Date:   Mon Nov 23 13:48:04 2020 +0100

    Further fix for CVE-2020-28935, so the chown is omitted when the pidfile
    fails due to a symlink.

commit ad387832979b6ce4c93f64fe706301cd7d034e87
Author: W.C.A. Wijngaards <wouter@nlnetlabs.nl>
Date:   Mon Nov 23 13:42:11 2020 +0100

    - Fix for #303 CVE-2020-28935 : Fix that symlink does not interfere
      with chown of pidfile.
---
 daemon/unbound.c |   52 +++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 35 insertions(+), 17 deletions(-)

--- daemon/unbound.c
+++ daemon/unbound.c	2022-01-19 08:17:55.765153598 +0000
@@ -323,22 +323,39 @@ readpid (const char* file)
 /** write pid to file. 
  * @param pidfile: file name of pid file.
  * @param pid: pid to write to file.
+ * @return false on failure
  */
-static void
+static int
 writepid (const char* pidfile, pid_t pid)
 {
-	FILE* f;
-
-	if ((f = fopen(pidfile, "w")) ==  NULL ) {
+	int fd;
+	char pidbuf[32];
+	size_t count = 0;
+	snprintf(pidbuf, sizeof(pidbuf), "%lu\n", (unsigned long)pid);
+
+	if((fd = open(pidfile, O_WRONLY | O_CREAT | O_TRUNC
+#ifdef O_NOFOLLOW
+		| O_NOFOLLOW
+#endif
+		, 0644)) == -1) {
 		log_err("cannot open pidfile %s: %s", 
 			pidfile, strerror(errno));
-		return;
+		return 0;
 	}
-	if(fprintf(f, "%lu\n", (unsigned long)pid) < 0) {
-		log_err("cannot write to pidfile %s: %s", 
-			pidfile, strerror(errno));
+	while(count < strlen(pidbuf)) {
+		ssize_t r = write(fd, pidbuf+count, strlen(pidbuf)-count);
+		if(r == -1) {
+			if(errno == EAGAIN || errno == EINTR)
+				continue;
+			log_err("cannot write to pidfile %s: %s",
+				pidfile, strerror(errno));
+			close(fd);
+			return 0;
+		}
+		count += r;
 	}
-	fclose(f);
+	close(fd);
+	return 1;
 }
 
 /**
@@ -473,16 +490,17 @@ perform_setup(struct daemon* daemon, str
 	/* write new pidfile (while still root, so can be outside chroot) */
 #ifdef HAVE_KILL
 	if(cfg->pidfile && cfg->pidfile[0] && need_pidfile) {
-		writepid(daemon->pidfile, getpid());
-		if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1 &&
-			pidinchroot) {
+		if(writepid(daemon->pidfile, getpid())) {
+			if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1 &&
+				pidinchroot) {
 #  ifdef HAVE_CHOWN
-			if(chown(daemon->pidfile, cfg_uid, cfg_gid) == -1) {
-				verbose(VERB_QUERY, "cannot chown %u.%u %s: %s",
-					(unsigned)cfg_uid, (unsigned)cfg_gid,
-					daemon->pidfile, strerror(errno));
-			}
+				if(chown(daemon->pidfile, cfg_uid, cfg_gid) == -1) {
+					verbose(VERB_QUERY, "cannot chown %u.%u %s: %s",
+						(unsigned)cfg_uid, (unsigned)cfg_gid,
+						daemon->pidfile, strerror(errno));
+				}
 #  endif /* HAVE_CHOWN */
+			}
 		}
 	}
 #else
openSUSE Build Service is sponsored by