pkgsrc-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

pkg/55522: opendmarc leaks resources



>Number:         55522
>Category:       pkg
>Synopsis:       opendmarc leaks resources
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jul 27 20:25:00 +0000 2020
>Originator:     Greg Oster
>Release:        NetBSD 9.0_STABLE
>Organization:
>Environment:
	
	
System: NetBSD thog 9.0_STABLE NetBSD 9.0_STABLE (GENERIC) #0: Sun Jul 26 11:43:50 CST 2020 oster@thog:/u1/builds/build308/src/obj/amd64/u1/builds/build308/src/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:

As Roy Marples mentioned here: https://sourceforge.net/p/opendmarc/tickets/213/
and has been documented in the thread here: https://mail-index.netbsd.org/current-users/2016/12/13/msg030623.html
opendmarc leaks file descriptors due to a missing res_ndestroy() call for each res_ninit().

>How-To-Repeat:
 
Run opendmarc.  Watch it run out of file descriptors.  Watch mail stop flowing into the system.

>Fix:

Apply the following patches (originally provided by Roy Marples here: https://sourceforge.net/p/opendmarc/tickets/213/ 
with minor fix and build tweaks by me):

--- build-config.h.in.orig	2015-02-23 20:32:27.000000000 +0000
+++ build-config.h.in
@@ -104,6 +104,9 @@
 /* Define to 1 if you have the `res_ninit()' function. */
 #undef HAVE_RES_NINIT
 
+/* Define to 1 if you have the 'res_ndestroy()' function. */
+#undef HAVE_RES_NDESTROY
+
 /* Define to 1 if you have the <signal.h> header file. */
 #undef HAVE_SIGNAL_H
 


--- configure.orig	2015-02-23 20:32:13.000000000 +0000
+++ configure
@@ -12971,6 +12971,184 @@ $as_echo "#define HAVE_RES_NINIT 1" >>co
 
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing res_ndestroy" >&5
+$as_echo_n "checking for library containing res_ndestroy... " >&6; }
+if ${ac_cv_search_res_ndestroy+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char res_ndestroy ();
+int
+main ()
+{
+return res_ndestroy ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' resolv; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi 
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_res_ndestroy=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_res_ndestroy+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_res_ndestroy+:} false; then :
+
+else
+  ac_cv_search_res_ndestroy=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_res_ndestroy" >&5
+$as_echo "$ac_cv_search_res_ndestroy" >&6; }
+ac_res=$ac_cv_search_res_ndestroy
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+$as_echo "#define HAVE_RES_NDESTROY 1" >>confdefs.h    
+
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing __res_ninit" >&5
+$as_echo_n "checking for library containing __res_ninit... " >&6; }
+if ${ac_cv_search___res_ninit+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char __res_ninit ();
+int
+main ()
+{
+return __res_ninit ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' resolv; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search___res_ninit=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search___res_ninit+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search___res_ninit+:} false; then :
+
+else
+  ac_cv_search___res_ninit=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search___res_ninit" >&5
+$as_echo "$ac_cv_search___res_ninit" >&6; }
+ac_res=$ac_cv_search___res_ninit
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+$as_echo "#define HAVE_RES_NINIT 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing __res_ndestroy" >&5
+$as_echo_n "checking for library containing __res_ndestroy... " >&6; }
+if ${ac_cv_search___res_ndestroy+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS 
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char __res_ndestroy (); 
+int
+main ()
+{
+return __res_ndestroy ();
+  ; 
+  return 0;
+} 
+_ACEOF
+for ac_lib in '' resolv; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib 
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"  
+  fi  
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search___res_ndestroy=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search___res_ndestroy+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search___res_ndestroy+:} false; then :
+
+else
+  ac_cv_search___res_ndestroy=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search___res_ndestroy" >&5
+$as_echo "$ac_cv_search___res_ndestroy" >&6; }
+ac_res=$ac_cv_search___res_ndestroy
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+$as_echo "#define HAVE_RES_NDESTROY 1" >>confdefs.h
+
+fi
+
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for idn_free in -lidn" >&5
 $as_echo_n "checking for idn_free in -lidn... " >&6; }
 if ${ac_cv_lib_idn_idn_free+:} false; then :



--- configure.ac.orig	2015-02-23 20:31:50.000000000 +0000
+++ configure.ac
@@ -126,6 +126,16 @@ AC_CHECK_LIB(resolv, inet_aton, , , [-ln
 AC_SEARCH_LIBS(res_ninit, resolv,
 	AC_DEFINE(HAVE_RES_NINIT, 1,
 	[Define to 1 if you have the `res_ninit()' function.]))
+AC_SEARCH_LIBS(res_ndestroy, resolv,
+       AC_DEFINE(HAVE_RES_NDESTROY, 1,
+       [Define to 1 if you have the `res_ndestroy()' function.]))
+AC_SEARCH_LIBS(__res_ninit, resolv,
+	AC_DEFINE(HAVE_RES_NINIT, 1,
+	[Define to 1 if you have the `__res_ninit()' function.]))
+AC_SEARCH_LIBS(__res_ndestroy, resolv,
+       AC_DEFINE(HAVE_RES_NDESTROY, 1,
+       [Define to 1 if you have the `__res_ndestroy()' function.]))
+
 AC_CHECK_LIB(idn, idn_free)
 AC_CHECK_LIB(rt, nanosleep)
 AC_SEARCH_LIBS(inet_addr, nsl)



--- libopendmarc/opendmarc_dns.c.orig	2015-02-23 20:31:51.000000000 +0000
+++ libopendmarc/opendmarc_dns.c
@@ -211,7 +211,11 @@ dmarc_dns_get_record(char *domain, int *
 	(void) opendmarc_policy_library_dns_hook(&resp.nscount,
                                                  &resp.nsaddr_list);
 	answer_len = res_nquery(&resp, bp, C_IN, T_TXT, answer_buf, sizeof answer_buf);
+#ifdef HAVE_RES_NDESTROY
+	res_ndestroy(&resp);
+#else
 	res_nclose(&resp);
+#endif
 #else /* HAVE_RES_NINIT */
 #if defined RES_USE_DNSSEC
 	_res.options |= RES_USE_DNSSEC;



--- libopendmarc/opendmarc_spf_dns.c.orig	2015-02-23 20:31:51.000000000 +0000
+++ libopendmarc/opendmarc_spf_dns.c
@@ -108,7 +108,11 @@ opendmarc_spf_dns_lookup_a_actual(char *
 
 #ifdef HAVE_RES_NINIT
 	k = res_nquery(&resp, bp, C_IN, sought, a_buf, sizeof a_buf);
+#ifdef HAVE_RES_NDESTROY
+	res_ndestroy(&resp);
+#else
 	res_nclose(&resp);
+#endif
 #else /* HAVE_RES_NINIT */
 	k = res_query(bp, C_IN, sought, a_buf, sizeof a_buf);
 #endif /* HAVE_RES_NINIT */
@@ -253,7 +257,11 @@ opendmarc_spf_dns_lookup_mx(char *domain
         memset(&resp, '\0', sizeof resp);
 	res_ninit(&resp);
 	k = res_nquery(&resp, domain, C_IN, T_MX, (u_char *) &q, sizeof(q));
+#ifdef HAVE_RES_NDESTROY
+	res_ndestroy(&resp);
+#else
 	res_nclose(&resp);
+#endif
 #else /* HAVE_RES_NINIT */
 	k = res_query(domain, C_IN, T_MX, (u_char *) &q, sizeof(q));
 #endif /* HAVE_RES_NINIT */
@@ -366,7 +374,11 @@ opendmarc_spf_dns_lookup_ptr(char *ip, c
         memset(&resp, '\0', sizeof resp);
 	res_ninit(&resp);
 	k = res_nquery(&resp, (char *)buf, C_IN, T_PTR, (u_char *) &q, sizeof(q));
+#ifdef HAVE_RES_NDESTROY
+	res_ndestroy(&resp);
+#else
 	res_nclose(&resp);
+#endif
 #else /* HAVE_RES_NINIT */
 	k = res_query((char *)buf, C_IN, T_PTR, (u_char *) &q, sizeof(q));
 #endif /* HAVE_RES_NINIT */
@@ -461,7 +473,11 @@ opendmarc_spf_dns_does_domain_exist(char
         (void) res_nquery(&resp, domain, C_IN, T_AAAA, aaaa_q, sizeof aaaa_q);  
 #endif /* T_AAAA */
         (void) res_nquery(&resp, domain, C_IN, T_MX, mx_q, sizeof mx_q);  
+#ifdef HAVE_RES_NDESTROY
+	res_ndestroy(&resp);
+#else
 	res_nclose(&resp);
+#endif
 #else /* HAVE_RES_NINIT */
         (void) res_query(domain, C_IN, T_A, a_q, sizeof a_q);  
 #ifdef T_AAAA
@@ -603,13 +619,21 @@ opendmarc_spf_dns_get_record(char *domai
 		}
 		*rp = h_errno;
 #ifdef HAVE_RES_NINIT 
+#ifdef HAVE_RES_NDESTROY
+		res_ndestroy(&resp);
+#else
 		res_nclose(&resp);
+#endif
 #endif /* HAVE_RES_NINIT */
 		return NULL;
 	}
 got_spf_record:
 #ifdef HAVE_RES_NINIT 
+#ifdef HAVE_RES_NDESTROY
+	res_ndestroy(&resp);
+#else
 	res_nclose(&resp);
+#endif
 #endif /* HAVE_RES_NINIT */
 
 	if (k > (int)(sizeof txt_buf))

>Unformatted:
 	
 	


Home | Main Index | Thread Index | Old Index