diff options
author | Guillem Jover <guillem@debian.org> | 2012-01-11 07:29:28 +0100 |
---|---|---|
committer | Guillem Jover <guillem@debian.org> | 2012-01-11 08:55:53 +0100 |
commit | bf44310d7638581b22c89922c354c60367075535 (patch) | |
tree | 374d1a3aecde1e9a8b125c6161ad442518cb311e | |
parent | 246c8223a6003af989b16f29dfd48d9415ea7dd8 (diff) | |
download | dpkg-bf44310d7638581b22c89922c354c60367075535.tar.gz |
libcompat: Use a different temporary file per process on vsnprintf()
Avoid race conditions from childs after fork(2).
Closes: #655411
Reported-by: Daniel Ruoso <daniel@ruoso.com>
-rw-r--r-- | debian/changelog | 3 | ||||
-rw-r--r-- | lib/compat/vsnprintf.c | 12 |
2 files changed, 14 insertions, 1 deletions
diff --git a/debian/changelog b/debian/changelog index 1164bdd8a..dfb3fa4a0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -47,6 +47,9 @@ dpkg (1.16.2) UNRELEASED; urgency=low Closes: #192619, #427945 * Add support for virtual output source:Package and source:Version fields. Closes: #653575 + * Use a different temporary file per process on libcompat's vsnprintf() + function to avoid race conditions from childs after fork(3). + Reported by Daniel Ruoso <daniel@ruoso.com>. Closes: #655411 [ Raphaël Hertzog ] * Update Dpkg::Shlibs to look into multiarch paths when cross-building diff --git a/lib/compat/vsnprintf.c b/lib/compat/vsnprintf.c index c7f100adb..5661bce7c 100644 --- a/lib/compat/vsnprintf.c +++ b/lib/compat/vsnprintf.c @@ -2,7 +2,7 @@ * libcompat - system compatibility library * * Copyright © 1995 Ian Jackson <ian@chiark.greenend.org.uk> - * Copyright © 2008, 2009 Guillem Jover <guillem@debian.org> + * Copyright © 2008-2012 Guillem Jover <guillem@debian.org> * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +20,8 @@ #include <config.h> +#include <sys/types.h> + #include <unistd.h> #include <stdarg.h> #include <stdio.h> @@ -28,6 +30,7 @@ int vsnprintf(char *buf, size_t maxsize, const char *fmt, va_list args) { static FILE *file = NULL; + static pid_t file_pid; size_t want, nr; int total; @@ -35,10 +38,17 @@ vsnprintf(char *buf, size_t maxsize, const char *fmt, va_list args) if (maxsize != 0 && buf == NULL) return -1; + /* Avoid race conditions from childs after a fork(2). */ + if (file_pid > 0 && file_pid != getpid()) { + fclose(file); + file = NULL; + } + if (!file) { file = tmpfile(); if (!file) return -1; + file_pid = getpid(); } else { if (fseek(file, 0, 0)) return -1; |