public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 3/3] libctf: look for a qsort_r that functions properly
  2019-06-03 20:48 [PATCH 1/3] libctf: fix the type of ctf_enum.cte_value Nick Alcock
  2019-06-03 20:48 ` [PATCH 2/3] libctf: fix use-after-free in function dumping Nick Alcock
@ 2019-06-03 20:48 ` Nick Alcock
  2019-06-04  9:55   ` Florian Weimer
  2019-06-05 10:25   ` Pedro Alves
  1 sibling, 2 replies; 7+ messages in thread
From: Nick Alcock @ 2019-06-03 20:48 UTC (permalink / raw)
  To: binutils; +Cc: jose.marchesi, John.W.Marshall, sebastian.huber

We cannot just look for any declaration of qsort_r, because some
operating systems have a qsort_r that has a different prototype
but which still has a pair of pointers in the right places (the last two
args are interchanged), so we cannot rely on compilation errors to flag
up a problem.

So, instead, use AC_RUN_IFELSE to check for the function of qsort_r(),
passing function pointers in to both args and making sure that we never
actually dereference the arg pointer.

This may still be problematic on systems with different representations
for function pointers and integer pointers, but even then we should get
the right result from configure (there just might be an ugly coredump
too).

(Now we are not using AC_LIBOBJ any more, we can use a better name for
the qsort_r replacement as well.)

libctf/
	* qsort_r.c: Rename to...
	* ctf-qsort_r.c: ... this.
	(_quicksort): Define to ctf_qsort_r.
	* ctf-decls.h (qsort_r): Remove.
	(ctf_qsort_r): Add.
	* Makefile.am (libctf_a_LIBADD): Remove.
	(libctf_a_SOURCES): New, add ctf-qsort_r.c.
	* ctf-archive.c (ctf_arc_write): Call ctf_qsort_r, not qsort_r.
	* ctf-create.c (ctf_update): Likewise.
	* configure.ac: Check for specific qsort_r that functions properly,
	not just for any declaration of it.
	* Makefile.in: Regenerate.
	* config.h.in: Likewise.
	* configure: Likewise.
---
 libctf/Makefile.am                  |   4 +-
 libctf/Makefile.in                  |  29 ++++---
 libctf/config.h.in                  |   7 +-
 libctf/configure                    | 115 +++++++++++++++-------------
 libctf/configure.ac                 |  30 +++++++-
 libctf/ctf-archive.c                |   9 ++-
 libctf/ctf-create.c                 |   2 +-
 libctf/ctf-decls.h                  |  16 +++-
 libctf/{qsort_r.c => ctf-qsort_r.c} |   2 +-
 9 files changed, 134 insertions(+), 80 deletions(-)
 rename libctf/{qsort_r.c => ctf-qsort_r.c} (99%)

diff --git a/libctf/Makefile.am b/libctf/Makefile.am
index 49c9f5280a..926c9919c5 100644
--- a/libctf/Makefile.am
+++ b/libctf/Makefile.am
@@ -35,4 +35,6 @@ noinst_LIBRARIES = libctf.a
 libctf_a_SOURCES = ctf-archive.c ctf-dump.c ctf-create.c ctf-decl.c ctf-error.c \
 		   ctf-hash.c ctf-labels.c ctf-lookup.c ctf-open.c ctf-open-bfd.c \
 		   ctf-subr.c ctf-types.c ctf-util.c
-libctf_a_LIBADD = $(LIBOBJS)
+if NEED_CTF_QSORT_R
+libctf_a_SOURCES += ctf-qsort_r.c
+endif
diff --git a/libctf/Makefile.in b/libctf/Makefile.in
index c2cada6616..4fea156c44 100644
--- a/libctf/Makefile.in
+++ b/libctf/Makefile.in
@@ -104,6 +104,7 @@ POST_INSTALL = :
 NORMAL_UNINSTALL = :
 PRE_UNINSTALL = :
 POST_UNINSTALL = :
+@NEED_CTF_QSORT_R_TRUE@am__append_1 = ctf-qsort_r.c
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
@@ -128,12 +129,17 @@ am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
 am__v_AR_0 = @echo "  AR      " $@;
 am__v_AR_1 = 
 libctf_a_AR = $(AR) $(ARFLAGS)
-libctf_a_DEPENDENCIES = $(LIBOBJS)
+libctf_a_LIBADD =
+am__libctf_a_SOURCES_DIST = ctf-archive.c ctf-dump.c ctf-create.c \
+	ctf-decl.c ctf-error.c ctf-hash.c ctf-labels.c ctf-lookup.c \
+	ctf-open.c ctf-open-bfd.c ctf-subr.c ctf-types.c ctf-util.c \
+	ctf-qsort_r.c
+@NEED_CTF_QSORT_R_TRUE@am__objects_1 = ctf-qsort_r.$(OBJEXT)
 am_libctf_a_OBJECTS = ctf-archive.$(OBJEXT) ctf-dump.$(OBJEXT) \
 	ctf-create.$(OBJEXT) ctf-decl.$(OBJEXT) ctf-error.$(OBJEXT) \
 	ctf-hash.$(OBJEXT) ctf-labels.$(OBJEXT) ctf-lookup.$(OBJEXT) \
 	ctf-open.$(OBJEXT) ctf-open-bfd.$(OBJEXT) ctf-subr.$(OBJEXT) \
-	ctf-types.$(OBJEXT) ctf-util.$(OBJEXT)
+	ctf-types.$(OBJEXT) ctf-util.$(OBJEXT) $(am__objects_1)
 libctf_a_OBJECTS = $(am_libctf_a_OBJECTS)
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -164,7 +170,7 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
 SOURCES = $(libctf_a_SOURCES)
-DIST_SOURCES = $(libctf_a_SOURCES)
+DIST_SOURCES = $(am__libctf_a_SOURCES_DIST)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -196,7 +202,7 @@ am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
 	$(top_srcdir)/../ar-lib $(top_srcdir)/../compile \
 	$(top_srcdir)/../depcomp $(top_srcdir)/../install-sh \
 	$(top_srcdir)/../missing $(top_srcdir)/../mkinstalldirs \
-	ChangeLog qsort_r.c
+	ChangeLog
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -323,11 +329,10 @@ ZLIBINC = @zlibinc@
 AM_CPPFLAGS = -D_GNU_SOURCE -I$(top_srcdir) -I$(top_srcdir)/../include -I$(top_srcdir)/../bfd -I../bfd
 AM_CFLAGS = -std=gnu99 @ac_libctf_warn_cflags@ @warn@ @c_warn@ @WARN_PEDANTIC@ @WERROR@ $(ZLIBINC)
 noinst_LIBRARIES = libctf.a
-libctf_a_SOURCES = ctf-archive.c ctf-dump.c ctf-create.c ctf-decl.c ctf-error.c \
-		   ctf-hash.c ctf-labels.c ctf-lookup.c ctf-open.c ctf-open-bfd.c \
-		   ctf-subr.c ctf-types.c ctf-util.c
-
-libctf_a_LIBADD = $(LIBOBJS)
+libctf_a_SOURCES = ctf-archive.c ctf-dump.c ctf-create.c ctf-decl.c \
+	ctf-error.c ctf-hash.c ctf-labels.c ctf-lookup.c ctf-open.c \
+	ctf-open-bfd.c ctf-subr.c ctf-types.c ctf-util.c \
+	$(am__append_1)
 all: config.h
 	$(MAKE) $(AM_MAKEFLAGS) all-am
 
@@ -396,7 +401,6 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/qsort_r.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-archive.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-create.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-decl.Po@am__quote@
@@ -407,6 +411,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-lookup.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-open-bfd.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-open.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-qsort_r.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-subr.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-types.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-util.Po@am__quote@
@@ -687,7 +692,7 @@ clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
 
 distclean: distclean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-	-rm -rf $(DEPDIR) ./$(DEPDIR)
+	-rm -rf ./$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-hdr distclean-tags
@@ -735,7 +740,7 @@ installcheck-am:
 maintainer-clean: maintainer-clean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
 	-rm -rf $(top_srcdir)/autom4te.cache
-	-rm -rf $(DEPDIR) ./$(DEPDIR)
+	-rm -rf ./$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
diff --git a/libctf/config.h.in b/libctf/config.h.in
index 0ecb5bb721..dff5501609 100644
--- a/libctf/config.h.in
+++ b/libctf/config.h.in
@@ -9,10 +9,6 @@
 /* Define to 1 if you have the <byteswap.h> header file. */
 #undef HAVE_BYTESWAP_H
 
-/* Define to 1 if you have the declaration of `qsort_r', and to 0 if you
-   don't. */
-#undef HAVE_DECL_QSORT_R
-
 /* Define to 1 if you have the <endian.h> header file. */
 #undef HAVE_ENDIAN_H
 
@@ -31,6 +27,9 @@
 /* Define to 1 if you have the `pread' function. */
 #undef HAVE_PREAD
 
+/* Whether a qsort_r exists with a void *arg as its last arg. */
+#undef HAVE_QSORT_R_ARG_LAST
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
diff --git a/libctf/configure b/libctf/configure
index 4fb44eb2cc..c59e4c6abc 100755
--- a/libctf/configure
+++ b/libctf/configure
@@ -624,6 +624,8 @@ ac_subst_vars='am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 LTLIBOBJS
 LIBOBJS
+NEED_CTF_QSORT_R_FALSE
+NEED_CTF_QSORT_R_TRUE
 zlibinc
 zlibdir
 ac_libctf_warn_cflags
@@ -1809,52 +1811,6 @@ $as_echo "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_func
-
-# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
-# ---------------------------------------------
-# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
-# accordingly.
-ac_fn_c_check_decl ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  as_decl_name=`echo $2|sed 's/ *(.*//'`
-  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
-$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-#ifndef $as_decl_name
-#ifdef __cplusplus
-  (void) $as_decl_use;
-#else
-  (void) $as_decl_name;
-#endif
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  eval "$3=yes"
-else
-  eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_decl
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
@@ -6401,16 +6357,65 @@ _ACEOF
 fi
 done
 
-ac_fn_c_check_decl "$LINENO" "qsort_r" "ac_cv_have_decl_qsort_r" "$ac_includes_default"
-if test "x$ac_cv_have_decl_qsort_r" = xyes; then :
-  ac_have_decl=1
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for qsort_r with arg last" >&5
+$as_echo_n "checking for qsort_r with arg last... " >&6; }
+if ${ac_cv_libctf_qsort_r_arg_last+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_libctf_qsort_r_arg_last=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+  int do_not_call (const void *a, const void *b, void *arg)
+  {
+    return (a < b);
+  }
+  static int works = 0;
+  int conftest_compar (const void *a, const void *b, void *arg)
+  {
+    if (arg == do_not_call)
+      works = 1;
+    return (a < b);
+  }
+  int foo[2] = { 0, 1 };
+int
+main ()
+{
+qsort_r (foo, 2, sizeof (int), conftest_compar, do_not_call);
+   return (works == 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_libctf_qsort_r_arg_last=yes
 else
-  ac_have_decl=0
+  ac_cv_libctf_qsort_r_arg_last=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libctf_qsort_r_arg_last" >&5
+$as_echo "$ac_cv_libctf_qsort_r_arg_last" >&6; }
+
+if test $ac_cv_libctf_qsort_r_arg_last = yes; then
+
+$as_echo "#define HAVE_QSORT_R_ARG_LAST 1" >>confdefs.h
+
+fi
+ if test "${ac_cv_libctf_qsort_r_arg_last}" != yes; then
+  NEED_CTF_QSORT_R_TRUE=
+  NEED_CTF_QSORT_R_FALSE='#'
+else
+  NEED_CTF_QSORT_R_TRUE='#'
+  NEED_CTF_QSORT_R_FALSE=
 fi
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_QSORT_R $ac_have_decl
-_ACEOF
 
 case " $LIBOBJS " in
   *" qsort_r.$ac_objext "* ) ;;
@@ -6561,6 +6566,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 
+if test -z "${NEED_CTF_QSORT_R_TRUE}" && test -z "${NEED_CTF_QSORT_R_FALSE}"; then
+  as_fn_error $? "conditional \"NEED_CTF_QSORT_R\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 
 : "${CONFIG_STATUS=./config.status}"
 ac_write_fail=0
diff --git a/libctf/configure.ac b/libctf/configure.ac
index 8fd5388d2a..185aa94378 100644
--- a/libctf/configure.ac
+++ b/libctf/configure.ac
@@ -90,7 +90,35 @@ fi
 AC_C_BIGENDIAN
 AC_CHECK_HEADERS(byteswap.h endian.h)
 AC_CHECK_FUNCS(pread)
-AC_CHECK_DECLS([qsort_r])
+
+AC_CACHE_CHECK([for qsort_r with arg last], ac_cv_libctf_qsort_r_arg_last,
+[AC_RUN_IFELSE(
+  [AC_LANG_PROGRAM(
+  [#include <stdlib.h>
+  int do_not_call (const void *a, const void *b, void *arg)
+  {
+    return (a < b);
+  }
+  static int works = 0;
+  int conftest_compar (const void *a, const void *b, void *arg)
+  {
+    if (arg == do_not_call)
+      works = 1;
+    return (a < b);
+  }
+  int foo[[2]] = { 0, 1 };],
+  [qsort_r (foo, 2, sizeof (int), conftest_compar, do_not_call);
+   return (works == 0);])],
+  [ac_cv_libctf_qsort_r_arg_last=yes],
+  [ac_cv_libctf_qsort_r_arg_last=no],
+  [ac_cv_libctf_qsort_r_arg_last=no])])
+
+if test $ac_cv_libctf_qsort_r_arg_last = yes; then
+  AC_DEFINE([HAVE_QSORT_R_ARG_LAST], 1,
+	    [Whether a qsort_r exists with a void *arg as its last arg.])
+fi
+AM_CONDITIONAL(NEED_CTF_QSORT_R, test "${ac_cv_libctf_qsort_r_arg_last}" != yes)
+
 AC_LIBOBJ([qsort_r])
 
 AC_CONFIG_FILES(Makefile)
diff --git a/libctf/ctf-archive.c b/libctf/ctf-archive.c
index a238edb66b..90cd020b78 100644
--- a/libctf/ctf-archive.c
+++ b/libctf/ctf-archive.c
@@ -169,10 +169,11 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
       modent++;
     }
 
-  qsort_r ((ctf_archive_modent_t *) ((char *) archdr
-				     + sizeof (struct ctf_archive)),
-	   le64toh (archdr->ctfa_nfiles),
-	   sizeof (struct ctf_archive_modent), sort_modent_by_name, nametbl);
+  ctf_qsort_r ((ctf_archive_modent_t *) ((char *) archdr
+					 + sizeof (struct ctf_archive)),
+	       le64toh (archdr->ctfa_nfiles),
+	       sizeof (struct ctf_archive_modent), sort_modent_by_name,
+	       nametbl);
 
    /* Now the name table.  */
 
diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c
index 227f62d8fd..3beed88712 100644
--- a/libctf/ctf-create.c
+++ b/libctf/ctf-create.c
@@ -344,7 +344,7 @@ ctf_update (ctf_file_t *fp)
     }
   assert (i == nvars);
 
-  qsort_r (dvarents, nvars, sizeof (ctf_varent_t), ctf_sort_var, s0);
+  ctf_qsort_r (dvarents, nvars, sizeof (ctf_varent_t), ctf_sort_var, s0);
   t += sizeof (ctf_varent_t) * nvars;
 
   assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_typeoff);
diff --git a/libctf/ctf-decls.h b/libctf/ctf-decls.h
index 5e9ede4809..1f8aab11e4 100644
--- a/libctf/ctf-decls.h
+++ b/libctf/ctf-decls.h
@@ -22,12 +22,22 @@
 
 #include "config.h"
 
-#if !HAVE_DECL_QSORT_R
 #include <stddef.h>
-void qsort_r (void *base, size_t nmemb, size_t size,
+#if HAVE_QSORT_R_ARG_LAST
+#include <stdlib.h>
+
+inline void
+ctf_qsort_r (void *base, size_t nmemb, size_t size,
+	     int (*compar)(const void *, const void *, void *),
+	     void *arg)
+{
+  qsort_r (base, nmemb, size, compar, arg);
+}
+#else
+void ctf_qsort_r (void *base, size_t nmemb, size_t size,
 	      int (*compar)(const void *, const void *, void *),
 	      void *arg);
-#endif /* !HAVE_DECL_QSORT_R */
+#endif /* !HAVE_QSORT_R_ARG_LAST */
 
 #undef MAX
 #undef MIN
diff --git a/libctf/qsort_r.c b/libctf/ctf-qsort_r.c
similarity index 99%
rename from libctf/qsort_r.c
rename to libctf/ctf-qsort_r.c
index 6c334fdaf3..6cb221d6f5 100644
--- a/libctf/qsort_r.c
+++ b/libctf/ctf-qsort_r.c
@@ -30,7 +30,7 @@
 #include "ctf-decls.h"
 
 #ifndef _LIBC
-# define _quicksort qsort_r
+# define _quicksort ctf_qsort_r
 # define __compar_d_fn_t compar_d_fn_t
 typedef int (*compar_d_fn_t) (const void *, const void *, void *);
 #endif
-- 
2.21.0.237.gd0cfaa883d

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/3] libctf: fix use-after-free in function dumping
  2019-06-03 20:48 [PATCH 1/3] libctf: fix the type of ctf_enum.cte_value Nick Alcock
@ 2019-06-03 20:48 ` Nick Alcock
  2019-06-03 20:48 ` [PATCH 3/3] libctf: look for a qsort_r that functions properly Nick Alcock
  1 sibling, 0 replies; 7+ messages in thread
From: Nick Alcock @ 2019-06-03 20:48 UTC (permalink / raw)
  To: binutils; +Cc: jose.marchesi, John.W.Marshall, sebastian.huber

This is actually a free-before-initializing (i.e. a free of garbage).

libctf/
	* ctf-dump.c (ctf_dump_funcs): Free in the right place.
---
 libctf/ctf-dump.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libctf/ctf-dump.c b/libctf/ctf-dump.c
index c2ed791eea..82f63c29d0 100644
--- a/libctf/ctf-dump.c
+++ b/libctf/ctf-dump.c
@@ -273,7 +273,6 @@ ctf_dump_funcs (ctf_file_t *fp, ctf_dump_state_t *state)
 	goto err;
 
       str = ctf_str_append (str, " ");
-      free (bit);
 
       /* Function name.  */
 
@@ -290,6 +289,7 @@ ctf_dump_funcs (ctf_file_t *fp, ctf_dump_state_t *state)
 	}
       str = ctf_str_append (str, bit);
       str = ctf_str_append (str, " (");
+      free (bit);
 
       /* Function arguments.  */
 
-- 
2.21.0.237.gd0cfaa883d

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/3] libctf: fix the type of ctf_enum.cte_value
@ 2019-06-03 20:48 Nick Alcock
  2019-06-03 20:48 ` [PATCH 2/3] libctf: fix use-after-free in function dumping Nick Alcock
  2019-06-03 20:48 ` [PATCH 3/3] libctf: look for a qsort_r that functions properly Nick Alcock
  0 siblings, 2 replies; 7+ messages in thread
From: Nick Alcock @ 2019-06-03 20:48 UTC (permalink / raw)
  To: binutils; +Cc: jose.marchesi, John.W.Marshall, sebastian.huber

This stops the file format from depending on the size of the host int.
(It does mean that we cannot encode enums with a value > 2^32 on
platforms with an int > 2^32: this will be fixed in the next format
revision.)

include/
	* ctf.h (ctf_enum.cte_value): Fix type to int32_t.
---
 include/ctf.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/ctf.h b/include/ctf.h
index 2c3384fe84..e99a673109 100644
--- a/include/ctf.h
+++ b/include/ctf.h
@@ -507,7 +507,7 @@ typedef struct ctf_lmember_v2
 typedef struct ctf_enum
 {
   uint32_t cte_name;		/* Reference to name in string table.  */
-  int cte_value;		/* Value associated with this name.  */
+  int32_t cte_value;		/* Value associated with this name.  */
 } ctf_enum_t;
 
 /* The ctf_archive is a collection of ctf_file_t's stored together. The format
-- 
2.21.0.237.gd0cfaa883d

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] libctf: look for a qsort_r that functions properly
  2019-06-03 20:48 ` [PATCH 3/3] libctf: look for a qsort_r that functions properly Nick Alcock
@ 2019-06-04  9:55   ` Florian Weimer
  2019-06-04  9:58     ` Florian Weimer
  2019-06-05 10:25   ` Pedro Alves
  1 sibling, 1 reply; 7+ messages in thread
From: Florian Weimer @ 2019-06-04  9:55 UTC (permalink / raw)
  To: Nick Alcock; +Cc: binutils, jose.marchesi, John.W.Marshall, sebastian.huber

* Nick Alcock:

> +AC_CACHE_CHECK([for qsort_r with arg last], ac_cv_libctf_qsort_r_arg_last,
> +[AC_RUN_IFELSE(
> +  [AC_LANG_PROGRAM(
> +  [#include <stdlib.h>
> +  int do_not_call (const void *a, const void *b, void *arg)
> +  {
> +    return (a < b);
> +  }
> +  static int works = 0;
> +  int conftest_compar (const void *a, const void *b, void *arg)
> +  {
> +    if (arg == do_not_call)
> +      works = 1;
> +    return (a < b);
> +  }
> +  int foo[[2]] = { 0, 1 };],
> +  [qsort_r (foo, 2, sizeof (int), conftest_compar, do_not_call);
> +   return (works == 0);])],
> +  [ac_cv_libctf_qsort_r_arg_last=yes],
> +  [ac_cv_libctf_qsort_r_arg_last=no],
> +  [ac_cv_libctf_qsort_r_arg_last=no])])

Can you use a compile test with the expected declaration, trying to
compile this?

#undef qsort_r
#include <stdlib.h>
void qsort_r (void *, size_t, size_t,
              int (*) (const void *, const void *, void *),
              void *);

And:

#undef qsort_r
#include <stdlib.h>
void qsort_r (void *, size_t, size_t, void *,
              int (*) (const void *, const void *, void *));

This will result in a hard compiler error, not just in an error.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] libctf: look for a qsort_r that functions properly
  2019-06-04  9:55   ` Florian Weimer
@ 2019-06-04  9:58     ` Florian Weimer
  0 siblings, 0 replies; 7+ messages in thread
From: Florian Weimer @ 2019-06-04  9:58 UTC (permalink / raw)
  To: Nick Alcock; +Cc: binutils, jose.marchesi, John.W.Marshall, sebastian.huber

* Florian Weimer:

> * Nick Alcock:
>
>> +AC_CACHE_CHECK([for qsort_r with arg last], ac_cv_libctf_qsort_r_arg_last,
>> +[AC_RUN_IFELSE(
>> +  [AC_LANG_PROGRAM(
>> +  [#include <stdlib.h>
>> +  int do_not_call (const void *a, const void *b, void *arg)
>> +  {
>> +    return (a < b);
>> +  }
>> +  static int works = 0;
>> +  int conftest_compar (const void *a, const void *b, void *arg)
>> +  {
>> +    if (arg == do_not_call)
>> +      works = 1;
>> +    return (a < b);
>> +  }
>> +  int foo[[2]] = { 0, 1 };],
>> +  [qsort_r (foo, 2, sizeof (int), conftest_compar, do_not_call);
>> +   return (works == 0);])],
>> +  [ac_cv_libctf_qsort_r_arg_last=yes],
>> +  [ac_cv_libctf_qsort_r_arg_last=no],
>> +  [ac_cv_libctf_qsort_r_arg_last=no])])
>
> Can you use a compile test with the expected declaration, trying to
> compile this?
>
> #undef qsort_r
> #include <stdlib.h>
> void qsort_r (void *, size_t, size_t,
>               int (*) (const void *, const void *, void *),
>               void *);
>
> And:
>
> #undef qsort_r
> #include <stdlib.h>
> void qsort_r (void *, size_t, size_t, void *,
>               int (*) (const void *, const void *, void *));
>
> This will result in a hard compiler error, not just in an error.

(I meant not just in a warning.)

Florian

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] libctf: look for a qsort_r that functions properly
  2019-06-03 20:48 ` [PATCH 3/3] libctf: look for a qsort_r that functions properly Nick Alcock
  2019-06-04  9:55   ` Florian Weimer
@ 2019-06-05 10:25   ` Pedro Alves
  2019-06-05 10:46     ` Nick Alcock
  1 sibling, 1 reply; 7+ messages in thread
From: Pedro Alves @ 2019-06-05 10:25 UTC (permalink / raw)
  To: Nick Alcock, binutils; +Cc: jose.marchesi, John.W.Marshall, sebastian.huber

On 6/3/19 9:47 PM, Nick Alcock wrote:

> We cannot just look for any declaration of qsort_r, because some
> operating systems

OOC, could you give some examples?

> have a qsort_r that has a different prototype
> but which still has a pair of pointers in the right places (the last two
> args are interchanged), so we cannot rely on compilation errors to flag
> up a problem.

> 
> So, instead, use AC_RUN_IFELSE to check for the function of qsort_r(),
> passing function pointers in to both args and making sure that we never
> actually dereference the arg pointer.

AC_RUN_IFELSE is really best avoided; obviously you can't run when
cross compiling.

How does gnulib handle this?

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] libctf: look for a qsort_r that functions properly
  2019-06-05 10:25   ` Pedro Alves
@ 2019-06-05 10:46     ` Nick Alcock
  0 siblings, 0 replies; 7+ messages in thread
From: Nick Alcock @ 2019-06-05 10:46 UTC (permalink / raw)
  To: Pedro Alves; +Cc: binutils, jose.marchesi, John.W.Marshall, sebastian.huber

On 5 Jun 2019, Pedro Alves told this:

> On 6/3/19 9:47 PM, Nick Alcock wrote:
>
>> We cannot just look for any declaration of qsort_r, because some
>> operating systems
>
> OOC, could you give some examples?

This is a BSD-heritage thing, so MacOS X and FreeBSD are examples.

>> So, instead, use AC_RUN_IFELSE to check for the function of qsort_r(),
>> passing function pointers in to both args and making sure that we never
>> actually dereference the arg pointer.
>
> AC_RUN_IFELSE is really best avoided; obviously you can't run when
> cross compiling.
>
> How does gnulib handle this?

This is an old patch: v2, posted later, uses gnulib's method (and mostly
gnulib's code too).

-- 
NULL && (void)

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-06-05 10:46 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-03 20:48 [PATCH 1/3] libctf: fix the type of ctf_enum.cte_value Nick Alcock
2019-06-03 20:48 ` [PATCH 2/3] libctf: fix use-after-free in function dumping Nick Alcock
2019-06-03 20:48 ` [PATCH 3/3] libctf: look for a qsort_r that functions properly Nick Alcock
2019-06-04  9:55   ` Florian Weimer
2019-06-04  9:58     ` Florian Weimer
2019-06-05 10:25   ` Pedro Alves
2019-06-05 10:46     ` Nick Alcock

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).