inet: frags: fix ip6frag_low_thresh boundary
commit 3d23401283e80ceb03f765842787e0e79ff598b7 upstream. Giving an integer to proc_doulongvec_minmax() is dangerous on 64bit arches, since linker might place next to it a non zero value preventing a change to ip6frag_low_thresh. ip6frag_low_thresh is not used anymore in the kernel, but we do not want to prematuraly break user scripts wanting to change it. Since specifying a minimal value of 0 for proc_doulongvec_minmax() is moot, let's remove these zero values in all defrag units. Fixes: 6e00f7dd5e4e ("ipv6: frags: fix /proc/sys/net/ipv6/ip6frag_low_thresh") Signed-off-by: Eric Dumazet <edumazet@google.com> Reported-by: Maciej Żenczykowski <maze@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
826ff79914
commit
bf40801a01
4 changed files with 17 additions and 31 deletions
|
@ -410,7 +410,6 @@ err:
|
|||
}
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static long zero;
|
||||
|
||||
static struct ctl_table lowpan_frags_ns_ctl_table[] = {
|
||||
{
|
||||
|
@ -427,7 +426,6 @@ static struct ctl_table lowpan_frags_ns_ctl_table[] = {
|
|||
.maxlen = sizeof(unsigned long),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_doulongvec_minmax,
|
||||
.extra1 = &zero,
|
||||
.extra2 = &init_net.ieee802154_lowpan.frags.high_thresh
|
||||
},
|
||||
{
|
||||
|
|
|
@ -58,14 +58,6 @@
|
|||
static int sysctl_ipfrag_max_dist __read_mostly = 64;
|
||||
static const char ip_frag_cache_name[] = "ip4-frags";
|
||||
|
||||
struct ipfrag_skb_cb
|
||||
{
|
||||
struct inet_skb_parm h;
|
||||
int offset;
|
||||
};
|
||||
|
||||
#define FRAG_CB(skb) ((struct ipfrag_skb_cb *)((skb)->cb))
|
||||
|
||||
/* Describe an entry in the "incomplete datagrams" queue. */
|
||||
struct ipq {
|
||||
struct inet_frag_queue q;
|
||||
|
@ -353,13 +345,13 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
|
|||
* this fragment, right?
|
||||
*/
|
||||
prev = qp->q.fragments_tail;
|
||||
if (!prev || FRAG_CB(prev)->offset < offset) {
|
||||
if (!prev || prev->ip_defrag_offset < offset) {
|
||||
next = NULL;
|
||||
goto found;
|
||||
}
|
||||
prev = NULL;
|
||||
for (next = qp->q.fragments; next != NULL; next = next->next) {
|
||||
if (FRAG_CB(next)->offset >= offset)
|
||||
if (next->ip_defrag_offset >= offset)
|
||||
break; /* bingo! */
|
||||
prev = next;
|
||||
}
|
||||
|
@ -370,7 +362,7 @@ found:
|
|||
* any overlaps are eliminated.
|
||||
*/
|
||||
if (prev) {
|
||||
int i = (FRAG_CB(prev)->offset + prev->len) - offset;
|
||||
int i = (prev->ip_defrag_offset + prev->len) - offset;
|
||||
|
||||
if (i > 0) {
|
||||
offset += i;
|
||||
|
@ -387,8 +379,8 @@ found:
|
|||
|
||||
err = -ENOMEM;
|
||||
|
||||
while (next && FRAG_CB(next)->offset < end) {
|
||||
int i = end - FRAG_CB(next)->offset; /* overlap is 'i' bytes */
|
||||
while (next && next->ip_defrag_offset < end) {
|
||||
int i = end - next->ip_defrag_offset; /* overlap is 'i' bytes */
|
||||
|
||||
if (i < next->len) {
|
||||
/* Eat head of the next overlapped fragment
|
||||
|
@ -396,7 +388,7 @@ found:
|
|||
*/
|
||||
if (!pskb_pull(next, i))
|
||||
goto err;
|
||||
FRAG_CB(next)->offset += i;
|
||||
next->ip_defrag_offset += i;
|
||||
qp->q.meat -= i;
|
||||
if (next->ip_summed != CHECKSUM_UNNECESSARY)
|
||||
next->ip_summed = CHECKSUM_NONE;
|
||||
|
@ -420,7 +412,13 @@ found:
|
|||
}
|
||||
}
|
||||
|
||||
FRAG_CB(skb)->offset = offset;
|
||||
/* Note : skb->ip_defrag_offset and skb->dev share the same location */
|
||||
dev = skb->dev;
|
||||
if (dev)
|
||||
qp->iif = dev->ifindex;
|
||||
/* Makes sure compiler wont do silly aliasing games */
|
||||
barrier();
|
||||
skb->ip_defrag_offset = offset;
|
||||
|
||||
/* Insert this fragment in the chain of fragments. */
|
||||
skb->next = next;
|
||||
|
@ -431,11 +429,6 @@ found:
|
|||
else
|
||||
qp->q.fragments = skb;
|
||||
|
||||
dev = skb->dev;
|
||||
if (dev) {
|
||||
qp->iif = dev->ifindex;
|
||||
skb->dev = NULL;
|
||||
}
|
||||
qp->q.stamp = skb->tstamp;
|
||||
qp->q.meat += skb->len;
|
||||
qp->ecn |= ecn;
|
||||
|
@ -511,7 +504,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
|
|||
}
|
||||
|
||||
WARN_ON(!head);
|
||||
WARN_ON(FRAG_CB(head)->offset != 0);
|
||||
WARN_ON(head->ip_defrag_offset != 0);
|
||||
|
||||
/* Allocate a new buffer for the datagram. */
|
||||
ihlen = ip_hdrlen(head);
|
||||
|
@ -678,7 +671,7 @@ struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user)
|
|||
EXPORT_SYMBOL(ip_check_defrag);
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static long zero;
|
||||
static int dist_min;
|
||||
|
||||
static struct ctl_table ip4_frags_ns_ctl_table[] = {
|
||||
{
|
||||
|
@ -695,7 +688,6 @@ static struct ctl_table ip4_frags_ns_ctl_table[] = {
|
|||
.maxlen = sizeof(unsigned long),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_doulongvec_minmax,
|
||||
.extra1 = &zero,
|
||||
.extra2 = &init_net.ipv4.frags.high_thresh
|
||||
},
|
||||
{
|
||||
|
@ -724,7 +716,7 @@ static struct ctl_table ip4_frags_ctl_table[] = {
|
|||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = &zero
|
||||
.extra1 = &dist_min,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
|
|
@ -64,7 +64,6 @@ struct nf_ct_frag6_skb_cb
|
|||
static struct inet_frags nf_frags;
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static long zero;
|
||||
|
||||
static struct ctl_table nf_ct_frag6_sysctl_table[] = {
|
||||
{
|
||||
|
@ -80,7 +79,6 @@ static struct ctl_table nf_ct_frag6_sysctl_table[] = {
|
|||
.maxlen = sizeof(unsigned long),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_doulongvec_minmax,
|
||||
.extra1 = &zero,
|
||||
.extra2 = &init_net.nf_frag.frags.high_thresh
|
||||
},
|
||||
{
|
||||
|
|
|
@ -547,7 +547,6 @@ static const struct inet6_protocol frag_protocol = {
|
|||
};
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static int zero;
|
||||
|
||||
static struct ctl_table ip6_frags_ns_ctl_table[] = {
|
||||
{
|
||||
|
@ -563,8 +562,7 @@ static struct ctl_table ip6_frags_ns_ctl_table[] = {
|
|||
.data = &init_net.ipv6.frags.low_thresh,
|
||||
.maxlen = sizeof(unsigned long),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = &zero,
|
||||
.proc_handler = proc_doulongvec_minmax,
|
||||
.extra2 = &init_net.ipv6.frags.high_thresh
|
||||
},
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue