net: neighbour: prohibit negative value for unres_qlen_bytes parameter
Subsystems (2)
PATCH 1/2 net: neighbour: prohibit negative value for unres_qlen_bytes parameter
From: Shan Wei <[email protected]>
unres_qlen_bytes and unres_qlen are int type.
But multiple relation(unres_qlen_bytes = unres_qlen * SKB_TRUESIZE(ETH_FRAME_LEN)) will cause type overflow when seting unres_qlen. e.g.
$ echo 1027506 > /proc/sys/net/ipv4/neigh/eth1/unres_qlen $ cat /proc/sys/net/ipv4/neigh/eth1/unres_qlen 1182657265 $ cat /proc/sys/net/ipv4/neigh/eth1/unres_qlen_bytes -2147479756
The gutted value is not that we setting。
But user/administrator don't know this is caused by int type overflow.
what's more, it is meaningless and even dangerous that unres_qlen_bytes is set with negative number. Because, for unresolved neighbour address, kernel will cache packets without limit in __neigh_event_send()(e.g. (u32)-1 = 2GB).
--- net/core/neighbour.c | 17 ++++++++++++----- 1 files changed, 12 insertions(+), 5 deletions(-)
net/core/neighbour.c +12 -5
@@ -62,6 +62,9 @@ static void __neigh_notify(struct neighbour *n, int type, int flags);static void neigh_update_notify (struct neighbour *neigh);static int pneigh_ifdown (struct neigh_table *tbl,struct net_device *dev); +static int zero; +static int unres_qlen_max =INT_MAX /SKB_TRUESIZE (ETH_FRAME_LEN ); +static struct neigh_table *neigh_tables;#ifdef CONFIG_PROC_FS static const struct file_operations neigh_stat_seq_fops;
@@ -1787,8 +1790,7 @@ static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms)nla_put_u32 (skb,NDTPA_QUEUE_LENBYTES , parms->queue_len_bytes) ||/* approximative value for deprecated QUEUE_LEN (in packets) */ nla_put_u32 (skb,NDTPA_QUEUE_LEN , -DIV_ROUND_UP (parms->queue_len_bytes, -SKB_TRUESIZE (ETH_FRAME_LEN ))) || + parms->queue_len_bytes /SKB_TRUESIZE (ETH_FRAME_LEN )) ||nla_put_u32 (skb,NDTPA_PROXY_QLEN , parms->proxy_qlen) ||nla_put_u32 (skb,NDTPA_APP_PROBES , parms->app_probes) || nla_put_u32(skb, NDTPA_UCAST_PROBES, parms->ucast_probes) ||
@@ -2777,9 +2779,13 @@ static int proc_unres_qlen(ctl_table *ctl, int write, void __user *buffer,int size, ret;ctl_table tmp = *ctl; + tmp.extra1 = &zero; + tmp.extra2 = &unres_qlen_max; tmp.data = &size; - size =DIV_ROUND_UP (*(int *)ctl->data,SKB_TRUESIZE (ETH_FRAME_LEN )); - ret =proc_dointvec (&tmp, write, buffer, lenp, ppos); + + size = *(int *)ctl->data /SKB_TRUESIZE (ETH_FRAME_LEN ); + ret =proc_dointvec_minmax (&tmp, write, buffer, lenp, ppos); +if (write && !ret) *(int *)ctl->data = size *SKB_TRUESIZE (ETH_FRAME_LEN );return ret;
@@ -2865,7 +2871,8 @@ static struct neigh_sysctl_table { .procname = "unres_qlen_bytes", .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, + .extra1 = &zero, + .proc_handler = proc_dointvec_minmax, }, [NEIGH_VAR_PROXY_QLEN] = { .procname = "proxy_qlen",
Signature · 1 line
1.7.1
From: Shan Wei <[email protected]>
Date: Wed, 05 Dec 2012 12:49:15 +0800
Quoted 15 lines
From: Shan Wei <[email protected]>
unres_qlen_bytesandunres_qlenare int type.
But multiplerelation(unres_qlen_bytes = unres_qlen * SKB_TRUESIZE(ETH_FRAME_LEN))will cause type overflow when setingunres_qlen. e.g.$ echo 1027506 > /proc/sys/net/ipv4/neigh/eth1/unres_qlen $ cat /proc/sys/net/ipv4/neigh/eth1/unres_qlen 1182657265 $ cat /proc/sys/net/ipv4/neigh/eth1/unres_qlen_bytes -2147479756The gutted value is not that we setting。
But user/administrator don't know this is caused by int type overflow.
Quoted 6 lines
what's more, it is meaningless and even dangerous that
unres_qlen_bytesis set with negative number. Because, for unresolved neighbour address, kernel will cache packets without limit in __neigh_event_send()(e.g. (u32)-1 = 2GB).Signed-off-by Shan Wei <[email protected]>
Applied.