diff options
Diffstat (limited to 'trunk/src/main.c')
-rw-r--r-- | trunk/src/main.c | 82 |
1 files changed, 76 insertions, 6 deletions
diff --git a/trunk/src/main.c b/trunk/src/main.c index 144ce84..4678ba4 100644 --- a/trunk/src/main.c +++ b/trunk/src/main.c @@ -58,12 +58,14 @@ const char *ld_library_path; const char *prelink_conf = PRELINK_CONF; const char *prelink_cache = PRELINK_CACHE; const char *undo_output; +int noreexecinit; +time_t initctime; -const char *argp_program_version = "prelink 1.0"; +const char *argp_program_version = PRELINK_PROG PKGVERSION " 1.0"; -const char *argp_program_bug_address = "<jakub@redhat.com>"; +const char *argp_program_bug_address = REPORT_BUGS_TO; -static char argp_doc[] = "prelink -- program to relocate and prelink ELF shared libraries and programs"; +static char argp_doc[] = PRELINK_PROG " -- program to relocate and prelink ELF shared libraries and programs"; #define OPT_DYNAMIC_LINKER 0x80 #define OPT_LD_LIBRARY_PATH 0x81 @@ -77,6 +79,8 @@ static char argp_doc[] = "prelink -- program to relocate and prelink ELF shared #define OPT_MD5 0x89 #define OPT_SHA 0x8a #define OPT_COMPUTE_CHECKSUM 0x8b +#define OPT_SYSROOT 0x8c +#define OPT_RTLD 0x8d static struct argp_option options[] = { {"all", 'a', 0, 0, "Prelink all binaries" }, @@ -94,6 +98,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" }, + {"root", OPT_SYSROOT, "ROOT_PATH", 0, "Prefix all paths with ROOT_PATH" }, {"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" }, @@ -111,6 +116,8 @@ static struct argp_option options[] = { {"mmap-region-end", OPT_MMAP_REG_END, "BASE_ADDRESS", OPTION_HIDDEN, "" }, {"seed", OPT_SEED, "SEED", OPTION_HIDDEN, "" }, {"compute-checksum", OPT_COMPUTE_CHECKSUM, 0, OPTION_HIDDEN, "" }, + {"rtld", OPT_RTLD, "RTLD", OPTION_HIDDEN, "" }, + {"init", 'i', 0, 0, "Do not re-execute init" }, { 0 } }; @@ -222,14 +229,39 @@ parse_opt (int key, char *arg, struct argp_state *state) case OPT_COMPUTE_CHECKSUM: compute_checksum = 1; break; + case OPT_SYSROOT: + sysroot = arg; + break; + case OPT_RTLD: + prelink_rtld = arg; + break; + case 'i': + noreexecinit=1; + break; default: return ARGP_ERR_UNKNOWN; } return 0; } +time_t get_ctime(const char *file) { + struct stat st; + if(stat(file,&st) == 0) + return st.st_ctime; + return 0; +} + +void checkinit() { + if(initctime != get_ctime("/sbin/init")) { + printf("Executing /sbin/init U\n"); + system("/sbin/init U"); + } +} + static struct argp argp = { options, parse_opt, "[FILES]", argp_doc }; +const char *prelink_rtld = NULL; + int main (int argc, char *argv[]) { @@ -237,9 +269,7 @@ main (int argc, char *argv[]) setlocale (LC_ALL, ""); - /* Set the default for exec_shield. */ - if (! access ("/proc/sys/kernel/exec-shield", F_OK)) - exec_shield = 1; + exec_shield = 2; prelink_init_cache (); @@ -247,6 +277,11 @@ main (int argc, char *argv[]) argp_parse (&argp, argc, argv, 0, &remaining, 0); + if(!noreexecinit) { + initctime = get_ctime("/sbin/init"); + atexit(checkinit); + } + if (ld_library_path == NULL) ld_library_path = getenv ("LD_LIBRARY_PATH"); @@ -261,6 +296,41 @@ main (int argc, char *argv[]) if ((undo || verify) && quick) error (EXIT_FAILURE, 0, "--undo and --quick options are incompatible"); + /* Set the default for exec_shield. */ + if (exec_shield == 2) + { + if (sysroot == NULL && ! access ("/proc/sys/kernel/exec-shield", F_OK)) + exec_shield = 1; + else + exec_shield = 0; + } + +#ifdef DEFAULT_SYSROOT + if (sysroot == NULL) + { + extern char *make_relative_prefix (const char *, const char *, const char *); + sysroot = make_relative_prefix (argv[0], BINDIR, DEFAULT_SYSROOT); + } +#endif + + if (sysroot) + { + sysroot = canonicalize_file_name (sysroot); + if (sysroot == NULL) + error (EXIT_FAILURE, 0, "Could not canonicalize --root argument"); + asprintf ((char **) &prelink_conf, "%s%s", sysroot, prelink_conf); + } + if (prelink_rtld != NULL && prelink_rtld[0] == 0) + prelink_rtld = NULL; + else + if (prelink_rtld == NULL) + { + extern char *make_relative_prefix (const char *, const char *, const char *); + const char *path = make_relative_prefix (argv[0], BINDIR, BINDIR); + asprintf ((char **) &prelink_rtld, "%s/%s", path, + PRELINK_RTLD_PROG EXEEXT); + } + if (print_cache) { prelink_load_cache (); |