Makefile.config
config.h
fips
-libfips.so
+libfips-32.so
+libfips-64.so
*.o
*~
# Smash together user's values with our extra values
FINAL_CFLAGS = -DFIPS_VERSION=$(VERSION) $(CFLAGS) $(WARN_CFLAGS) $(CONFIGURE_CFLAGS) $(extra_cflags)
-FINAL_FIPS_LDFLAGS = $(LDFLAGS) $(AS_NEEDED_LDFLAGS) $(TALLOC_LDFLAGS)
-FINAL_LIBFIPS_LDFLAGS = $(LDFLAGS) -ldl
+FINAL_FIPS_LDFLAGS = $(LDFLAGS) $(AS_NEEDED_LDFLAGS) $(CONFIGURE_LDFLAGS)
+FINAL_LIBFIPS_LDFLAGS = $(LDFLAGS) $(CONFIGURE_LDFLAGS) -ldl
FINAL_FIPS_LINKER = CC
-ifneq ($(LINKER_RESOLVES_LIBRARY_DEPENDENCIES),1)
-FINAL_FIPS_LDFLAGS += $(CONFIGURE_LDFLAGS)
-endif
.PHONY: all
-all: fips libfips.so
+all: fips libfips-64.so libfips-32.so
ifeq ($(MAKECMDGOALS),)
ifeq ($(shell cat .first-build-message 2>/dev/null),)
# Otherwise, print the full command line.
quiet ?= $($(shell echo $1 | sed -e s'/ .*//'))
+%-32.o: %.c $(global_deps)
+ @mkdir -p .deps/$(@D)
+ $(call quiet,CC $(CFLAGS) -m32) -c $(FINAL_CFLAGS) -m32 $< -o $@ -MD -MP -MF .deps/$*.d
+
+%-64.o: %.c $(global_deps)
+ @mkdir -p .deps/$(@D)
+ $(call quiet,CC $(CFLAGS) -m64) -c $(FINAL_CFLAGS) -m64 $< -o $@ -MD -MP -MF .deps/$*.d
+
%.o: %.c $(global_deps)
@mkdir -p .deps/$(@D)
$(call quiet,CC $(CFLAGS)) -c $(FINAL_CFLAGS) $< -o $@ -MD -MP -MF .deps/$*.d
libfips_srcs = \
glxwrap.c
-libfips_modules = $(libfips_srcs:.c=.o)
+libfips_32_modules = $(libfips_srcs:.c=-32.o)
+
+libfips_64_modules = $(libfips_srcs:.c=-64.o)
+
+libfips-32.so: $(libfips_32_modules) libfips.sym
+ $(call quiet,$(FINAL_FIPS_LINKER) $(CFLAGS) -m32) $(FINAL_CFLAGS) -m32 $(libfips_32_modules) $(FINAL_LIBFIPS_LDFLAGS) $(LIBRARY_LINK_FLAGS) -o $@
-libfips.so: $(libfips_modules) libfips.sym
- $(call quiet,$(FINAL_FIPS_LINKER) $(CFLAGS)) $(FINAL_CFLAGS) $(libfips_modules) $(FINAL_LIBFIPS_LDFLAGS) $(LIBRARY_LINK_FLAGS) -o $@
+libfips-64.so: $(libfips_64_modules) libfips.sym
+ $(call quiet,$(FINAL_FIPS_LINKER) $(CFLAGS) -m64) $(FINAL_CFLAGS) -m64 $(libfips_64_modules) $(FINAL_LIBFIPS_LDFLAGS) $(LIBRARY_LINK_FLAGS) -o $@
.PHONY: install
install: all
mkdir -p $(DESTDIR)$(bindir)
install fips $(DESTDIR)$(bindir)/fips
mkdir -p $(DESTDIR)$(libdir)/fips
- install -m0644 libfips.so $(DESTDIR)$(libdir)/fips/libfips.so
+ install -m0644 libfips-32.so $(DESTDIR)$(libdir)/fips/libfips-32.so
+ install -m0644 libfips-64.so $(DESTDIR)$(libdir)/fips/libfips-64.so
ifeq ($(MAKECMDGOALS), install)
@echo ""
@echo "Fips is now installed to $(DESTDIR)$(prefix)"
endif
SRCS := $(SRCS) $(fips_srcs) $(libfips_srcs)
-CLEAN := $(CLEAN) fips $(fips_modules) $(libfips_modules)
+CLEAN := $(CLEAN) fips $(fips_modules) $(libfips_32_modules) $(libfips_64_modules)
DISTCLEAN := $(DISTCLEAN) .first-build-message Makefile.config
errors=$((errors + 1))
fi
-printf "Checking which platform we are on... "
-uname=`uname`
-if [ $uname = "Darwin" ] ; then
- printf "Mac OS X.\n"
- platform=MACOSX
- linker_resolves_library_dependencies=0
-elif [ $uname = "SunOS" ] ; then
- printf "Solaris.\n"
- platform=SOLARIS
- linker_resolves_library_dependencies=0
-elif [ $uname = "FreeBSD" ] ; then
- printf "FreeBSD.\n"
- platform=FREEBSD
- linker_resolves_library_dependencies=0
-elif [ $uname = "OpenBSD" ] ; then
- printf "OpenBSD.\n"
- platform=OPENBSD
- linker_resolves_library_dependencies=0
-elif [ $uname = "Linux" ] || [ $uname = "GNU" ] ; then
- printf "$uname\n"
- platform="$uname"
- linker_resolves_library_dependencies=1
+printf "Checking for libelf... "
+printf "#include <gelf.h>\nint main(void){return elf_version (EV_CURRENT);}\n" > elf-minimal.c
+if ${CC} -o elf-minimal elf-minimal.c -lelf > /dev/null 2>&1
+then
+ printf "Yes.\n"
+ have_libelf=1
+ libelf_cflags=
+ libelf_ldflags=-lelf
else
- printf "Unknown.\n"
- cat <<EOF
-
-*** Warning: Unknown platform. ${PROJECT} might or might not build correctly.
-
-EOF
+ printf "No.\n"
+ have_libelf=0
+ libelf_cflags=
+ libelf_ldflags=
+ errors=$((errors + 1))
fi
+rm -f elf-minimal elf-minimal.c
if [ $errors -gt 0 ]; then
cat <<EOF
echo " http://talloc.samba.org/"
echo
fi
+ if [ $have_libelf -eq 0 ]; then
+ echo " The libelf library (including development files such as headers)"
+ echo " http://http://sourceforge.net/projects/elftoolchain/"
+ echo
+ fi
cat <<EOF
With any luck, you're using a modern, package-based operating system
that has all of these packages available in the distribution. In that
On Debian and similar systems:
- sudo apt-get install libtalloc-dev
+ sudo apt-get install libtalloc-dev libelf-dev
Or on Fedora and similar systems:
- sudo yum install libtalloc-devel
+ sudo yum install libtalloc-devel libelf-devel
On other systems, similar commands can be used, but the details of the
package names may be different.
# The directory to which read-only (configuration) files should be installed
sysconfdir = ${SYSCONFDIR:=\$(prefix)/etc}
-# Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD
-PLATFORM = ${platform}
-
-# Whether the linker will automatically resolve the dependency of one
-# library on another (if not, then linking a binary requires linking
-# directly against both)
-LINKER_RESOLVES_LIBRARY_DEPENDENCIES = ${linker_resolves_library_dependencies}
-
# Flags needed to compile and link against talloc
TALLOC_CFLAGS = ${talloc_cflags}
TALLOC_LDFLAGS = ${talloc_ldflags}
+# Flags needed to compile and link against libelf
+LIBELF_CFLAGS = ${libelf_cflags}
+LIBELF_LDFLAGS = ${libelf_ldflags}
+
# Flags needed to have linker link only to necessary libraries
AS_NEEDED_LDFLAGS = ${as_needed_ldflags}
# Combined flags for compiling and linking against all of the above
-CONFIGURE_CFLAGS = \$(TALLOC_CFLAGS)
-CONFIGURE_LDFLAGS = \$(TALLOC_LDFLAGS)
+CONFIGURE_CFLAGS = \$(TALLOC_CFLAGS) \$(LIBELF_CFLAGS)
+CONFIGURE_LDFLAGS = \$(TALLOC_LDFLAGS) \$(LIBELF_LDFLAGS)
EOF
# construct config.h
#include <linux/limits.h>
+#include <fcntl.h>
+#include <gelf.h>
+
#include "execute.h"
/* Terminate a string representing a filename at the final '/' to
return 1;
}
-/* Given "library" filename resolve it to an absolute path to an
- * existing file as follows:
+/* Is the given elf program 32 or 64 bit?
+ *
+ * Note: This function aborts the current program if 'program' cannot
+ * be opened as a valid ELF file. */
+static int
+elf_bits (const char *program)
+{
+ Elf *elf;
+ GElf_Ehdr ehdr;
+ int fd, class;
+
+ fd = open (program, O_RDONLY, 0);
+ if (fd < 0) {
+ fprintf (stderr, "Failed to open %s: %s\n", program,
+ strerror (errno));
+ exit (1);
+ }
+
+ if (elf_version (EV_CURRENT ) == EV_NONE) {
+ fprintf (stderr, "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",
+ program, elf_errmsg(-1));
+ exit (1);
+ }
+
+ if (elf_kind (elf) != ELF_K_ELF) {
+ fprintf (stderr, "Not an ELF object: %s\n", program);
+ exit (1);
+ }
+
+ if (gelf_getehdr (elf, &ehdr) == NULL) {
+ fprintf (stderr, "getehdr on %s failed: %s\n",
+ program, elf_errmsg (-1));
+ exit (1);
+ }
+
+ class = gelf_getclass (elf);
+
+ if (class == ELFCLASSNONE) {
+ fprintf (stderr, "getclass on %s failed: %s\n", program,
+ elf_errmsg (-1));
+ exit (1);
+ }
+
+ if (class == ELFCLASS32)
+ return 32;
+ else
+ return 64;
+
+}
+
+/* Find the appropriate path to the libfips wrapper.
+ *
+ * This involves, first, examining the elf header of the 'program'
+ * binary to be executed to know whether we should look for
+ * libfips-32.so or libfips-64.so.
+ *
+ * Next, we find the absolute patch containing the library as follows:
*
* 1. Look in same directory as current executable image
*
* Returns: a string talloc'ed to 'ctx'
*/
static char *
-resolve_path (void *ctx, const char *library)
+find_libfips_path (void *ctx, const char *program)
{
- char *bin_path, *lib_path;
+ char *bin_path, *library, *lib_path;
+ int bits;
+
+ bits = elf_bits (program);
+
+ library = talloc_asprintf(ctx, "libfips-%d.so", bits);
bin_path = get_bin_name (ctx);
exit (1);
}
-/* After forking, set LD_PRELOAD to preload "library" within child
- * environment, then exec given arguments.
- *
- * The "library" argument is the filename (without path) of a shared
- * library to load. The complete path will be resolved with
- * resolve_library_path above. */
+/* After forking, set LD_PRELOAD to preload libfips-{32,64}.so within
+ * child environment, then exec given arguments.
+ */
static int
-fork_exec_with_preload_and_wait (char * const argv[], const char *library)
+fork_exec_with_fips_preload_and_wait (char * const argv[])
{
pid_t pid;
int i, status;
void *ctx = talloc_new (NULL);
char *lib_path;
- lib_path = resolve_path (ctx, library);
+ lib_path = find_libfips_path (ctx, argv[0]);
setenv ("LD_PRELOAD", lib_path, 1);
}
int
-execute_with_preload (int argc, char * const argv[], const char *library)
+execute_with_fips_preload (int argc, char * const argv[])
{
char **execvp_args;
int i;
/* execvp needs final NULL */
execvp_args[i] = NULL;
- return fork_exec_with_preload_and_wait (execvp_args, library);
+ return fork_exec_with_fips_preload_and_wait (execvp_args);
}
#define EXECUTE_H
/* Execute the program with arguments as specified, but with the
- * library specified in "library" pre-loaded. The library should be
- * specified as the compiled filename (such as libfips.so).
+ * fips library specified as an LD_PRELOAD.
*/
int
-execute_with_preload (int argc, char * const argv[], const char *library);
+execute_with_fips_preload (int argc, char * const argv[]);
#endif
exit (1);
}
- ret = execute_with_preload (argc - optind, &argv[optind], "libfips.so");
+ ret = execute_with_fips_preload (argc - optind, &argv[optind]);
return ret;
}