5228e3e
From 0a7c084603663a1e63b01bd677429a20bc7d4c62 Mon Sep 17 00:00:00 2001
5228e3e
From: Paolo Bonzini <pbonzini@redhat.com>
5228e3e
Date: Mon, 1 Jul 2013 15:57:44 +0200
5228e3e
Subject: [PATCH] scsi-lowlevel: do not use unsafe pointer casts
5228e3e
5228e3e
Casting unsigned char * pointers to uint32_t * may cause wrong
5228e3e
results if the pointers are not correctly aligned.  Instead,
5228e3e
build up the big-endian values from each byte with multiple
5228e3e
dereferences of the original pointer.
5228e3e
5228e3e
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
5228e3e
---
5228e3e
 lib/scsi-lowlevel.c | 36 +++++++++++++++++++++---------------
5228e3e
 1 file changed, 21 insertions(+), 15 deletions(-)
5228e3e
5228e3e
diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c
5228e3e
index ad94eef..37f41d5 100644
5228e3e
--- a/lib/scsi-lowlevel.c
5228e3e
+++ b/lib/scsi-lowlevel.c
5228e3e
@@ -212,10 +212,10 @@ scsi_get_uint64(const unsigned char *c)
5228e3e
 {
5228e3e
 	uint64_t val;
5228e3e
 
5228e3e
-	val = ntohl(*(uint32_t *)c);
5228e3e
+	val = scsi_get_uint32(c);
5228e3e
 	val <<= 32;
5228e3e
 	c += 4;
5228e3e
-	val |= ntohl(*(uint32_t *)c);
5228e3e
+	val |= scsi_get_uint32(c);
5228e3e
 
5228e3e
 	return val;
5228e3e
 }
5228e3e
@@ -223,13 +223,21 @@ scsi_get_uint64(const unsigned char *c)
5228e3e
 inline uint32_t
5228e3e
 scsi_get_uint32(const unsigned char *c)
5228e3e
 {
5228e3e
-	return ntohl(*(uint32_t *)c);
5228e3e
+	uint32_t val;
5228e3e
+	val = c[0];
5228e3e
+	val = (val << 8) | c[1];
5228e3e
+	val = (val << 8) | c[2];
5228e3e
+	val = (val << 8) | c[3];
5228e3e
+	return val;
5228e3e
 }
5228e3e
 
5228e3e
 inline uint16_t
5228e3e
 scsi_get_uint16(const unsigned char *c)
5228e3e
 {
5228e3e
-	return ntohs(*(uint16_t *)c);
5228e3e
+	uint16_t val;
5228e3e
+	val = c[0];
5228e3e
+	val = (val << 8) | c[1];
5228e3e
+	return val;
5228e3e
 }
5228e3e
 
5228e3e
 static inline uint64_t
5228e3e
@@ -237,14 +245,8 @@ task_get_uint64(struct scsi_task *task, int offset)
5228e3e
 {
5228e3e
 	if (offset <= task->datain.size - 8) {
5228e3e
 		const unsigned char *c = &task->datain.data[offset];
5228e3e
-		uint64_t val;
5228e3e
 
5228e3e
-		val = ntohl(*(uint32_t *)c);
5228e3e
-		val <<= 32;
5228e3e
-		c += 4;
5228e3e
-		val |= ntohl(*(uint32_t *)c);
5228e3e
-
5228e3e
-		return val;
5228e3e
+		return scsi_get_uint64(c);
5228e3e
 	} else {
5228e3e
 		return 0;
5228e3e
 	}
5228e3e
@@ -256,7 +258,7 @@ task_get_uint32(struct scsi_task *task, int offset)
5228e3e
 	if (offset <= task->datain.size - 4) {
5228e3e
 		const unsigned char *c = &task->datain.data[offset];
5228e3e
 
5228e3e
-		return ntohl(*(uint32_t *)c);
5228e3e
+		return scsi_get_uint32(c);
5228e3e
 	} else {
5228e3e
 		return 0;
5228e3e
 	}
5228e3e
@@ -268,7 +270,7 @@ task_get_uint16(struct scsi_task *task, int offset)
5228e3e
 	if (offset <= task->datain.size - 2) {
5228e3e
 		const unsigned char *c = &task->datain.data[offset];
5228e3e
 
5228e3e
-		return ntohs(*(uint16_t *)c);
5228e3e
+		return scsi_get_uint16(c);
5228e3e
 	} else {
5228e3e
 		return 0;
5228e3e
 	}
5228e3e
@@ -300,13 +302,17 @@ scsi_set_uint64(unsigned char *c, uint64_t v)
5228e3e
 inline void
5228e3e
 scsi_set_uint32(unsigned char *c, uint32_t val)
5228e3e
 {
5228e3e
-	*(uint32_t *)c = htonl(val);
5228e3e
+	c[0] = val >> 24;
5228e3e
+	c[1] = val >> 16;
5228e3e
+	c[2] = val >> 8;
5228e3e
+	c[3] = val;
5228e3e
 }
5228e3e
 
5228e3e
 inline void
5228e3e
 scsi_set_uint16(unsigned char *c, uint16_t val)
5228e3e
 {
5228e3e
-	*(uint16_t *)c = htons(val);
5228e3e
+	c[0] = val >> 8;
5228e3e
+	c[1] = val;
5228e3e
 }
5228e3e
 
5228e3e
 /*
5228e3e
-- 
5228e3e
1.8.1.4
5228e3e