* THE SOFTWARE.
*/
-#include "config.h"
+#include "fips.h"
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <gelf.h>
#include "execute.h"
+#include "xmalloc.h"
/* Terminate a string representing a filename at the final '/' to
* eliminate the final filename component, (leaving only the directory
* of the filename being linked to). Go figure. */
int name_len = PATH_MAX + 1;
- name = talloc_size (ctx, name_len - 1);
+ name = talloc_size (ctx, name_len);
if (name == NULL) {
fprintf (stderr, "Out of memory.\n");
exit (1);
}
- name_len = readlink (link, name, name_len);
+ name_len = readlink (link, name, name_len - 1);
if (name_len < 0) {
- fprintf (stderr, "Failed to readlink %s: %s\n", link,
+ fprintf (stderr, "fips: Error: Failed to readlink %s: %s\n", link,
strerror (errno));
exit (1);
}
- name[name_len + 1] = '\0';
+ name[name_len] = '\0';
return name;
}
fd = open (absolute_program, O_RDONLY, 0);
if (fd < 0) {
- fprintf (stderr, "Failed to open %s: %s\n", absolute_program,
+ fprintf (stderr, "fips: Failed to open %s: %s\n", absolute_program,
strerror (errno));
exit (1);
}
if (elf_version (EV_CURRENT ) == EV_NONE) {
- fprintf (stderr, "Failed to initialize elf library: %s\n",
+ fprintf (stderr, "fips: Failed to initialize elf library: %s\n",
elf_errmsg (-1));
exit (1);
}
elf = elf_begin (fd, ELF_C_READ, NULL);
if (elf == NULL) {
- fprintf (stderr, "Call to elf_begin on %s failed: %s\n",
+ fprintf (stderr, "fips: Call to elf_begin on %s failed: %s\n",
absolute_program, elf_errmsg(-1));
exit (1);
}
if (elf_kind (elf) != ELF_K_ELF) {
- fprintf (stderr, "Not an ELF object: %s\n", absolute_program);
+ fprintf (stderr, "fips: Not an ELF object: %s\n", absolute_program);
exit (1);
}
if (gelf_getehdr (elf, &ehdr) == NULL) {
- fprintf (stderr, "getehdr on %s failed: %s\n",
+ fprintf (stderr, "fips: getehdr on %s failed: %s\n",
absolute_program, elf_errmsg (-1));
exit (1);
}
class = gelf_getclass (elf);
if (class == ELFCLASSNONE) {
- fprintf (stderr, "getclass on %s failed: %s\n",
+ fprintf (stderr, "fips: getclass on %s failed: %s\n",
absolute_program, elf_errmsg (-1));
exit (1);
}
"\t%s\n"
"and\n"
"\t%s/" BINDIR_TO_LIBFIPSDIR "\n", bin_path, bin_path);
- exit (1);
-}
-
-/* After forking, set LD_PRELOAD to preload libfips-{32,64}.so within
- * child environment, then exec given arguments.
- */
-static int
-fork_exec_with_fips_preload_and_wait (char * const argv[])
-{
- pid_t pid;
- int i, status;
-
- pid = fork ();
- /* Child */
- if (pid == 0) {
- void *ctx = talloc_new (NULL);
- char *lib_path;
-
- lib_path = find_libfips_path (ctx, argv[0]);
-
- setenv ("LD_PRELOAD", lib_path, 1);
-
- talloc_free (ctx);
-
- execvp (argv[0], argv);
- fprintf (stderr, "Failed to execute:");
- for (i = 0; argv[i]; i++) {
- fprintf (stderr, " %s", argv[i]);
- }
- fprintf (stderr, "\n");
- exit (1);
- }
-
- /* Parent */
- waitpid (pid, &status, 0);
- if (WIFEXITED (status)) {
- return (WEXITSTATUS (status));
- }
- if (WIFSIGNALED (status)) {
- fprintf (stderr, "Child terminated by signal %d\n",
- WTERMSIG (status));
- }
- return 1;
+ fprintf(stderr, "\nIt's possible fips was not compiled with support for %d-bit applications.\n", bits);
+ fprintf(stderr, "Perhaps you need to install gcc-multilib and re-compile fips?\n");
+ exit (1);
}
int
execute_with_fips_preload (int argc, char * const argv[])
{
+ void *ctx = talloc_new (NULL);
+ char *lib_path;
+ char *ld_preload_value;
char **execvp_args;
int i;
- execvp_args = malloc((argc + 1) * sizeof(char *));
- if (execvp_args == NULL) {
- fprintf (stderr, "Out of memory,\n");
- return 1;
- }
+ execvp_args = xmalloc((argc + 1) * sizeof(char *));
for (i = 0; i < argc; i++) {
execvp_args[i] = argv[i];
/* execvp needs final NULL */
execvp_args[i] = NULL;
- return fork_exec_with_fips_preload_and_wait (execvp_args);
+ lib_path = find_libfips_path (ctx, argv[0]);
+
+ ld_preload_value = getenv ("LD_PRELOAD");
+
+ if (ld_preload_value) {
+ ld_preload_value = talloc_asprintf(ctx, "%s:%s",
+ ld_preload_value,
+ lib_path);
+ } else {
+ ld_preload_value = lib_path;
+ }
+
+ setenv ("LD_PRELOAD", ld_preload_value, 1);
+
+ talloc_free (ctx);
+
+ execvp (argv[0], argv);
+ fprintf (stderr, "Failed to execute:");
+ for (i = 0; argv[i]; i++) {
+ fprintf (stderr, " %s", argv[i]);
+ }
+ fprintf (stderr, "\n");
+ exit (1);
}