summaryrefslogtreecommitdiff
path: root/lib/compat
diff options
context:
space:
mode:
authorGuillem Jover <guillem@debian.org>2012-01-11 07:29:28 +0100
committerGuillem Jover <guillem@debian.org>2012-01-11 08:55:53 +0100
commitbf44310d7638581b22c89922c354c60367075535 (patch)
tree374d1a3aecde1e9a8b125c6161ad442518cb311e /lib/compat
parent246c8223a6003af989b16f29dfd48d9415ea7dd8 (diff)
downloaddpkg-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>
Diffstat (limited to 'lib/compat')
-rw-r--r--lib/compat/vsnprintf.c12
1 files changed, 11 insertions, 1 deletions
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;