lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20100308210957.GH23634@hmsreliant.think-freely.org>
Date:	Mon, 8 Mar 2010 16:09:57 -0500
From:	Neil Horman <nhorman@...driver.com>
To:	"Stephens, Allan" <allan.stephens@...driver.com>
Cc:	davem@...emloft.net, netdev@...r.kernel.org
Subject: Re: [PATCH] tipc: fix endianness on tipc subscriber messages

On Mon, Mar 08, 2010 at 12:48:38PM -0800, Stephens, Allan wrote:
> Hi there:
> 
> There are a couple of problems with this patch that need to be resolved
> before it can be applied to the upstream kernel.
> 
> 1) Neil's replacement of the htohl() call with the equivalent
> htonl()/ntohl() calls, while well intentioned, was done without
> understanding why the htohl() calls were put there in the first place.
I'd love to hear what those reasons are.  You're formating on-the-wire data to
an endianness defined by the receiving entity.  I'm hard pressed to imagine a
reason why thats sane.

> In addition, the TIPC specification that he used to justify some of his
> decisions is out-dated, and doesn't reflect the latest version of the
> TIPC protocol.  (I'll discuss this further in a follow-up email.)
> 
Please, point out a more recent spec.  The one I referenced is the most recent
publically available spec that I can find. although again, I'm hard pressed to
believe that the spec has changed to include a requirement to send data in
receiver byte order.

> 2) Neil's alteration of the memcpy() in the subscription cancelation
> routine is simply wrong.  The pieces of the data structure that he
> claims are local are not local, and must be checked to ensure that the
> cancellation is done properly.
> 

The origional memcmp checks sizeof(tipc_subscr) bytes of each entry in the
array.  tipc_subscr is defined as:
struct tipc_subscr {
        struct tipc_name_seq seq;       /* name sequence of interest */
        __u32 timeout;                  /* subscription duration (in ms) */
        __u32 filter;                   /* bitmask of filter options */
        char usr_handle[8];             /* available for subscriber use */
};

In subscr_subscribe (from which we also call subscr_cancel), we allocate new
entries for that list, only fillingout the seq.type, seq.lower, seq.upper,
timeout and filter.  So if anyone locally changes usr_handle (which I see
several places that do), the memcmp won't match up properly.  Additionally, I'm
hard pressed to believe (and this would be supported by the section of the spec
that I referenced), timeout, and filter also don't bear on the uniqueness of the
subscriber Id.  Of course a subsequent version of the spec might have changed
that, But if it is, please point it out to me.

> I'm also surprised to see that this patch was immediately applied to
> net-2.6.  First, there was no opportunity given for people to comment on
> the patch.  Secondly, I would have expected this patch to be applied to
> net-next-2.6, since the functionality being changed here (at least the
> first part of it) is more like a feature enhancement than a bug fix.  Am
> I misunderstanding the process being followed here?  If so, please
> explain ...
> 
I'll let David Comment of this, since the destination tree is his final
decision.

Neil

> Regards,
> Al
> 
> > -----Original Message-----
> > From: Neil Horman [mailto:nhorman@...driver.com] 
> > Sent: Monday, March 08, 2010 3:03 PM
> > To: netdev@...r.kernel.org
> > Cc: Stephens, Allan; davem@...emloft.net; nhorman@...driver.com
> > Subject: [PATCH] tipc: fix endianness on tipc subscriber messages
> > 
> > Remove htohl implementation from tipc
> > 
> > I was working on forward porting the downstream commits for 
> > TIPC and ran accross this one:
> > http://tipc.cslab.ericsson.net/cgi-bin/gitweb.cgi?p=people/all
> > an/tipc.git;a=commitdiff;h=894279b9437b63cbb02405ad5b8e033b51e4e31e
> > 
> > I was going to just take it, when I looked closer and noted 
> > what it was doing.
> > This is basically a routine to byte swap fields of data in 
> > sent/received packets for tipc, dependent upon the receivers 
> > guessed endianness of the peer when a connection is 
> > established.  Asside from just seeming silly to me, it 
> > appears to violate the latest RFC draft for tipc:
> > http://tipc.sourceforge.net/doc/draft-spec-tipc-02.txt
> > Which, according to section 4.2 and 4.3.3, requires that all 
> > fields of all commands be sent in network byte order.  So 
> > instead of just taking this patch, instead I'm removing the 
> > htohl function and replacing the calls with calls to ntohl in 
> > the rx path and htonl in the send path.
> > 
> > As part of this fix, I'm also changing the subscr_cancel 
> > function, which searches the list of subscribers, using a 
> > memcmp of the entire subscriber list, for the entry to tear 
> > down.  unfortunately it memcmps the entire tipc_subscr 
> > structure which has several bits that are private to the 
> > local side, so nothing will ever match.  section 5.2 of the 
> > draft spec indicates the <type,upper,lower> tuple should 
> > uniquely identify a subscriber, so convert subscr_cancel to 
> > just match on those fields (properly endian swapped).
> > 
> > I've tested this using the tipc test suite, and its passed 
> > without issue.
> > 
> > Signed-off-by: Neil Horman <nhorman@...driver.com>
> > CC: Allan Stephens <allan.stephens@...driver.com>
> > 
> > 
> >  subscr.c |   57 
> > ++++++++++++++++++++++-----------------------------------
> >  subscr.h |    2 --
> >  2 files changed, 22 insertions(+), 37 deletions(-)
> > 
> > diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 
> > ac91f0d..ff123e5 100644
> > --- a/net/tipc/subscr.c
> > +++ b/net/tipc/subscr.c
> > @@ -76,19 +76,6 @@ struct top_srv {
> >  static struct top_srv topsrv = { 0 };
> >  
> >  /**
> > - * htohl - convert value to endianness used by destination
> > - * @in: value to convert
> > - * @swap: non-zero if endianness must be reversed
> > - *
> > - * Returns converted value
> > - */
> > -
> > -static u32 htohl(u32 in, int swap)
> > -{
> > -	return swap ? swab32(in) : in;
> > -}
> > -
> > -/**
> >   * subscr_send_event - send a message containing a 
> > tipc_event to the subscriber
> >   *
> >   * Note: Must not hold subscriber's server port lock, since 
> > tipc_send() will @@ -107,11 +94,11 @@ static void 
> > subscr_send_event(struct subscription *sub,
> >  	msg_sect.iov_base = (void *)&sub->evt;
> >  	msg_sect.iov_len = sizeof(struct tipc_event);
> >  
> > -	sub->evt.event = htohl(event, sub->swap);
> > -	sub->evt.found_lower = htohl(found_lower, sub->swap);
> > -	sub->evt.found_upper = htohl(found_upper, sub->swap);
> > -	sub->evt.port.ref = htohl(port_ref, sub->swap);
> > -	sub->evt.port.node = htohl(node, sub->swap);
> > +	sub->evt.event = htonl(event);
> > +	sub->evt.found_lower = htonl(found_lower);
> > +	sub->evt.found_upper = htonl(found_upper);
> > +	sub->evt.port.ref = htonl(port_ref);
> > +	sub->evt.port.node = htonl(node);
> >  	tipc_send(sub->server_ref, 1, &msg_sect);  }
> >  
> > @@ -287,16 +274,23 @@ static void subscr_cancel(struct 
> > tipc_subscr *s,  {
> >  	struct subscription *sub;
> >  	struct subscription *sub_temp;
> > +	__u32 type, lower, upper;
> >  	int found = 0;
> >  
> >  	/* Find first matching subscription, exit if not found */
> >  
> > +	type = ntohl(s->seq.type);
> > +	lower = ntohl(s->seq.lower);
> > +	upper = ntohl(s->seq.upper);
> > +
> >  	list_for_each_entry_safe(sub, sub_temp, 
> > &subscriber->subscription_list,
> >  				 subscription_list) {
> > -		if (!memcmp(s, &sub->evt.s, sizeof(struct 
> > tipc_subscr))) {
> > -			found = 1;
> > -			break;
> > -		}
> > +			if ((type == sub->seq.type) &&
> > +			    (lower == sub->seq.lower) &&
> > +			    (upper == sub->seq.upper)) {
> > +				found = 1;
> > +				break;
> > +			}
> >  	}
> >  	if (!found)
> >  		return;
> > @@ -325,16 +319,10 @@ static struct subscription 
> > *subscr_subscribe(struct tipc_subscr *s,
> >  					     struct subscriber 
> > *subscriber)  {
> >  	struct subscription *sub;
> > -	int swap;
> > -
> > -	/* Determine subscriber's endianness */
> > -
> > -	swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE));
> >  
> >  	/* Detect & process a subscription cancellation request */
> >  
> > -	if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) {
> > -		s->filter &= ~htohl(TIPC_SUB_CANCEL, swap);
> > +	if (ntohl(s->filter) & TIPC_SUB_CANCEL) {
> >  		subscr_cancel(s, subscriber);
> >  		return NULL;
> >  	}
> > @@ -359,11 +347,11 @@ static struct subscription 
> > *subscr_subscribe(struct tipc_subscr *s,
> >  
> >  	/* Initialize subscription object */
> >  
> > -	sub->seq.type = htohl(s->seq.type, swap);
> > -	sub->seq.lower = htohl(s->seq.lower, swap);
> > -	sub->seq.upper = htohl(s->seq.upper, swap);
> > -	sub->timeout = htohl(s->timeout, swap);
> > -	sub->filter = htohl(s->filter, swap);
> > +	sub->seq.type = ntohl(s->seq.type);
> > +	sub->seq.lower = ntohl(s->seq.lower);
> > +	sub->seq.upper = ntohl(s->seq.upper);
> > +	sub->timeout = ntohl(s->timeout);
> > +	sub->filter = ntohl(s->filter);
> >  	if ((!(sub->filter & TIPC_SUB_PORTS) ==
> >  	     !(sub->filter & TIPC_SUB_SERVICE)) ||
> >  	    (sub->seq.lower > sub->seq.upper)) { @@ -376,7 
> > +364,6 @@ static struct subscription *subscr_subscribe(struct 
> > tipc_subscr *s,
> >  	INIT_LIST_HEAD(&sub->nameseq_list);
> >  	list_add(&sub->subscription_list, 
> > &subscriber->subscription_list);
> >  	sub->server_ref = subscriber->port_ref;
> > -	sub->swap = swap;
> >  	memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr));
> >  	atomic_inc(&topsrv.subscription_count);
> >  	if (sub->timeout != TIPC_WAIT_FOREVER) { diff --git 
> > a/net/tipc/subscr.h b/net/tipc/subscr.h index 45d89bf..c20f496 100644
> > --- a/net/tipc/subscr.h
> > +++ b/net/tipc/subscr.h
> > @@ -53,7 +53,6 @@ typedef void (*tipc_subscr_event) (struct 
> > subscription *sub,
> >   * @nameseq_list: adjacent subscriptions in name sequence's 
> > subscription list
> >   * @subscription_list: adjacent subscriptions in 
> > subscriber's subscription list
> >   * @server_ref: object reference of server port associated 
> > with subscription
> > - * @swap: indicates if subscriber uses opposite endianness 
> > in its messages
> >   * @evt: template for events generated by subscription
> >   */
> >  
> > @@ -66,7 +65,6 @@ struct subscription {
> >  	struct list_head nameseq_list;
> >  	struct list_head subscription_list;
> >  	u32 server_ref;
> > -	int swap;
> >  	struct tipc_event evt;
> >  };
> >  
> > 
> 
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ