mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 14:12:06 +00:00
netfilter pull request 23-08-31
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEN9lkrMBJgcdVAPub1V2XiooUIOQFAmTv1cgACgkQ1V2XiooU IOSkexAAr7A9dsFLmP5gESXxkMIeJ+ZdwPeKd+XYm1qe+3AFAPd6fo1UxNKIoCD2 aEff/MJy+SImc3khnjRJ1swXZNI1FFOQMNhywqVvWdpT/Z4SB+yt3bYIXM9CG7qQ X1s5n8zlP1WntCk716LGdwEcaA+hcmMTgVPaVPPJOZpNBQsZaB9TjuPMcI05zTBz xkNwRAZFxssCwS0/bDqHH8guC95AxDdzgZRjGL9y1786y10/qNet9/WWxcx+MwTp K8xA3WUPWiBMcY1N1amYb44tzMLWaLedGGzcuDFMth8s+pyxGOJM/QsNUyNG0qPr 9I4bIZWjgsi6OAFXLJQacXH0hXohChIyXFTq3yq09M5AG5EKQi0I9Da1olOtYER7 6yvaEFQICyGWcY9eg1tlqr6ZioKx/3g9Xa54jPcldXl3U0+qhuUj6qIkXrGbnahy yizTpozEmMxFevdMbjCEZ6dRWixjFmB66KeVLuoyBpZXHoXvyGbCKkz/GJ45bFW8 gVgSTLZYtQYYCWA2CIdr3ucXlzibWnhh6b+yB3IYncHUitXu029IA51eeOuuEL9N XAgExjAUU5GwMo6iPFEnIsPM5scYNkwnt90SaW6DaPVqAahqyZ2e84IYzw7zod2v z1IGGp+tjUXIsBMXzLX96JBXWlK6w5nMDnYag4UUQia3X3fUZmc= =2mzW -----END PGP SIGNATURE----- Merge tag 'nf-23-08-31' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains Netfilter fixes for net: 1) Fix mangling of TCP options with non-linear skbuff, from Xiao Liang. 2) OOB read in xt_sctp due to missing sanitization of array length field. From Wander Lairson Costa. 3) OOB read in xt_u32 due to missing sanitization of array length field. Also from Wander Lairson Costa. All of them above, always broken for several releases. 4) Missing audit log for set element reset command, from Phil Sutter. 5) Missing audit log for rule reset command, also from Phil. These audit log support are missing in 6.5. * tag 'nf-23-08-31' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: netfilter: nf_tables: Audit log rule reset netfilter: nf_tables: Audit log setelem reset netfilter: xt_u32: validate user space input netfilter: xt_sctp: validate the flag_info count netfilter: nft_exthdr: Fix non-linear header modification ==================== Link: https://lore.kernel.org/r/20230830235935.465690-1-pablo@netfilter.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
4e60de1e47
@ -117,6 +117,8 @@ enum audit_nfcfgop {
|
||||
AUDIT_NFT_OP_OBJ_RESET,
|
||||
AUDIT_NFT_OP_FLOWTABLE_REGISTER,
|
||||
AUDIT_NFT_OP_FLOWTABLE_UNREGISTER,
|
||||
AUDIT_NFT_OP_SETELEM_RESET,
|
||||
AUDIT_NFT_OP_RULE_RESET,
|
||||
AUDIT_NFT_OP_INVALID,
|
||||
};
|
||||
|
||||
|
@ -143,6 +143,8 @@ static const struct audit_nfcfgop_tab audit_nfcfgs[] = {
|
||||
{ AUDIT_NFT_OP_OBJ_RESET, "nft_reset_obj" },
|
||||
{ AUDIT_NFT_OP_FLOWTABLE_REGISTER, "nft_register_flowtable" },
|
||||
{ AUDIT_NFT_OP_FLOWTABLE_UNREGISTER, "nft_unregister_flowtable" },
|
||||
{ AUDIT_NFT_OP_SETELEM_RESET, "nft_reset_setelem" },
|
||||
{ AUDIT_NFT_OP_RULE_RESET, "nft_reset_rule" },
|
||||
{ AUDIT_NFT_OP_INVALID, "nft_invalid" },
|
||||
};
|
||||
|
||||
|
@ -102,6 +102,7 @@ static const u8 nft2audit_op[NFT_MSG_MAX] = { // enum nf_tables_msg_types
|
||||
[NFT_MSG_NEWFLOWTABLE] = AUDIT_NFT_OP_FLOWTABLE_REGISTER,
|
||||
[NFT_MSG_GETFLOWTABLE] = AUDIT_NFT_OP_INVALID,
|
||||
[NFT_MSG_DELFLOWTABLE] = AUDIT_NFT_OP_FLOWTABLE_UNREGISTER,
|
||||
[NFT_MSG_GETSETELEM_RESET] = AUDIT_NFT_OP_SETELEM_RESET,
|
||||
};
|
||||
|
||||
static void nft_validate_state_update(struct nft_table *table, u8 new_validate_state)
|
||||
@ -3421,6 +3422,18 @@ err:
|
||||
nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
|
||||
}
|
||||
|
||||
static void audit_log_rule_reset(const struct nft_table *table,
|
||||
unsigned int base_seq,
|
||||
unsigned int nentries)
|
||||
{
|
||||
char *buf = kasprintf(GFP_ATOMIC, "%s:%u",
|
||||
table->name, base_seq);
|
||||
|
||||
audit_log_nfcfg(buf, table->family, nentries,
|
||||
AUDIT_NFT_OP_RULE_RESET, GFP_ATOMIC);
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
struct nft_rule_dump_ctx {
|
||||
char *table;
|
||||
char *chain;
|
||||
@ -3527,6 +3540,9 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
|
||||
done:
|
||||
rcu_read_unlock();
|
||||
|
||||
if (reset && idx > cb->args[0])
|
||||
audit_log_rule_reset(table, cb->seq, idx - cb->args[0]);
|
||||
|
||||
cb->args[0] = idx;
|
||||
return skb->len;
|
||||
}
|
||||
@ -3634,6 +3650,9 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
|
||||
if (err < 0)
|
||||
goto err_fill_rule_info;
|
||||
|
||||
if (reset)
|
||||
audit_log_rule_reset(table, nft_pernet(net)->base_seq, 1);
|
||||
|
||||
return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid);
|
||||
|
||||
err_fill_rule_info:
|
||||
@ -5624,13 +5643,25 @@ static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
|
||||
return nf_tables_fill_setelem(args->skb, set, elem, args->reset);
|
||||
}
|
||||
|
||||
static void audit_log_nft_set_reset(const struct nft_table *table,
|
||||
unsigned int base_seq,
|
||||
unsigned int nentries)
|
||||
{
|
||||
char *buf = kasprintf(GFP_ATOMIC, "%s:%u", table->name, base_seq);
|
||||
|
||||
audit_log_nfcfg(buf, table->family, nentries,
|
||||
AUDIT_NFT_OP_SETELEM_RESET, GFP_ATOMIC);
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
struct nft_set_dump_ctx {
|
||||
const struct nft_set *set;
|
||||
struct nft_ctx ctx;
|
||||
};
|
||||
|
||||
static int nft_set_catchall_dump(struct net *net, struct sk_buff *skb,
|
||||
const struct nft_set *set, bool reset)
|
||||
const struct nft_set *set, bool reset,
|
||||
unsigned int base_seq)
|
||||
{
|
||||
struct nft_set_elem_catchall *catchall;
|
||||
u8 genmask = nft_genmask_cur(net);
|
||||
@ -5646,6 +5677,8 @@ static int nft_set_catchall_dump(struct net *net, struct sk_buff *skb,
|
||||
|
||||
elem.priv = catchall->elem;
|
||||
ret = nf_tables_fill_setelem(skb, set, &elem, reset);
|
||||
if (reset && !ret)
|
||||
audit_log_nft_set_reset(set->table, base_seq, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -5725,12 +5758,17 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
set->ops->walk(&dump_ctx->ctx, set, &args.iter);
|
||||
|
||||
if (!args.iter.err && args.iter.count == cb->args[0])
|
||||
args.iter.err = nft_set_catchall_dump(net, skb, set, reset);
|
||||
args.iter.err = nft_set_catchall_dump(net, skb, set,
|
||||
reset, cb->seq);
|
||||
rcu_read_unlock();
|
||||
|
||||
nla_nest_end(skb, nest);
|
||||
nlmsg_end(skb, nlh);
|
||||
|
||||
if (reset && args.iter.count > args.iter.skip)
|
||||
audit_log_nft_set_reset(table, cb->seq,
|
||||
args.iter.count - args.iter.skip);
|
||||
|
||||
if (args.iter.err && args.iter.err != -EMSGSIZE)
|
||||
return args.iter.err;
|
||||
if (args.iter.count == cb->args[0])
|
||||
@ -5955,13 +5993,13 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
|
||||
struct netlink_ext_ack *extack = info->extack;
|
||||
u8 genmask = nft_genmask_cur(info->net);
|
||||
u8 family = info->nfmsg->nfgen_family;
|
||||
int rem, err = 0, nelems = 0;
|
||||
struct net *net = info->net;
|
||||
struct nft_table *table;
|
||||
struct nft_set *set;
|
||||
struct nlattr *attr;
|
||||
struct nft_ctx ctx;
|
||||
bool reset = false;
|
||||
int rem, err = 0;
|
||||
|
||||
table = nft_table_lookup(net, nla[NFTA_SET_ELEM_LIST_TABLE], family,
|
||||
genmask, 0);
|
||||
@ -6004,8 +6042,13 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
|
||||
NL_SET_BAD_ATTR(extack, attr);
|
||||
break;
|
||||
}
|
||||
nelems++;
|
||||
}
|
||||
|
||||
if (reset)
|
||||
audit_log_nft_set_reset(table, nft_pernet(net)->base_seq,
|
||||
nelems);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -238,7 +238,12 @@ static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr,
|
||||
if (!tcph)
|
||||
goto err;
|
||||
|
||||
if (skb_ensure_writable(pkt->skb, nft_thoff(pkt) + tcphdr_len))
|
||||
goto err;
|
||||
|
||||
tcph = (struct tcphdr *)(pkt->skb->data + nft_thoff(pkt));
|
||||
opt = (u8 *)tcph;
|
||||
|
||||
for (i = sizeof(*tcph); i < tcphdr_len - 1; i += optl) {
|
||||
union {
|
||||
__be16 v16;
|
||||
@ -253,15 +258,6 @@ static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr,
|
||||
if (i + optl > tcphdr_len || priv->len + priv->offset > optl)
|
||||
goto err;
|
||||
|
||||
if (skb_ensure_writable(pkt->skb,
|
||||
nft_thoff(pkt) + i + priv->len))
|
||||
goto err;
|
||||
|
||||
tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff,
|
||||
&tcphdr_len);
|
||||
if (!tcph)
|
||||
goto err;
|
||||
|
||||
offset = i + priv->offset;
|
||||
|
||||
switch (priv->len) {
|
||||
@ -325,9 +321,9 @@ static void nft_exthdr_tcp_strip_eval(const struct nft_expr *expr,
|
||||
if (skb_ensure_writable(pkt->skb, nft_thoff(pkt) + tcphdr_len))
|
||||
goto drop;
|
||||
|
||||
opt = (u8 *)nft_tcp_header_pointer(pkt, sizeof(buff), buff, &tcphdr_len);
|
||||
if (!opt)
|
||||
goto err;
|
||||
tcph = (struct tcphdr *)(pkt->skb->data + nft_thoff(pkt));
|
||||
opt = (u8 *)tcph;
|
||||
|
||||
for (i = sizeof(*tcph); i < tcphdr_len - 1; i += optl) {
|
||||
unsigned int j;
|
||||
|
||||
|
@ -149,6 +149,8 @@ static int sctp_mt_check(const struct xt_mtchk_param *par)
|
||||
{
|
||||
const struct xt_sctp_info *info = par->matchinfo;
|
||||
|
||||
if (info->flag_count > ARRAY_SIZE(info->flag_info))
|
||||
return -EINVAL;
|
||||
if (info->flags & ~XT_SCTP_VALID_FLAGS)
|
||||
return -EINVAL;
|
||||
if (info->invflags & ~XT_SCTP_VALID_FLAGS)
|
||||
|
@ -96,11 +96,32 @@ static bool u32_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
return ret ^ data->invert;
|
||||
}
|
||||
|
||||
static int u32_mt_checkentry(const struct xt_mtchk_param *par)
|
||||
{
|
||||
const struct xt_u32 *data = par->matchinfo;
|
||||
const struct xt_u32_test *ct;
|
||||
unsigned int i;
|
||||
|
||||
if (data->ntests > ARRAY_SIZE(data->tests))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < data->ntests; ++i) {
|
||||
ct = &data->tests[i];
|
||||
|
||||
if (ct->nnums > ARRAY_SIZE(ct->location) ||
|
||||
ct->nvalues > ARRAY_SIZE(ct->value))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_match xt_u32_mt_reg __read_mostly = {
|
||||
.name = "u32",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.match = u32_mt,
|
||||
.checkentry = u32_mt_checkentry,
|
||||
.matchsize = sizeof(struct xt_u32),
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user