On Sat, Mar 26, 2016 at 12:59:30AM +0100, Emilio Pozuelo Monfort wrote:
> It'd be nice to get this fixed as it's preventing a bunch of packages from 
> being
> built. Which means cruft stays in the archive.

Hi maintainers,

I intend to NMU for this bug and a few other bugs that I'd really like to see
fixed before stretch. I've uploaded to DELAYED/7-day; let me know if you'd
like anything changed. I've attached my own git diff on top of Steven's diff
(which is on top of latest pkg-net-snmp git).

/* Steinar */
-- 
Homepage: https://www.sesse.net/
>From b568443aec9b0ccbeb6f59782dba08c9da63d37f Mon Sep 17 00:00:00 2001
From: "Steinar H. Gunderson" <sgunder...@bigfoot.com>
Date: Tue, 29 Mar 2016 02:03:37 +0200
Subject: [PATCH] Diff for 5.7.3+dfsg-1.1 NMU, adding various patches for
 bugfixes (and one small new feature).

---
 debian/changelog                                   |  21 +++-
 debian/patches/callback_print.diff                 |  13 +++
 .../do_not_callback_for_failed_reports.diff        | 129 +++++++++++++++++++++
 debian/patches/fix_engineid_reprobe.diff           |  16 +++
 debian/patches/fix_perl_bulk_gets.diff             |  88 ++++++++++++++
 debian/patches/let_perl_access_engineid.diff       |  94 +++++++++++++++
 debian/patches/series                              |   5 +
 7 files changed, 364 insertions(+), 2 deletions(-)
 create mode 100644 debian/patches/callback_print.diff
 create mode 100644 debian/patches/do_not_callback_for_failed_reports.diff
 create mode 100644 debian/patches/fix_engineid_reprobe.diff
 create mode 100644 debian/patches/fix_perl_bulk_gets.diff
 create mode 100644 debian/patches/let_perl_access_engineid.diff

diff --git a/debian/changelog b/debian/changelog
index 94bf7e1..e4622d2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,8 @@
-net-snmp (5.7.3+dfsg-2) UNRELEASED; urgency=medium
+net-snmp (5.7.3+dfsg-1.1) unstable; urgency=medium
+
+  * Non-maintainer upload, done on top of the latest version in pkg-net-snmp
+    git, as well as adding Steven Chamberlain's kFreeBSD patches from
+    bug #810892.
 
   [ Hideki Yamane ]
   * debian/patches
@@ -24,7 +28,20 @@ net-snmp (5.7.3+dfsg-2) UNRELEASED; urgency=medium
   * Re-enable IPv6 on kfreebsd (Closes: #765846)
   * Build with the libbsd overlay on kfreebsd, for nlist
 
- -- Hideki Yamane <henr...@debian.org>  Thu, 18 Jun 2015 06:43:28 +0900
+  [ Steinar H. Gunderson ]
+  * New patches, mostly for various bug fixes (some of them for crash bugs):
+    * fix_engineid_reprobe.diff: Do not probe engineID for USM
+      if it is already given. (Closes: #765873)
+    * callback_print.diff: Fix enum formatting when doing asynchronous queries
+      from Perl. (Closes: #765289)
+    * do_not_callback_for_failed_reports.diff: Fix access of freed data due to
+      callbacks for reports occasionally coming twice.
+    * fix_perl_bulk_gets.diff: Fix handling of truncated bulk get responses
+      in the Perl module. (Patch 1278 in upstream patch tracker.)
+    * let_perl_access_engineid.diff: Add a new functions to let Perl code
+      access the security engine ID.
+
+ -- Steinar H. Gunderson <se...@debian.org>  Tue, 29 Mar 2016 10:30:24 +0200
 
 net-snmp (5.7.3+dfsg-1) unstable; urgency=medium
 
diff --git a/debian/patches/callback_print.diff b/debian/patches/callback_print.diff
new file mode 100644
index 0000000..f4b6df6
--- /dev/null
+++ b/debian/patches/callback_print.diff
@@ -0,0 +1,13 @@
+--- net-snmp-5.7.2.1~dfsg.orig/perl/SNMP/SNMP.xs
++++ net-snmp-5.7.2.1~dfsg/perl/SNMP/SNMP.xs
+@@ -1300,6 +1300,10 @@ void *cb_data;
+          netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_OIDS, 1);
+          netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_NUMERIC);
+       }
++      if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseEnums", 8, 1)))
++         sprintval_flag = USE_ENUMS;
++      if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseSprintValue", 14, 1)))
++         sprintval_flag = USE_SPRINT_VALUE;
+ 
+       sv_bless(varlist_ref, gv_stashpv("SNMP::VarList",0));
+       for(vars = (pdu?pdu->variables:NULL); vars; vars = vars->next_variable) {
diff --git a/debian/patches/do_not_callback_for_failed_reports.diff b/debian/patches/do_not_callback_for_failed_reports.diff
new file mode 100644
index 0000000..96db193
--- /dev/null
+++ b/debian/patches/do_not_callback_for_failed_reports.diff
@@ -0,0 +1,129 @@
+Index: net-snmp-5.7.3/snmplib/snmp_api.c
+===================================================================
+--- net-snmp-5.7.3.orig/snmplib/snmp_api.c
++++ net-snmp-5.7.3/snmplib/snmp_api.c
+@@ -5346,71 +5346,71 @@ _sess_process_packet(void *sessp, netsnm
+        * should be per session ! 
+        */
+ 
+-      if (callback == NULL
+-	  || callback(NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE, sp,
+-		      pdu->reqid, pdu, magic) == 1) {
+-	if (pdu->command == SNMP_MSG_REPORT) {
+-	  if (sp->s_snmp_errno == SNMPERR_NOT_IN_TIME_WINDOW ||
+-	      snmpv3_get_report_type(pdu) ==
+-	      SNMPERR_NOT_IN_TIME_WINDOW) {
+-	    /*
+-	     * trigger immediate retry on recoverable Reports 
+-	     * * (notInTimeWindow), incr_retries == TRUE to prevent
+-	     * * inifinite resend                      
+-	     */
+-	    if (rp->retries <= sp->retries) {
+-	      snmp_resend_request(slp, rp, TRUE);
+-	      break;
+-	    } else {
+-	      /* We're done with retries, so no longer waiting for a response */
+-	      if (magic) {
+-		((struct synch_state*)magic)->waiting = 0;
+-	      }
+-	    }
++      if (pdu->command == SNMP_MSG_REPORT) {
++	if (sp->s_snmp_errno == SNMPERR_NOT_IN_TIME_WINDOW ||
++	    snmpv3_get_report_type(pdu) ==
++	    SNMPERR_NOT_IN_TIME_WINDOW) {
++	  /*
++	   * trigger immediate retry on recoverable Reports 
++	   * * (notInTimeWindow), incr_retries == TRUE to prevent
++	   * * inifinite resend		      
++	   */
++	  if (rp->retries <= sp->retries) {
++	    snmp_resend_request(slp, rp, TRUE);
++	    break;
+ 	  } else {
+-	    if (SNMPV3_IGNORE_UNAUTH_REPORTS) {
+-	      break;
+-	    } else { /* Set the state to no longer be waiting, since we're done with retries */
+-	      if (magic) {
+-		((struct synch_state*)magic)->waiting = 0;
+-	      }
++	    /* We're done with retries, so no longer waiting for a response */
++	    if (magic) {
++	      ((struct synch_state*)magic)->waiting = 0;
++	    }
++	  }
++	} else {
++	  if (SNMPV3_IGNORE_UNAUTH_REPORTS) {
++	    break;
++	  } else { /* Set the state to no longer be waiting, since we're done with retries */
++	    if (magic) {
++	      ((struct synch_state*)magic)->waiting = 0;
+ 	    }
+ 	  }
++	}
+ 
+-	  /*
+-	   * Handle engineID discovery.  
+-	   */
+-	  if (!sp->securityEngineIDLen && pdu->securityEngineIDLen) {
+-	    sp->securityEngineID =
+-	      (u_char *) malloc(pdu->securityEngineIDLen);
+-	    if (sp->securityEngineID == NULL) {
++	/*
++	 * Handle engineID discovery.  
++	 */
++	if (!sp->securityEngineIDLen && pdu->securityEngineIDLen) {
++	  sp->securityEngineID =
++	    (u_char *) malloc(pdu->securityEngineIDLen);
++	  if (sp->securityEngineID == NULL) {
++	    /*
++	     * TODO FIX: recover after message callback *?
++	     */
++	    return -1;
++	  }
++	  memcpy(sp->securityEngineID, pdu->securityEngineID,
++		 pdu->securityEngineIDLen);
++	  sp->securityEngineIDLen = pdu->securityEngineIDLen;
++	  if (!sp->contextEngineIDLen) {
++	    sp->contextEngineID =
++	      (u_char *) malloc(pdu->
++				securityEngineIDLen);
++	    if (sp->contextEngineID == NULL) {
+ 	      /*
+ 	       * TODO FIX: recover after message callback *?
+-               */
++	       */
+ 	      return -1;
+ 	    }
+-	    memcpy(sp->securityEngineID, pdu->securityEngineID,
++	    memcpy(sp->contextEngineID,
++		   pdu->securityEngineID,
+ 		   pdu->securityEngineIDLen);
+-	    sp->securityEngineIDLen = pdu->securityEngineIDLen;
+-	    if (!sp->contextEngineIDLen) {
+-	      sp->contextEngineID =
+-		(u_char *) malloc(pdu->
+-				  securityEngineIDLen);
+-	      if (sp->contextEngineID == NULL) {
+-		/*
+-		 * TODO FIX: recover after message callback *?
+-		 */
+-                return -1;
+-	      }
+-	      memcpy(sp->contextEngineID,
+-		     pdu->securityEngineID,
+-		     pdu->securityEngineIDLen);
+-	      sp->contextEngineIDLen =
+-		pdu->securityEngineIDLen;
+-	    }
++	    sp->contextEngineIDLen =
++	      pdu->securityEngineIDLen;
+ 	  }
+ 	}
++      }
+ 
++      if (callback == NULL || 
++	 callback(NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE, sp,
++		  pdu->reqid, pdu, magic) == 1) {
+ 	/*
+ 	 * Successful, so delete request.  
+ 	 */
diff --git a/debian/patches/fix_engineid_reprobe.diff b/debian/patches/fix_engineid_reprobe.diff
new file mode 100644
index 0000000..c9d4778
--- /dev/null
+++ b/debian/patches/fix_engineid_reprobe.diff
@@ -0,0 +1,16 @@
+Index: net-snmp-5.7.3/snmplib/snmpusm.c
+===================================================================
+--- net-snmp-5.7.3.orig/snmplib/snmpusm.c
++++ net-snmp-5.7.3/snmplib/snmpusm.c
+@@ -3129,6 +3129,11 @@ int usm_discover_engineid(void *slpv, ne
+     int status, i;
+     struct session_list *slp = (struct session_list *) slpv;
+ 
++    if (slp->session->securityEngineIDLen != 0) {
++        DEBUGMSGTL(("snmp_api", "engineID already known, skipping probe\n"));
++        return SNMPERR_SUCCESS;
++    }
++
+     if (usm_build_probe_pdu(&pdu) != 0) {
+         DEBUGMSGTL(("snmp_api", "unable to create probe PDU\n"));
+         return SNMP_ERR_GENERR;
diff --git a/debian/patches/fix_perl_bulk_gets.diff b/debian/patches/fix_perl_bulk_gets.diff
new file mode 100644
index 0000000..88d1fe4
--- /dev/null
+++ b/debian/patches/fix_perl_bulk_gets.diff
@@ -0,0 +1,88 @@
+Index: net-snmp-5.7.2.1+dfsg/perl/SNMP/SNMP.pm
+===================================================================
+--- net-snmp-5.7.2.1+dfsg.orig/perl/SNMP/SNMP.pm
++++ net-snmp-5.7.2.1+dfsg/perl/SNMP/SNMP.pm
+@@ -866,22 +866,11 @@ sub _gettable_do_it() {
+ 
+     $vbl = $_[$#_] if ($state->{'options'}{'callback'});
+ 
+-    while ($#$vbl > -1 && !$this->{ErrorNum}) {
+-	if (($#$vbl + 1) % ($#{$state->{'stopconds'}} + 1) != 0) {
+-	    if ($vbl->[$#$vbl][2] ne 'ENDOFMIBVIEW') {
+-		# unless it's an end of mib view we didn't get the
+-		# proper number of results back.
+-		print STDERR "ack: gettable results not appropriate\n";
+-	    }
+-	    my @k = keys(%{$state->{'result_hash'}});
+-	    last if ($#k > -1);  # bail with what we have
+-	    return;
+-	}
+-
+-	$state->{'varbinds'} = [];
+-	my $newstopconds;
++    my $num_vbls = defined($vbl) ? scalar @$vbl : 0;
++    my $num_stopconds = scalar @{$state->{'stopconds'}};
+ 
+-	my $lastsetstart = ($state->{'repeatcount'}-1) * ($#{$state->{'stopconds'}}+1);
++    while ($num_vbls > 0 && !$this->{ErrorNum}) {
++	my @found_eof = (0) x $num_stopconds;
+ 
+ 	for (my $i = 0; $i <= $#$vbl; $i++) {
+ 	    my $row_oid = SNMP::translateObj($vbl->[$i][0]);
+@@ -890,9 +879,11 @@ sub _gettable_do_it() {
+ 	    my $row_value = $vbl->[$i][2];
+ 	    my $row_type = $vbl->[$i][3];
+ 
+-	    if ($row_oid =~ 
+-		/^$state->{'stopconds'}[$i % ($#{$state->{'stopconds'}}+1)]/ &&
+-		$row_value ne 'ENDOFMIBVIEW' ){
++	    my $stopcond_num = $i % $num_stopconds;
++	    my $stopcond = $state->{'stopconds'}[$stopcond_num];
++	    if ($row_oid !~ /^\Q$stopcond\E/ || $row_value eq 'ENDOFMIBVIEW') {
++		$found_eof[$stopcond_num] = 1;
++	    } else {
+ 
+ 		if ($row_type eq "OBJECTID") {
+ 
+@@ -903,26 +894,30 @@ sub _gettable_do_it() {
+ 
+ 		}
+ 
++		# continue past this next time
++
++		$state->{'varbinds'}[$stopcond_num] = [ $row_text, $row_index ];
++
+ 		# Place the results in a hash
+ 
+ 		$state->{'result_hash'}{$row_index}{$row_text} = $row_value;
++	    }
++	}
+ 
+-		# continue past this next time
+-		if ($i >= $lastsetstart) {
+-		    push @$newstopconds,
+-		      $state->{'stopconds'}->[$i%($#{$state->{'stopconds'}}+1)];
+-		    push @{$state->{'varbinds'}},[$vbl->[$i][0],$vbl->[$i][1]];
+-		}
++	my @newstopconds = ();
++	my @newvarbinds = ();
++	for (my $i = 0; $i < $num_stopconds; ++$i) {
++	    unless ($found_eof[$i]) {
++		push @newstopconds, $state->{'stopconds'}[$i];
++		push @newvarbinds, $state->{'varbinds'}[$i];
+ 	    }
+ 	}
+-	if ($#$newstopconds == -1) {
++	if ($#newstopconds == -1) {
+ 	    last;
+ 	}
+-	if ($#{$state->{'varbinds'}} == -1) {
+-	    print "gettable ack.  shouldn't get here\n";
+-	}
++	$state->{'varbinds'} = \@newvarbinds;
++	$state->{'stopconds'} = \@newstopconds;
+ 	$vbl = $state->{'varbinds'};
+-	$state->{'stopconds'} = $newstopconds;
+ 
+         #
+         # if we've been configured with a callback, then call the
diff --git a/debian/patches/let_perl_access_engineid.diff b/debian/patches/let_perl_access_engineid.diff
new file mode 100644
index 0000000..b65135f
--- /dev/null
+++ b/debian/patches/let_perl_access_engineid.diff
@@ -0,0 +1,94 @@
+Index: net-snmp-5.7.2.1+dfsg/perl/SNMP/SNMP.pm
+===================================================================
+--- net-snmp-5.7.2.1+dfsg.orig/perl/SNMP/SNMP.pm
++++ net-snmp-5.7.2.1+dfsg/perl/SNMP/SNMP.pm
+@@ -1238,6 +1238,16 @@ sub inform {
+    return(wantarray() ? @res : $res[0]);
+ }
+ 
++sub get_sec_engine_id {
++   my $this = shift;
++   return SNMP::_get_sec_engine_id($this);
++}
++
++sub get_context_engine_id {
++   my $this = shift;
++   return SNMP::_get_context_engine_id($this);
++}
++
+ package SNMP::TrapSession;
+ @SNMP::TrapSession::ISA = ('SNMP::Session');
+ 
+@@ -2034,6 +2044,17 @@ as well.
+ 
+ =back
+ 
++=item $sess->get_sec_engine_id
++
++Returns the security engine ID for the current session, whether probed
++or provided by the client, in hex format suitable for the SecEngineId
++parameter when creating a session in the future. Returns undef if we have not
++had not had any contact with the remote agent yet.
++
++=item $sess->get_context_engine_id
++
++Like get_sec_engine_id, but for the context engine ID (ContextEngineId).
++
+ =back
+ 
+ =head1 SNMP::TrapSession
+Index: net-snmp-5.7.2.1+dfsg/perl/SNMP/SNMP.xs
+===================================================================
+--- net-snmp-5.7.2.1+dfsg.orig/perl/SNMP/SNMP.xs
++++ net-snmp-5.7.2.1+dfsg/perl/SNMP/SNMP.xs
+@@ -4741,6 +4741,50 @@ done:
+ 
+ 
+ char *
++snmp_get_sec_engine_id(sess_ref)
++        SV *	sess_ref
++	CODE:
++	{
++           RETVAL = NULL;
++           if (SvROK(sess_ref)) {
++              SV **sess_ptr_sv = hv_fetch((HV*)SvRV(sess_ref), "SessPtr", 7, 1);
++	      SnmpSession *ss = (SnmpSession *)SvIV((SV*)SvRV(*sess_ptr_sv));
++              if (ss->securityEngineIDLen > 0) {
++                 binary_to_hex(ss->securityEngineID,
++                               ss->securityEngineIDLen,
++                               &RETVAL);
++              }
++           }
++	}
++	OUTPUT:
++        RETVAL
++        CLEANUP:
++        netsnmp_free(RETVAL);
++
++
++char *
++snmp_get_context_engine_id(sess_ref)
++        SV *	sess_ref
++	CODE:
++	{
++           RETVAL = NULL;
++           if (SvROK(sess_ref)) {
++              SV **sess_ptr_sv = hv_fetch((HV*)SvRV(sess_ref), "SessPtr", 7, 1);
++	      SnmpSession *ss = (SnmpSession *)SvIV((SV*)SvRV(*sess_ptr_sv));
++              if (ss->contextEngineIDLen > 0) {
++                 binary_to_hex(ss->contextEngineID,
++                               ss->contextEngineIDLen,
++                               &RETVAL);
++              }
++           }
++	}
++	OUTPUT:
++        RETVAL
++        CLEANUP:
++        netsnmp_free(RETVAL);
++
++
++char *
+ snmp_get_type(tag, best_guess)
+ 	char *		tag
+         int             best_guess
diff --git a/debian/patches/series b/debian/patches/series
index 5ad0dc2..a93def2 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -25,3 +25,8 @@ fix-request-id-0.patch
 0025-Bug-788964-net-snmp-snmp_pdu_parse-DoS.patch
 0026-fix-Bug-785380-incorrect-date-format.patch
 0027-fix-455707-traptoemail-use-FQDN.patch
+let_perl_access_engineid.diff
+fix_perl_bulk_gets.diff
+do_not_callback_for_failed_reports.diff
+callback_print.diff
+fix_engineid_reprobe.diff
-- 
2.7.0

Reply via email to