--- prelink/src/main.c.bak 2007-10-03 18:40:09.000000000 +0300 +++ prelink/src/main.c 2010-04-15 21:27:51.923577422 +0300 @@ -35,6 +35,7 @@ int all; int force; int verbose; int print_cache; +int do_fsync; int reloc_only; GElf_Addr reloc_base; int no_update; @@ -94,6 +95,7 @@ static struct argp_option options[] = { {"quick", 'q', 0, 0, "Quick scan" }, {"random", 'R', 0, 0, "Choose random base for libraries" }, {"reloc-only", 'r', "BASE_ADDRESS", 0, "Relocate library to given address, don't prelink" }, + {"fsync", 's', 0, 0, "fsync written libraries and binaries prior to rename" }, {"undo", 'u', 0, 0, "Undo prelink" }, {"verbose", 'v', 0, 0, "Produce verbose output" }, {"verify", 'y', 0, 0, "Verify file consistency by undoing and redoing prelink and printing original to standard output" }, @@ -143,17 +145,20 @@ parse_opt (int key, char *arg, struct ar case 'R': random_base |= 1; break; + case 's': + do_fsync = 1; + break; case OPT_SEED: random_base |= 2; seed = strtoull (arg, &endarg, 0); if (endarg != strchr (arg, '\0')) - error (EXIT_FAILURE, 0, "--seed option requires numberic argument"); + error (EXIT_FAILURE, 0, "--seed option requires numeric argument"); break; case 'r': reloc_only = 1; reloc_base = strtoull (arg, &endarg, 0); if (endarg != strchr (arg, '\0')) - error (EXIT_FAILURE, 0, "-r option requires numberic argument"); + error (EXIT_FAILURE, 0, "-r option requires numeric argument"); break; case 'h': dereference = 1; --- prelink/src/dso.c.bak 2010-04-13 17:41:15.000000000 +0300 +++ prelink/src/dso.c 2010-04-15 21:30:04.934577073 +0300 @@ -1612,7 +1612,12 @@ relocate_dso (DSO *dso, GElf_Addr base) static int close_dso_1 (DSO *dso) { - if (dso_is_rdwr (dso)) + int ret = 0; + int rdwr; + + rdwr = dso_is_rdwr (dso); + + if (rdwr) { int i; @@ -1630,11 +1635,19 @@ close_dso_1 (DSO *dso) } elf_end (dso->elf); - close (dso->fd); + if (rdwr && do_fsync) + { + if (fsync (dso->fd) != 0) ret = 1; + } + if (close (dso->fd) != 0) ret = 1; if (dso->elfro) { elf_end (dso->elfro); - close (dso->fdro); + if (rdwr && do_fsync) + { + if (fsync (dso->fdro) != 0) ret = 1; + } + if (close (dso->fdro) != 0) ret = 1; } if (dso->filename != dso->soname) free ((char *) dso->soname); @@ -1644,7 +1657,7 @@ close_dso_1 (DSO *dso) free (dso->adjust); free (dso->undo.d_buf); free (dso); - return 0; + return ret; } int @@ -1654,8 +1667,7 @@ close_dso (DSO *dso) if (rdwr && dso->temp_filename != NULL) unlink (dso->temp_filename); - close_dso_1 (dso); - return 0; + return close_dso_1 (dso); } int @@ -1775,7 +1787,12 @@ update_dso (DSO *dso, const char *orig_n fdin = dup (dso->fd); else fdin = -1; - close_dso_1 (dso); + if (close_dso_1 (dso)) + { + unlink (name2); + error (0, EIO, "Could not fsync/close %s", name2); + return 1; + } u.actime = time (NULL); u.modtime = st.st_mtime; utime (name2, &u); --- prelink/src/cache.c.bak 2006-10-23 13:26:26.000000000 +0300 +++ prelink/src/cache.c 2010-04-15 21:27:51.953576074 +0300 @@ -681,6 +681,7 @@ prelink_save_cache (int do_warn) if (write (fd, &cache, sizeof (cache)) != sizeof (cache) || write (fd, data, len) != len + || fsync (fd) != 0 || fchmod (fd, 0644) || close (fd) || rename (prelink_cache_tmp, prelink_cache)) --- prelink/src/execstack.c.bak 2010-04-12 20:26:07.000000000 +0300 +++ prelink/src/execstack.c 2010-04-15 21:27:51.978576240 +0300 @@ -31,6 +31,7 @@ int set; int execflag; +int do_fsync; const char *argp_program_version = "execstack 1.0"; @@ -44,6 +45,7 @@ static struct argp_option options[] = { {"clear-execstack", 'c', 0, 0, "Clear executable stack flag bit" }, {"noexecstack", 'c', 0, OPTION_HIDDEN, "" }, {"query", 'q', 0, 0, "Query executable stack flag bit" }, + {"fsync", 'f', 0, 0, "fsync written binaries prior to rename" }, { 0 } }; @@ -63,6 +65,9 @@ parse_opt (int key, char *arg, struct ar case 'q': set = 0; break; + case 'f': + do_fsync = 1; + break; default: return ARGP_ERR_UNKNOWN; } --- prelink/src/prelink.h.bak 2010-04-12 20:24:00.000000000 +0300 +++ prelink/src/prelink.h 2010-04-15 21:27:52.003575794 +0300 @@ -535,6 +535,7 @@ extern int exec_shield; extern int undo; extern int verify; extern int print_cache; +extern int do_fsync; enum verify_method_t { VERIFY_CONTENT, VERIFY_MD5, VERIFY_SHA }; extern enum verify_method_t verify_method; extern int quick;