mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
netfilter: xtables: change targets to return error code
Part of the transition of done by this semantic patch:
// <smpl>
@ rule1 @
struct xt_target ops;
identifier check;
@@
ops.checkentry = check;
@@
identifier rule1.check;
@@
check(...) { <...
-return true;
+return 0;
...> }
@@
identifier rule1.check;
@@
check(...) { <...
-return false;
+return -EINVAL;
...> }
// </smpl>
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
This commit is contained in:
@@ -63,11 +63,11 @@ static int ebt_arpreply_tg_check(const struct xt_tgchk_param *par)
|
||||
const struct ebt_entry *e = par->entryinfo;
|
||||
|
||||
if (BASE_CHAIN && info->target == EBT_RETURN)
|
||||
return false;
|
||||
return -EINVAL;
|
||||
if (e->ethproto != htons(ETH_P_ARP) ||
|
||||
e->invflags & EBT_IPROTO)
|
||||
return false;
|
||||
return true;
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_target ebt_arpreply_tg_reg __read_mostly = {
|
||||
|
||||
@@ -32,7 +32,7 @@ static int ebt_dnat_tg_check(const struct xt_tgchk_param *par)
|
||||
unsigned int hook_mask;
|
||||
|
||||
if (BASE_CHAIN && info->target == EBT_RETURN)
|
||||
return false;
|
||||
return -EINVAL;
|
||||
|
||||
hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
|
||||
if ((strcmp(par->table, "nat") != 0 ||
|
||||
@@ -40,10 +40,10 @@ static int ebt_dnat_tg_check(const struct xt_tgchk_param *par)
|
||||
(1 << NF_BR_LOCAL_OUT)))) &&
|
||||
(strcmp(par->table, "broute") != 0 ||
|
||||
hook_mask & ~(1 << NF_BR_BROUTING)))
|
||||
return false;
|
||||
return -EINVAL;
|
||||
if (INVALID_TARGET)
|
||||
return false;
|
||||
return true;
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_target ebt_dnat_tg_reg __read_mostly = {
|
||||
|
||||
@@ -29,11 +29,11 @@ static int ebt_log_tg_check(const struct xt_tgchk_param *par)
|
||||
struct ebt_log_info *info = par->targinfo;
|
||||
|
||||
if (info->bitmask & ~EBT_LOG_MASK)
|
||||
return false;
|
||||
return -EINVAL;
|
||||
if (info->loglevel >= 8)
|
||||
return false;
|
||||
return -EINVAL;
|
||||
info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0';
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct tcpudphdr
|
||||
|
||||
@@ -43,14 +43,14 @@ static int ebt_mark_tg_check(const struct xt_tgchk_param *par)
|
||||
|
||||
tmp = info->target | ~EBT_VERDICT_BITS;
|
||||
if (BASE_CHAIN && tmp == EBT_RETURN)
|
||||
return false;
|
||||
return -EINVAL;
|
||||
if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
|
||||
return false;
|
||||
return -EINVAL;
|
||||
tmp = info->target & ~EBT_VERDICT_BITS;
|
||||
if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE &&
|
||||
tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE)
|
||||
return false;
|
||||
return true;
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_COMPAT
|
||||
struct compat_ebt_mark_t_info {
|
||||
|
||||
@@ -40,9 +40,9 @@ static int ebt_nflog_tg_check(const struct xt_tgchk_param *par)
|
||||
struct ebt_nflog_info *info = par->targinfo;
|
||||
|
||||
if (info->flags & ~EBT_NFLOG_MASK)
|
||||
return false;
|
||||
return -EINVAL;
|
||||
info->prefix[EBT_NFLOG_PREFIX_SIZE - 1] = '\0';
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_target ebt_nflog_tg_reg __read_mostly = {
|
||||
|
||||
@@ -38,17 +38,17 @@ static int ebt_redirect_tg_check(const struct xt_tgchk_param *par)
|
||||
unsigned int hook_mask;
|
||||
|
||||
if (BASE_CHAIN && info->target == EBT_RETURN)
|
||||
return false;
|
||||
return -EINVAL;
|
||||
|
||||
hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
|
||||
if ((strcmp(par->table, "nat") != 0 ||
|
||||
hook_mask & ~(1 << NF_BR_PRE_ROUTING)) &&
|
||||
(strcmp(par->table, "broute") != 0 ||
|
||||
hook_mask & ~(1 << NF_BR_BROUTING)))
|
||||
return false;
|
||||
return -EINVAL;
|
||||
if (INVALID_TARGET)
|
||||
return false;
|
||||
return true;
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_target ebt_redirect_tg_reg __read_mostly = {
|
||||
|
||||
@@ -49,14 +49,14 @@ static int ebt_snat_tg_check(const struct xt_tgchk_param *par)
|
||||
|
||||
tmp = info->target | ~EBT_VERDICT_BITS;
|
||||
if (BASE_CHAIN && tmp == EBT_RETURN)
|
||||
return false;
|
||||
return -EINVAL;
|
||||
|
||||
if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
|
||||
return false;
|
||||
return -EINVAL;
|
||||
tmp = info->target | EBT_VERDICT_BITS;
|
||||
if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT)
|
||||
return false;
|
||||
return true;
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_target ebt_snat_tg_reg __read_mostly = {
|
||||
|
||||
@@ -254,14 +254,14 @@ static int ebt_ulog_tg_check(const struct xt_tgchk_param *par)
|
||||
struct ebt_ulog_info *uloginfo = par->targinfo;
|
||||
|
||||
if (uloginfo->nlgroup > 31)
|
||||
return false;
|
||||
return -EINVAL;
|
||||
|
||||
uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0';
|
||||
|
||||
if (uloginfo->qthreshold > EBT_ULOG_MAX_QLEN)
|
||||
uloginfo->qthreshold = EBT_ULOG_MAX_QLEN;
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_target ebt_ulog_tg_reg __read_mostly = {
|
||||
|
||||
@@ -358,13 +358,13 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
|
||||
cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT &&
|
||||
cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT_DPT) {
|
||||
pr_info("unknown mode %u\n", cipinfo->hash_mode);
|
||||
return false;
|
||||
return -EINVAL;
|
||||
|
||||
}
|
||||
if (e->ip.dmsk.s_addr != htonl(0xffffffff) ||
|
||||
e->ip.dst.s_addr == 0) {
|
||||
pr_info("Please specify destination IP\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* FIXME: further sanity checks */
|
||||
@@ -374,20 +374,20 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
|
||||
if (!(cipinfo->flags & CLUSTERIP_FLAG_NEW)) {
|
||||
pr_info("no config found for %pI4, need 'new'\n",
|
||||
&e->ip.dst.s_addr);
|
||||
return false;
|
||||
return -EINVAL;
|
||||
} else {
|
||||
struct net_device *dev;
|
||||
|
||||
if (e->ip.iniface[0] == '\0') {
|
||||
pr_info("Please specify an interface name\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev = dev_get_by_name(&init_net, e->ip.iniface);
|
||||
if (!dev) {
|
||||
pr_info("no such interface %s\n",
|
||||
e->ip.iniface);
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
config = clusterip_config_init(cipinfo,
|
||||
@@ -395,7 +395,7 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
|
||||
if (!config) {
|
||||
pr_info("cannot allocate config\n");
|
||||
dev_put(dev);
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
dev_mc_add(config->dev,config->clustermac, ETH_ALEN, 0);
|
||||
}
|
||||
@@ -405,10 +405,10 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
|
||||
if (nf_ct_l3proto_try_module_get(par->family) < 0) {
|
||||
pr_info("cannot load conntrack support for proto=%u\n",
|
||||
par->family);
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* drop reference count of cluster config when rule is deleted */
|
||||
|
||||
@@ -100,18 +100,18 @@ static int ecn_tg_check(const struct xt_tgchk_param *par)
|
||||
|
||||
if (einfo->operation & IPT_ECN_OP_MASK) {
|
||||
pr_info("unsupported ECN operation %x\n", einfo->operation);
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (einfo->ip_ect & ~IPT_ECN_IP_MASK) {
|
||||
pr_info("new ECT codepoint %x out of mask\n", einfo->ip_ect);
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR)) &&
|
||||
(e->ip.proto != IPPROTO_TCP || (e->ip.invflags & XT_INV_PROTO))) {
|
||||
pr_info("cannot use TCP operations on a non-tcp rule\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_target ecn_tg_reg __read_mostly = {
|
||||
|
||||
@@ -445,13 +445,13 @@ static int log_tg_check(const struct xt_tgchk_param *par)
|
||||
|
||||
if (loginfo->level >= 8) {
|
||||
pr_debug("level %u >= 8\n", loginfo->level);
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
|
||||
pr_debug("prefix is not null-terminated\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_target log_tg_reg __read_mostly = {
|
||||
|
||||
@@ -34,13 +34,13 @@ static int masquerade_tg_check(const struct xt_tgchk_param *par)
|
||||
|
||||
if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
|
||||
pr_debug("bad MAP_IPS.\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (mr->rangesize != 1) {
|
||||
pr_debug("bad rangesize %u\n", mr->rangesize);
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
|
||||
@@ -28,13 +28,13 @@ static int netmap_tg_check(const struct xt_tgchk_param *par)
|
||||
|
||||
if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) {
|
||||
pr_debug("bad MAP_IPS.\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (mr->rangesize != 1) {
|
||||
pr_debug("bad rangesize %u.\n", mr->rangesize);
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
|
||||
@@ -32,13 +32,13 @@ static int redirect_tg_check(const struct xt_tgchk_param *par)
|
||||
|
||||
if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
|
||||
pr_debug("bad MAP_IPS.\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (mr->rangesize != 1) {
|
||||
pr_debug("bad rangesize %u.\n", mr->rangesize);
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
|
||||
@@ -181,16 +181,16 @@ static int reject_tg_check(const struct xt_tgchk_param *par)
|
||||
|
||||
if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
|
||||
pr_info("ECHOREPLY no longer supported.\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
} else if (rejinfo->with == IPT_TCP_RESET) {
|
||||
/* Must specify that it's a TCP packet */
|
||||
if (e->ip.proto != IPPROTO_TCP ||
|
||||
(e->ip.invflags & XT_INV_PROTO)) {
|
||||
pr_info("TCP_RESET invalid for non-tcp\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_target reject_tg_reg __read_mostly = {
|
||||
|
||||
@@ -313,14 +313,14 @@ static int ulog_tg_check(const struct xt_tgchk_param *par)
|
||||
|
||||
if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
|
||||
pr_debug("prefix not null-terminated\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (loginfo->qthreshold > ULOG_MAX_QLEN) {
|
||||
pr_debug("queue threshold %Zu > MAX_QLEN\n",
|
||||
loginfo->qthreshold);
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
@@ -81,9 +81,9 @@ static int ipt_snat_checkentry(const struct xt_tgchk_param *par)
|
||||
/* Must be a valid range */
|
||||
if (mr->rangesize != 1) {
|
||||
pr_info("SNAT: multiple ranges no longer supported\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ipt_dnat_checkentry(const struct xt_tgchk_param *par)
|
||||
@@ -93,9 +93,9 @@ static int ipt_dnat_checkentry(const struct xt_tgchk_param *par)
|
||||
/* Must be a valid range */
|
||||
if (mr->rangesize != 1) {
|
||||
pr_info("DNAT: multiple ranges no longer supported\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
|
||||
@@ -457,13 +457,13 @@ static int log_tg6_check(const struct xt_tgchk_param *par)
|
||||
|
||||
if (loginfo->level >= 8) {
|
||||
pr_debug("level %u >= 8\n", loginfo->level);
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
|
||||
pr_debug("prefix not null-terminated\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_target log_tg6_reg __read_mostly = {
|
||||
|
||||
@@ -220,16 +220,16 @@ static int reject_tg6_check(const struct xt_tgchk_param *par)
|
||||
|
||||
if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
|
||||
pr_info("ECHOREPLY is not supported.\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
} else if (rejinfo->with == IP6T_TCP_RESET) {
|
||||
/* Must specify that it's a TCP packet */
|
||||
if (e->ipv6.proto != IPPROTO_TCP ||
|
||||
(e->ipv6.invflags & XT_INV_PROTO)) {
|
||||
pr_info("TCP_RESET illegal for non-tcp\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_target reject_tg6_reg __read_mostly = {
|
||||
|
||||
@@ -528,6 +528,8 @@ EXPORT_SYMBOL_GPL(xt_compat_match_to_user);
|
||||
int xt_check_target(struct xt_tgchk_param *par,
|
||||
unsigned int size, u_int8_t proto, bool inv_proto)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (XT_ALIGN(par->target->targetsize) != size) {
|
||||
pr_err("%s_tables: %s.%u target: invalid size "
|
||||
"%u (kernel) != (user) %u\n",
|
||||
@@ -559,8 +561,14 @@ int xt_check_target(struct xt_tgchk_param *par,
|
||||
par->target->proto);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (par->target->checkentry != NULL && !par->target->checkentry(par))
|
||||
return -EINVAL;
|
||||
if (par->target->checkentry != NULL) {
|
||||
ret = par->target->checkentry(par);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
else if (ret > 0)
|
||||
/* Flag up potential errors. */
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_check_target);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user