The commit is pushed to "branch-rh7-3.10.0-327.18.2.vz7.14.x-ovz" and will 
appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-327.18.2.vz7.14.21
------>
commit 508ffc3f26fe937c0197197e6d6b3f88b7450eb1
Author: Florian Westphal <[email protected]>
Date:   Mon Jun 27 15:35:34 2016 +0400

    ms/netfilter: x_tables: make sure e->next_offset covers remaining blob size
    
    ML: 6e94e0cfb0887e4013b3b930fa6ab1fe6bb6ba91
    
    Otherwise this function may read data beyond the ruleset blob.
    
    Signed-off-by: Florian Westphal <[email protected]>
    Signed-off-by: Pablo Neira Ayuso <[email protected]>
    Signed-off-by: Cyrill Gorcunov <[email protected]>
    
    https://jira.sw.ru/browse/PSBM-49001
    
    Reviewed-by: Vladimir Davydov <[email protected]>
---
 net/ipv4/netfilter/arp_tables.c | 6 ++++--
 net/ipv4/netfilter/ip_tables.c  | 6 ++++--
 net/ipv6/netfilter/ip6_tables.c | 6 ++++--
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 5e31404..3a83e07 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -591,7 +591,8 @@ static inline int check_entry_size_and_hooks(struct 
arpt_entry *e,
        unsigned int h;
 
        if ((unsigned long)e % __alignof__(struct arpt_entry) != 0 ||
-           (unsigned char *)e + sizeof(struct arpt_entry) >= limit) {
+           (unsigned char *)e + sizeof(struct arpt_entry) >= limit ||
+           (unsigned char *)e + e->next_offset > limit) {
                duprintf("Bad offset %p\n", e);
                return -EINVAL;
        }
@@ -1243,7 +1244,8 @@ check_compat_entry_size_and_hooks(struct 
compat_arpt_entry *e,
 
        duprintf("check_compat_entry_size_and_hooks %p\n", e);
        if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0 ||
-           (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit) {
+           (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit ||
+           (unsigned char *)e + e->next_offset > limit) {
                duprintf("Bad offset %p, limit = %p\n", e, limit);
                return -EINVAL;
        }
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index fb736df..0542f5d 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -742,7 +742,8 @@ check_entry_size_and_hooks(struct ipt_entry *e,
        unsigned int h;
 
        if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 ||
-           (unsigned char *)e + sizeof(struct ipt_entry) >= limit) {
+           (unsigned char *)e + sizeof(struct ipt_entry) >= limit ||
+           (unsigned char *)e + e->next_offset > limit) {
                duprintf("Bad offset %p\n", e);
                return -EINVAL;
        }
@@ -1490,7 +1491,8 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry 
*e,
 
        duprintf("check_compat_entry_size_and_hooks %p\n", e);
        if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 ||
-           (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit) {
+           (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit ||
+           (unsigned char *)e + e->next_offset > limit) {
                duprintf("Bad offset %p, limit = %p\n", e, limit);
                return -EINVAL;
        }
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 1c8ed76..3b3ace0 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -751,7 +751,8 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
        unsigned int h;
 
        if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 ||
-           (unsigned char *)e + sizeof(struct ip6t_entry) >= limit) {
+           (unsigned char *)e + sizeof(struct ip6t_entry) >= limit ||
+           (unsigned char *)e + e->next_offset > limit) {
                duprintf("Bad offset %p\n", e);
                return -EINVAL;
        }
@@ -1499,7 +1500,8 @@ check_compat_entry_size_and_hooks(struct 
compat_ip6t_entry *e,
 
        duprintf("check_compat_entry_size_and_hooks %p\n", e);
        if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 ||
-           (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit) {
+           (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit ||
+           (unsigned char *)e + e->next_offset > limit) {
                duprintf("Bad offset %p, limit = %p\n", e, limit);
                return -EINVAL;
        }
_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to