Skip to contentSkip to conversation

caif: fix endian conversion in cffrml_transmit()

PATCH Superseded Dan Carpenter 5 participants 6 messages Nov 21, 2011

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 caif: fix endian conversion in cffrml_transmit()

The "tmp" variable here is used to store the result of cpu_to_le16() so it should be a u16 instead of an int. We want the high bits set and the current code works on little endian systems but not on big endian systems.

---
This is a static checker thing. I haven't tested it. Please review carefully.

net/caif/cffrml.c +2 -1
index f399211..2b46c48 100644
@@ -136,10 +136,11 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt)
 
 static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt)
 {
-	int tmp;
+	u16 tmp;
 	u16 chks;
 	u16 len;
 	struct cffrml *this = container_obj(layr);
+
 	if (this->dofcs) {
 		chks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff);
 		tmp = cpu_to_le16(chks);
#1 lore raw
Quoted 4 lines · Dan Carpenter

The "tmp" variable here is used to store the result of cpu_to_le16() so it should be a u16 instead of an int. We want the high bits set and the current code works on little endian systems but not on big endian systems.

Charming... On b-e we end up feeding zeroes instead of the value we want.

However, that u16 clearly ought to be __le16 - it's there for purpose.

#2 lore raw

PATCH v2 1/1 caif: fix endian conversion in cffrml_transmit()

The "tmp" variable here is used to store the result of cpu_to_le16() so it should be an __le16 instead of an int. We want the high bits set and the current code works on little endian systems but not on big endian systems.

---
v2: In v1 I used a u16 instead of an __le16. Also I've changed the name to "data" instead of "tmp".

net/caif/cffrml.c +6 -5
index f399211..d3ca87b 100644
@@ -136,20 +136,21 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt)
 
 static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt)
 {
-	int tmp;
 	u16 chks;
 	u16 len;
+	__le16 data;
+
 	struct cffrml *this = container_obj(layr);
 	if (this->dofcs) {
 		chks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff);
-		tmp = cpu_to_le16(chks);
-		cfpkt_add_trail(pkt, &tmp, 2);
+		data = cpu_to_le16(chks);
+		cfpkt_add_trail(pkt, &data, 2);
 	} else {
 		cfpkt_pad_trail(pkt, 2);
 	}
 	len = cfpkt_getlen(pkt);
-	tmp = cpu_to_le16(len);
-	cfpkt_add_head(pkt, &tmp, 2);
+	data = cpu_to_le16(len);
+	cfpkt_add_head(pkt, &data, 2);
 	cfpkt_info(pkt)->hdr_len += 2;
 	if (cfpkt_erroneous(pkt)) {
 		pr_err("Packet is erroneous!\n");
Acked-by on v2 1/1
#3 lore raw
Quoted 9 lines

The "tmp" variable here is used to store the result of cpu_to_le16() so it should be an __le16 instead of an int.  We want the high bits set and the current code works on little endian systems but not on big endian systems.

---
v2:  In v1 I used a u16 instead of an __le16.  Also I've changed the name to "data" instead of "tmp".

Thanks Dan, good catch - this would have failed badly on a b_e architecture.

Regards,
Sjur

maintainer
#4 lore raw

From: Sjur Brændeland <[email protected]>
Date: Mon, 21 Nov 2011 22:20:09 +0100

Quoted 5 lines
Quoted 5 lines

The "tmp" variable here is used to store the result of cpu_to_le16() so it should be an __le16 instead of an int.  We want the high bits set and the current code works on little endian systems but not on big endian systems.

Quoted 8 lines
Quoted 4 lines

---
v2:  In v1 I used a u16 instead of an __le16.  Also I've changed the name to "data" instead of "tmp".

Thanks Dan, good catch - this would have failed badly on a b_e architecture.

Applied, thanks guys.
--
To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Acked-by on v1 1/1
#5 lore raw
In reply to Dan Carpenter

Hi Dan,

Quoted 6 lines

The "tmp" variable here is used to store the result of cpu_to_le16() so it should be a u16 instead of an int. We want the high bits set and the current code works on little endian systems but not on big endian systems.

Looks OK by me, unless you want to make sparse with __CHECK_ENDIAN__ shut up, then you should use __le16 ;-)

Regards,
Sjur

--
To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html