mirror of https://gitee.com/openkylin/linux.git
[IPV6] SNMP: Avoid unaligned accesses.
Because stats pointer may not be aligned for u64, use memcpy to fill u64 values. Issue reported by David Miller <davem@davemloft.net>. Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
This commit is contained in:
parent
9e412ba763
commit
2334e97355
|
@ -172,7 +172,7 @@ int snmp6_alloc_dev(struct inet6_dev *idev);
|
||||||
int snmp6_free_dev(struct inet6_dev *idev);
|
int snmp6_free_dev(struct inet6_dev *idev);
|
||||||
int snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign);
|
int snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign);
|
||||||
void snmp6_mib_free(void *ptr[2]);
|
void snmp6_mib_free(void *ptr[2]);
|
||||||
void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, int bytes);
|
void snmp6_fill_stats(void *stats, struct inet6_dev *idev, int attrtype, int bytes);
|
||||||
|
|
||||||
struct ip6_ra_chain
|
struct ip6_ra_chain
|
||||||
{
|
{
|
||||||
|
|
|
@ -210,20 +210,30 @@ static const struct file_operations snmp6_seq_fops = {
|
||||||
};
|
};
|
||||||
#endif /* CONFIG_PROC_FS */
|
#endif /* CONFIG_PROC_FS */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stats may not be aligned for u64, so use memcpy to avoid
|
||||||
|
* unaligned accesses.
|
||||||
|
*/
|
||||||
|
static inline void __set_u64(void *p, u64 v)
|
||||||
|
{
|
||||||
|
memcpy(p, &v, sizeof(u64));
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
__snmp6_fill_stats(u64 *stats, void **mib, int items, int bytes)
|
__snmp6_fill_stats(void *stats, void **mib, int items, int bytes)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
u8 *p = stats;
|
||||||
int pad = bytes - sizeof(u64) * items;
|
int pad = bytes - sizeof(u64) * items;
|
||||||
BUG_ON(pad < 0);
|
BUG_ON(pad < 0);
|
||||||
stats[0] = items;
|
__set_u64(p, items);
|
||||||
for (i = 1; i < items; i++)
|
for (i = 1, p += sizeof(u64); i < items; i++, p += sizeof(u64))
|
||||||
stats[i] = (u64)fold_field(mib, i);
|
__set_u64(p, fold_field(mib, i));
|
||||||
memset(&stats[items], 0, pad);
|
memset(p, 0, pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, int bytes)
|
snmp6_fill_stats(void *stats, struct inet6_dev *idev, int attrtype, int bytes)
|
||||||
{
|
{
|
||||||
switch(attrtype) {
|
switch(attrtype) {
|
||||||
case IFLA_INET6_STATS:
|
case IFLA_INET6_STATS:
|
||||||
|
|
Loading…
Reference in New Issue