netfilter: xtables: compat out of scope fix
As per C99 6.2.4(2) when temporary table data goes out of scope, the behaviour is undefined: if (compat) { struct foo tmp; ... private = &tmp; } [dereference private] Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Cc: stable@kernel.org Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
committed by
David S. Miller
parent
13ccdfc2af
commit
14c7dbe043
@@ -925,10 +925,10 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
|
|||||||
if (t && !IS_ERR(t)) {
|
if (t && !IS_ERR(t)) {
|
||||||
struct arpt_getinfo info;
|
struct arpt_getinfo info;
|
||||||
const struct xt_table_info *private = t->private;
|
const struct xt_table_info *private = t->private;
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
if (compat) {
|
|
||||||
struct xt_table_info tmp;
|
struct xt_table_info tmp;
|
||||||
|
|
||||||
|
if (compat) {
|
||||||
ret = compat_table_info(private, &tmp);
|
ret = compat_table_info(private, &tmp);
|
||||||
xt_compat_flush_offsets(NFPROTO_ARP);
|
xt_compat_flush_offsets(NFPROTO_ARP);
|
||||||
private = &tmp;
|
private = &tmp;
|
||||||
|
@@ -1132,10 +1132,10 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
|
|||||||
if (t && !IS_ERR(t)) {
|
if (t && !IS_ERR(t)) {
|
||||||
struct ipt_getinfo info;
|
struct ipt_getinfo info;
|
||||||
const struct xt_table_info *private = t->private;
|
const struct xt_table_info *private = t->private;
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
if (compat) {
|
|
||||||
struct xt_table_info tmp;
|
struct xt_table_info tmp;
|
||||||
|
|
||||||
|
if (compat) {
|
||||||
ret = compat_table_info(private, &tmp);
|
ret = compat_table_info(private, &tmp);
|
||||||
xt_compat_flush_offsets(AF_INET);
|
xt_compat_flush_offsets(AF_INET);
|
||||||
private = &tmp;
|
private = &tmp;
|
||||||
|
@@ -1164,10 +1164,10 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
|
|||||||
if (t && !IS_ERR(t)) {
|
if (t && !IS_ERR(t)) {
|
||||||
struct ip6t_getinfo info;
|
struct ip6t_getinfo info;
|
||||||
const struct xt_table_info *private = t->private;
|
const struct xt_table_info *private = t->private;
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
if (compat) {
|
|
||||||
struct xt_table_info tmp;
|
struct xt_table_info tmp;
|
||||||
|
|
||||||
|
if (compat) {
|
||||||
ret = compat_table_info(private, &tmp);
|
ret = compat_table_info(private, &tmp);
|
||||||
xt_compat_flush_offsets(AF_INET6);
|
xt_compat_flush_offsets(AF_INET6);
|
||||||
private = &tmp;
|
private = &tmp;
|
||||||
|
Reference in New Issue
Block a user