From 1207e36d0a8674d6c627bb9b2759faf1e290e13e Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 15 Apr 2009 13:05:09 -0400 Subject: [PATCH] libuuid: Close all file descriptors before running uuidd This avoids problems when the calling program has open file descriptors (especially sockets) open. Also fix up some warn_unused_result warnings from gcc. Addresses-Launchpad-bug: #305057 Signed-off-by: "Theodore Ts'o" --- configure | 4 +++- configure.in | 2 +- lib/uuid/gen_uuid.c | 39 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/configure b/configure index a6b787b..cf1bc1b 100755 --- a/configure +++ b/configure @@ -14712,7 +14712,9 @@ fi -for ac_func in chflags getrusage llseek lseek64 open64 fstat64 ftruncate64 getmntinfo strtoull strcasecmp srandom jrand48 fchown mallinfo fdatasync strnlen strptime strdup sysconf pathconf posix_memalign memalign valloc __secure_getenv prctl mmap utime setresuid setresgid usleep nanosleep + + +for ac_func in chflags getrusage llseek lseek64 open64 fstat64 ftruncate64 getmntinfo strtoull strcasecmp srandom jrand48 fchown mallinfo fdatasync strnlen strptime strdup sysconf pathconf posix_memalign memalign valloc __secure_getenv prctl mmap utime setresuid setresgid usleep nanosleep getdtablesize getrlimit do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 diff --git a/configure.in b/configure.in index 2534df4..caf2cb4 100644 --- a/configure.in +++ b/configure.in @@ -701,7 +701,7 @@ AC_CHECK_MEMBER(struct sockaddr.sa_len, [#include #include ]) dnl -AC_CHECK_FUNCS(chflags getrusage llseek lseek64 open64 fstat64 ftruncate64 getmntinfo strtoull strcasecmp srandom jrand48 fchown mallinfo fdatasync strnlen strptime strdup sysconf pathconf posix_memalign memalign valloc __secure_getenv prctl mmap utime setresuid setresgid usleep nanosleep) +AC_CHECK_FUNCS(chflags getrusage llseek lseek64 open64 fstat64 ftruncate64 getmntinfo strtoull strcasecmp srandom jrand48 fchown mallinfo fdatasync strnlen strptime strdup sysconf pathconf posix_memalign memalign valloc __secure_getenv prctl mmap utime setresuid setresgid usleep nanosleep getdtablesize getrlimit) dnl dnl Check to see if -lsocket is required (solaris) to make something dnl that uses socket() to compile; this is needed for the UUID library diff --git a/lib/uuid/gen_uuid.c b/lib/uuid/gen_uuid.c index a3052d4..b7a12ee 100644 --- a/lib/uuid/gen_uuid.c +++ b/lib/uuid/gen_uuid.c @@ -86,6 +86,9 @@ #if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H) #include #endif +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif #include "uuidP.h" #include "uuidd.h" @@ -311,6 +314,7 @@ static int get_clock(uint32_t *clock_high, uint32_t *clock_low, struct flock fl; uint64_t clock_reg; mode_t save_umask; + int len; if (state_fd == -2) { save_umask = umask(0); @@ -392,10 +396,14 @@ try_again: if (state_fd > 0) { rewind(state_f); - ftruncate(state_fd, 0); - fprintf(state_f, "clock: %04x tv: %lu %lu adj: %d\n", - clock_seq, last.tv_sec, last.tv_usec, adjustment); + len = fprintf(state_f, + "clock: %04x tv: %016lu %08lu adj: %08d\n", + clock_seq, last.tv_sec, last.tv_usec, adjustment); fflush(state_f); + if (ftruncate(state_fd, len) < 0) { + fprintf(state_f, " \n"); + fflush(state_f); + } rewind(state_f); fl.l_type = F_UNLCK; fcntl(state_fd, F_SETLK, &fl); @@ -427,6 +435,30 @@ static ssize_t read_all(int fd, char *buf, size_t count) return c; } +/* + * Close all file descriptors + */ +static void close_all_fds(void) +{ + int i, max; + +#if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX) + max = sysconf(_SC_OPEN_MAX); +#elif defined(HAVE_GETDTABLESIZE) + max = getdtablesize(); +#elif defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) + struct rlimit rl; + + getrlimit(RLIMIT_NOFILE, &rl); + max = rl.rlim_cur; +#else + max = OPEN_MAX; +#endif + + for (i=0; i < max; i++) + close(i); +} + /* * Try using the uuidd daemon to generate the UUID @@ -459,6 +491,7 @@ static int get_uuid_via_daemon(int op, uuid_t out, int *num) access_ret = access(uuidd_path, X_OK); if (access_ret == 0 && start_attempts++ < 5) { if ((pid = fork()) == 0) { + close_all_fds(); execl(uuidd_path, "uuidd", "-qT", "300", (char *) NULL); exit(1); -- 1.8.3.1