Skip to content

Commit

Permalink
net: Fix various endianness glitches
Browse files Browse the repository at this point in the history
Sparse can help us find endianness bugs, but we need to make some
cleanups to be able to more easily spot real bugs.

Signed-off-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Eric Dumazet authored and davem330 committed Apr 21, 2010
1 parent cb903bf commit 0eae88f
Show file tree
Hide file tree
Showing 17 changed files with 65 additions and 61 deletions.
2 changes: 1 addition & 1 deletion net/bridge/br_multicast.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

static inline int br_ip_hash(struct net_bridge_mdb_htable *mdb, __be32 ip)
{
return jhash_1word(mdb->secret, (u32)ip) & (mdb->max - 1);
return jhash_1word(mdb->secret, (__force u32)ip) & (mdb->max - 1);
}

static struct net_bridge_mdb_entry *__br_mdb_ip_get(
Expand Down
15 changes: 8 additions & 7 deletions net/bridge/br_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,19 +130,20 @@ struct net_bridge_port
#endif
};

struct br_cpu_netstats {
unsigned long rx_packets;
unsigned long rx_bytes;
unsigned long tx_packets;
unsigned long tx_bytes;
};

struct net_bridge
{
spinlock_t lock;
struct list_head port_list;
struct net_device *dev;

struct br_cpu_netstats __percpu {
unsigned long rx_packets;
unsigned long rx_bytes;
unsigned long tx_packets;
unsigned long tx_bytes;
} *stats;

struct br_cpu_netstats __percpu *stats;
spinlock_t hash_lock;
struct hlist_head hash[BR_HASH_SIZE];
unsigned long feature_mask;
Expand Down
2 changes: 1 addition & 1 deletion net/ethernet/eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ int eth_rebuild_header(struct sk_buff *skb)
default:
printk(KERN_DEBUG
"%s: unable to resolve type %X addresses.\n",
dev->name, (int)eth->h_proto);
dev->name, (__force int)eth->h_proto);

memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
break;
Expand Down
8 changes: 4 additions & 4 deletions net/ipv4/af_inet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1323,8 +1323,8 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head,
if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl)))
goto out_unlock;

id = ntohl(*(u32 *)&iph->id);
flush = (u16)((ntohl(*(u32 *)iph) ^ skb_gro_len(skb)) | (id ^ IP_DF));
id = ntohl(*(__be32 *)&iph->id);
flush = (u16)((ntohl(*(__be32 *)iph) ^ skb_gro_len(skb)) | (id ^ IP_DF));
id >>= 16;

for (p = *head; p; p = p->next) {
Expand All @@ -1337,8 +1337,8 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head,

if ((iph->protocol ^ iph2->protocol) |
(iph->tos ^ iph2->tos) |
(iph->saddr ^ iph2->saddr) |
(iph->daddr ^ iph2->daddr)) {
((__force u32)iph->saddr ^ (__force u32)iph2->saddr) |
((__force u32)iph->daddr ^ (__force u32)iph2->daddr)) {
NAPI_GRO_CB(p)->same_flow = 0;
continue;
}
Expand Down
10 changes: 5 additions & 5 deletions net/ipv4/ipmr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1772,10 +1772,10 @@ int ip_mr_input(struct sk_buff *skb)

vif = ipmr_find_vif(mrt, skb->dev);
if (vif >= 0) {
int err = ipmr_cache_unresolved(mrt, vif, skb);
int err2 = ipmr_cache_unresolved(mrt, vif, skb);
read_unlock(&mrt_lock);

return err;
return err2;
}
read_unlock(&mrt_lock);
kfree_skb(skb);
Expand Down Expand Up @@ -2227,9 +2227,9 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
const struct ipmr_mfc_iter *it = seq->private;
const struct mr_table *mrt = it->mrt;

seq_printf(seq, "%08lX %08lX %-3hd",
(unsigned long) mfc->mfc_mcastgrp,
(unsigned long) mfc->mfc_origin,
seq_printf(seq, "%08X %08X %-3hd",
(__force u32) mfc->mfc_mcastgrp,
(__force u32) mfc->mfc_origin,
mfc->mfc_parent);

if (it->cache != &mrt->mfc_unres_queue) {
Expand Down
29 changes: 14 additions & 15 deletions net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,9 @@ static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat);
(__raw_get_cpu_var(rt_cache_stat).field++)

static inline unsigned int rt_hash(__be32 daddr, __be32 saddr, int idx,
int genid)
int genid)
{
return jhash_3words((__force u32)(__be32)(daddr),
(__force u32)(__be32)(saddr),
return jhash_3words((__force u32)daddr, (__force u32)saddr,
idx, genid)
& rt_hash_mask;
}
Expand Down Expand Up @@ -378,12 +377,13 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v)
struct rtable *r = v;
int len;

seq_printf(seq, "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t"
"%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X%n",
seq_printf(seq, "%s\t%08X\t%08X\t%8X\t%d\t%u\t%d\t"
"%08X\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X%n",
r->u.dst.dev ? r->u.dst.dev->name : "*",
(unsigned long)r->rt_dst, (unsigned long)r->rt_gateway,
(__force u32)r->rt_dst,
(__force u32)r->rt_gateway,
r->rt_flags, atomic_read(&r->u.dst.__refcnt),
r->u.dst.__use, 0, (unsigned long)r->rt_src,
r->u.dst.__use, 0, (__force u32)r->rt_src,
(dst_metric(&r->u.dst, RTAX_ADVMSS) ?
(int)dst_metric(&r->u.dst, RTAX_ADVMSS) + 40 : 0),
dst_metric(&r->u.dst, RTAX_WINDOW),
Expand Down Expand Up @@ -685,18 +685,17 @@ static inline bool rt_caching(const struct net *net)
static inline bool compare_hash_inputs(const struct flowi *fl1,
const struct flowi *fl2)
{
return (__force u32)(((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) |
(fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr) |
return ((((__force u32)fl1->nl_u.ip4_u.daddr ^ (__force u32)fl2->nl_u.ip4_u.daddr) |
((__force u32)fl1->nl_u.ip4_u.saddr ^ (__force u32)fl2->nl_u.ip4_u.saddr) |
(fl1->iif ^ fl2->iif)) == 0);
}

static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
{
return ((__force u32)((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) |
(fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr)) |
return (((__force u32)fl1->nl_u.ip4_u.daddr ^ (__force u32)fl2->nl_u.ip4_u.daddr) |
((__force u32)fl1->nl_u.ip4_u.saddr ^ (__force u32)fl2->nl_u.ip4_u.saddr) |
(fl1->mark ^ fl2->mark) |
(*(u16 *)&fl1->nl_u.ip4_u.tos ^
*(u16 *)&fl2->nl_u.ip4_u.tos) |
(*(u16 *)&fl1->nl_u.ip4_u.tos ^ *(u16 *)&fl2->nl_u.ip4_u.tos) |
(fl1->oif ^ fl2->oif) |
(fl1->iif ^ fl2->iif)) == 0;
}
Expand Down Expand Up @@ -2319,8 +2318,8 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
rcu_read_lock();
for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
rth = rcu_dereference(rth->u.dst.rt_next)) {
if (((rth->fl.fl4_dst ^ daddr) |
(rth->fl.fl4_src ^ saddr) |
if ((((__force u32)rth->fl.fl4_dst ^ (__force u32)daddr) |
((__force u32)rth->fl.fl4_src ^ (__force u32)saddr) |
(rth->fl.iif ^ iif) |
rth->fl.oif |
(rth->fl.fl4_tos ^ tos)) == 0 &&
Expand Down
15 changes: 8 additions & 7 deletions net/ipv4/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2721,7 +2721,7 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb)
struct tcphdr *th2;
unsigned int len;
unsigned int thlen;
unsigned int flags;
__be32 flags;
unsigned int mss = 1;
unsigned int hlen;
unsigned int off;
Expand Down Expand Up @@ -2771,10 +2771,10 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb)

found:
flush = NAPI_GRO_CB(p)->flush;
flush |= flags & TCP_FLAG_CWR;
flush |= (flags ^ tcp_flag_word(th2)) &
~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH);
flush |= th->ack_seq ^ th2->ack_seq;
flush |= (__force int)(flags & TCP_FLAG_CWR);
flush |= (__force int)((flags ^ tcp_flag_word(th2)) &
~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH));
flush |= (__force int)(th->ack_seq ^ th2->ack_seq);
for (i = sizeof(*th); i < thlen; i += 4)
flush |= *(u32 *)((u8 *)th + i) ^
*(u32 *)((u8 *)th2 + i);
Expand All @@ -2795,8 +2795,9 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb)

out_check_final:
flush = len < mss;
flush |= flags & (TCP_FLAG_URG | TCP_FLAG_PSH | TCP_FLAG_RST |
TCP_FLAG_SYN | TCP_FLAG_FIN);
flush |= (__force int)(flags & (TCP_FLAG_URG | TCP_FLAG_PSH |
TCP_FLAG_RST | TCP_FLAG_SYN |
TCP_FLAG_FIN));

if (p && (!NAPI_GRO_CB(skb)->same_flow || flush))
pp = head;
Expand Down
4 changes: 2 additions & 2 deletions net/ipv4/tcp_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -1286,8 +1286,8 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
goto drop_and_release;

/* Secret recipe starts with IP addresses */
*mess++ ^= daddr;
*mess++ ^= saddr;
*mess++ ^= (__force u32)daddr;
*mess++ ^= (__force u32)saddr;

/* plus variable length Initiator Cookie */
c = (u8 *)mess;
Expand Down
4 changes: 2 additions & 2 deletions net/ipv4/tcp_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -861,7 +861,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
th->urg_ptr = htons(tp->snd_up - tcb->seq);
th->urg = 1;
} else if (after(tcb->seq + 0xFFFF, tp->snd_nxt)) {
th->urg_ptr = 0xFFFF;
th->urg_ptr = htons(0xFFFF);
th->urg = 1;
}
}
Expand Down Expand Up @@ -2485,7 +2485,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
*tail-- ^= TCP_SKB_CB(skb)->seq + 1;

/* recommended */
*tail-- ^= ((th->dest << 16) | th->source);
*tail-- ^= (((__force u32)th->dest << 16) | (__force u32)th->source);
*tail-- ^= (u32)(unsigned long)cvp; /* per sockopt */

sha_transform((__u32 *)&xvp->cookie_bakery[0],
Expand Down
8 changes: 4 additions & 4 deletions net/ipv4/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,13 +307,13 @@ static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
static unsigned int udp4_portaddr_hash(struct net *net, __be32 saddr,
unsigned int port)
{
return jhash_1word(saddr, net_hash_mix(net)) ^ port;
return jhash_1word((__force u32)saddr, net_hash_mix(net)) ^ port;
}

int udp_v4_get_port(struct sock *sk, unsigned short snum)
{
unsigned int hash2_nulladdr =
udp4_portaddr_hash(sock_net(sk), INADDR_ANY, snum);
udp4_portaddr_hash(sock_net(sk), htonl(INADDR_ANY), snum);
unsigned int hash2_partial =
udp4_portaddr_hash(sock_net(sk), inet_sk(sk)->inet_rcv_saddr, 0);

Expand Down Expand Up @@ -466,14 +466,14 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
daddr, hnum, dif,
hslot2, slot2);
if (!result) {
hash2 = udp4_portaddr_hash(net, INADDR_ANY, hnum);
hash2 = udp4_portaddr_hash(net, htonl(INADDR_ANY), hnum);
slot2 = hash2 & udptable->mask;
hslot2 = &udptable->hash2[slot2];
if (hslot->count < hslot2->count)
goto begin;

result = udp4_lib_lookup2(net, saddr, sport,
INADDR_ANY, hnum, dif,
htonl(INADDR_ANY), hnum, dif,
hslot2, slot2);
}
rcu_read_unlock();
Expand Down
3 changes: 2 additions & 1 deletion net/ipv6/addrconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,8 @@ static u32 ipv6_addr_hash(const struct in6_addr *addr)
* We perform the hash function over the last 64 bits of the address
* This will include the IEEE address token on links that support it.
*/
return jhash_2words(addr->s6_addr32[2], addr->s6_addr32[3], 0)
return jhash_2words((__force u32)addr->s6_addr32[2],
(__force u32)addr->s6_addr32[3], 0)
& (IN6_ADDR_HSIZE - 1);
}

Expand Down
3 changes: 2 additions & 1 deletion net/ipv6/ip6_fib.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ static __inline__ __be32 addr_bit_set(void *token, int fn_bit)
* htonl(1 << ((~fn_bit)&0x1F))
* See include/asm-generic/bitops/le.h.
*/
return (1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)) & addr[fn_bit >> 5];
return (__force __be32)(1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)) &
addr[fn_bit >> 5];
}

static __inline__ struct fib6_node * node_alloc(void)
Expand Down
4 changes: 2 additions & 2 deletions net/ipv6/tcp_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -1234,12 +1234,12 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
goto drop_and_free;

/* Secret recipe starts with IP addresses */
d = &ipv6_hdr(skb)->daddr.s6_addr32[0];
d = (__force u32 *)&ipv6_hdr(skb)->daddr.s6_addr32[0];
*mess++ ^= *d++;
*mess++ ^= *d++;
*mess++ ^= *d++;
*mess++ ^= *d++;
d = &ipv6_hdr(skb)->saddr.s6_addr32[0];
d = (__force u32 *)&ipv6_hdr(skb)->saddr.s6_addr32[0];
*mess++ ^= *d++;
*mess++ ^= *d++;
*mess++ ^= *d++;
Expand Down
4 changes: 2 additions & 2 deletions net/ipv6/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ static unsigned int udp6_portaddr_hash(struct net *net,
if (ipv6_addr_any(addr6))
hash = jhash_1word(0, mix);
else if (ipv6_addr_v4mapped(addr6))
hash = jhash_1word(addr6->s6_addr32[3], mix);
hash = jhash_1word((__force u32)addr6->s6_addr32[3], mix);
else
hash = jhash2(addr6->s6_addr32, 4, mix);
hash = jhash2((__force u32 *)addr6->s6_addr32, 4, mix);

return hash ^ port;
}
Expand Down
10 changes: 5 additions & 5 deletions net/sched/sch_sfq.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
case htons(ETH_P_IP):
{
const struct iphdr *iph = ip_hdr(skb);
h = iph->daddr;
h2 = iph->saddr ^ iph->protocol;
h = (__force u32)iph->daddr;
h2 = (__force u32)iph->saddr ^ iph->protocol;
if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
(iph->protocol == IPPROTO_TCP ||
iph->protocol == IPPROTO_UDP ||
Expand All @@ -138,8 +138,8 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
case htons(ETH_P_IPV6):
{
struct ipv6hdr *iph = ipv6_hdr(skb);
h = iph->daddr.s6_addr32[3];
h2 = iph->saddr.s6_addr32[3] ^ iph->nexthdr;
h = (__force u32)iph->daddr.s6_addr32[3];
h2 = (__force u32)iph->saddr.s6_addr32[3] ^ iph->nexthdr;
if (iph->nexthdr == IPPROTO_TCP ||
iph->nexthdr == IPPROTO_UDP ||
iph->nexthdr == IPPROTO_UDPLITE ||
Expand All @@ -150,7 +150,7 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
break;
}
default:
h = (unsigned long)skb_dst(skb) ^ skb->protocol;
h = (unsigned long)skb_dst(skb) ^ (__force u32)skb->protocol;
h2 = (unsigned long)skb->sk;
}

Expand Down
2 changes: 1 addition & 1 deletion net/sunrpc/xprt.c
Original file line number Diff line number Diff line change
Expand Up @@ -974,7 +974,7 @@ void xprt_reserve(struct rpc_task *task)

static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt)
{
return xprt->xid++;
return (__force __be32)xprt->xid++;
}

static inline void xprt_init_xid(struct rpc_xprt *xprt)
Expand Down
3 changes: 2 additions & 1 deletion net/xfrm/xfrm_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ static inline unsigned int __xfrm6_addr_hash(xfrm_address_t *addr)

static inline unsigned int __xfrm4_daddr_saddr_hash(xfrm_address_t *daddr, xfrm_address_t *saddr)
{
return ntohl(daddr->a4 + saddr->a4);
u32 sum = (__force u32)daddr->a4 + (__force u32)saddr->a4;
return ntohl((__force __be32)sum);
}

static inline unsigned int __xfrm6_daddr_saddr_hash(xfrm_address_t *daddr, xfrm_address_t *saddr)
Expand Down

0 comments on commit 0eae88f

Please sign in to comment.