aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/cipso_ipv4.c
diff options
context:
space:
mode:
authorPaul Moore <paul.moore@hp.com>2007-06-07 21:38:14 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-06-08 16:33:10 -0400
commit50e5d35ce2c4190cead13a091ea1ceab47d29cc2 (patch)
treeae400ba823701f51bd304d85f4e7a28be22c3ac7 /net/ipv4/cipso_ipv4.c
parentba6ff9f2b5c6018b293bd21083ffaa5ad710e671 (diff)
[CIPSO]: Fix several unaligned kernel accesses in the CIPSO engine.
IPv4 options are not very well aligned within the packet and the format of a CIPSO option is even worse. The result is that the CIPSO engine in the kernel does a few unaligned accesses when parsing and validating incoming packets with CIPSO options attached which generate error messages on certain alignment sensitive platforms. This patch fixes this by marking these unaligned accesses with the get_unaliagned() macro. Signed-off-by: Paul Moore <paul.moore@hp.com> Acked-by: James Morris <jmorris@namei.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/cipso_ipv4.c')
-rw-r--r--net/ipv4/cipso_ipv4.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index fc839f9148ec..ab56a052ce31 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -45,6 +45,7 @@
45#include <net/cipso_ipv4.h> 45#include <net/cipso_ipv4.h>
46#include <asm/atomic.h> 46#include <asm/atomic.h>
47#include <asm/bug.h> 47#include <asm/bug.h>
48#include <asm/unaligned.h>
48 49
49struct cipso_v4_domhsh_entry { 50struct cipso_v4_domhsh_entry {
50 char *domain; 51 char *domain;
@@ -1000,7 +1001,7 @@ static int cipso_v4_map_cat_enum_valid(const struct cipso_v4_doi *doi_def,
1000 return -EFAULT; 1001 return -EFAULT;
1001 1002
1002 for (iter = 0; iter < enumcat_len; iter += 2) { 1003 for (iter = 0; iter < enumcat_len; iter += 2) {
1003 cat = ntohs(*((__be16 *)&enumcat[iter])); 1004 cat = ntohs(get_unaligned((__be16 *)&enumcat[iter]));
1004 if (cat <= cat_prev) 1005 if (cat <= cat_prev)
1005 return -EFAULT; 1006 return -EFAULT;
1006 cat_prev = cat; 1007 cat_prev = cat;
@@ -1068,8 +1069,8 @@ static int cipso_v4_map_cat_enum_ntoh(const struct cipso_v4_doi *doi_def,
1068 1069
1069 for (iter = 0; iter < net_cat_len; iter += 2) { 1070 for (iter = 0; iter < net_cat_len; iter += 2) {
1070 ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat, 1071 ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat,
1071 ntohs(*((__be16 *)&net_cat[iter])), 1072 ntohs(get_unaligned((__be16 *)&net_cat[iter])),
1072 GFP_ATOMIC); 1073 GFP_ATOMIC);
1073 if (ret_val != 0) 1074 if (ret_val != 0)
1074 return ret_val; 1075 return ret_val;
1075 } 1076 }
@@ -1102,9 +1103,10 @@ static int cipso_v4_map_cat_rng_valid(const struct cipso_v4_doi *doi_def,
1102 return -EFAULT; 1103 return -EFAULT;
1103 1104
1104 for (iter = 0; iter < rngcat_len; iter += 4) { 1105 for (iter = 0; iter < rngcat_len; iter += 4) {
1105 cat_high = ntohs(*((__be16 *)&rngcat[iter])); 1106 cat_high = ntohs(get_unaligned((__be16 *)&rngcat[iter]));
1106 if ((iter + 4) <= rngcat_len) 1107 if ((iter + 4) <= rngcat_len)
1107 cat_low = ntohs(*((__be16 *)&rngcat[iter + 2])); 1108 cat_low = ntohs(
1109 get_unaligned((__be16 *)&rngcat[iter + 2]));
1108 else 1110 else
1109 cat_low = 0; 1111 cat_low = 0;
1110 1112
@@ -1201,9 +1203,10 @@ static int cipso_v4_map_cat_rng_ntoh(const struct cipso_v4_doi *doi_def,
1201 u16 cat_high; 1203 u16 cat_high;
1202 1204
1203 for (net_iter = 0; net_iter < net_cat_len; net_iter += 4) { 1205 for (net_iter = 0; net_iter < net_cat_len; net_iter += 4) {
1204 cat_high = ntohs(*((__be16 *)&net_cat[net_iter])); 1206 cat_high = ntohs(get_unaligned((__be16 *)&net_cat[net_iter]));
1205 if ((net_iter + 4) <= net_cat_len) 1207 if ((net_iter + 4) <= net_cat_len)
1206 cat_low = ntohs(*((__be16 *)&net_cat[net_iter + 2])); 1208 cat_low = ntohs(
1209 get_unaligned((__be16 *)&net_cat[net_iter + 2]));
1207 else 1210 else
1208 cat_low = 0; 1211 cat_low = 0;
1209 1212
@@ -1565,7 +1568,7 @@ int cipso_v4_validate(unsigned char **option)
1565 } 1568 }
1566 1569
1567 rcu_read_lock(); 1570 rcu_read_lock();
1568 doi_def = cipso_v4_doi_search(ntohl(*((__be32 *)&opt[2]))); 1571 doi_def = cipso_v4_doi_search(ntohl(get_unaligned((__be32 *)&opt[2])));
1569 if (doi_def == NULL) { 1572 if (doi_def == NULL) {
1570 err_offset = 2; 1573 err_offset = 2;
1571 goto validate_return_locked; 1574 goto validate_return_locked;
@@ -1856,7 +1859,7 @@ int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
1856 if (ret_val == 0) 1859 if (ret_val == 0)
1857 return ret_val; 1860 return ret_val;
1858 1861
1859 doi = ntohl(*(__be32 *)&cipso_ptr[2]); 1862 doi = ntohl(get_unaligned((__be32 *)&cipso_ptr[2]));
1860 rcu_read_lock(); 1863 rcu_read_lock();
1861 doi_def = cipso_v4_doi_search(doi); 1864 doi_def = cipso_v4_doi_search(doi);
1862 if (doi_def == NULL) { 1865 if (doi_def == NULL) {
@@ -1911,7 +1914,7 @@ int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
1911 if (cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr) == 0) 1914 if (cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr) == 0)
1912 return 0; 1915 return 0;
1913 1916
1914 doi = ntohl(*(__be32 *)&cipso_ptr[2]); 1917 doi = ntohl(get_unaligned((__be32 *)&cipso_ptr[2]));
1915 rcu_read_lock(); 1918 rcu_read_lock();
1916 doi_def = cipso_v4_doi_search(doi); 1919 doi_def = cipso_v4_doi_search(doi);
1917 if (doi_def == NULL) 1920 if (doi_def == NULL)