Commit d37bed89 authored by Sabrina Dubroca's avatar Sabrina Dubroca Committed by Steffen Klassert
Browse files

xfrm: add extack to validate_tmpl

parent fb7deaba
Loading
Loading
Loading
Loading
+20 −9
Original line number Diff line number Diff line
@@ -1616,13 +1616,16 @@ static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut,
	}
}

static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family)
static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family,
			 struct netlink_ext_ack *extack)
{
	u16 prev_family;
	int i;

	if (nr > XFRM_MAX_DEPTH)
	if (nr > XFRM_MAX_DEPTH) {
		NL_SET_ERR_MSG(extack, "Template count must be <= XFRM_MAX_DEPTH (" __stringify(XFRM_MAX_DEPTH) ")");
		return -EINVAL;
	}

	prev_family = family;

@@ -1642,12 +1645,16 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family)
		case XFRM_MODE_BEET:
			break;
		default:
			if (ut[i].family != prev_family)
			if (ut[i].family != prev_family) {
				NL_SET_ERR_MSG(extack, "Mode in template doesn't support a family change");
				return -EINVAL;
			}
			break;
		}
		if (ut[i].mode >= XFRM_MODE_MAX)
		if (ut[i].mode >= XFRM_MODE_MAX) {
			NL_SET_ERR_MSG(extack, "Mode in template must be < XFRM_MODE_MAX (" __stringify(XFRM_MODE_MAX) ")");
			return -EINVAL;
		}

		prev_family = ut[i].family;

@@ -1659,17 +1666,21 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family)
			break;
#endif
		default:
			NL_SET_ERR_MSG(extack, "Invalid family in template");
			return -EINVAL;
		}

		if (!xfrm_id_proto_valid(ut[i].id.proto))
		if (!xfrm_id_proto_valid(ut[i].id.proto)) {
			NL_SET_ERR_MSG(extack, "Invalid XFRM protocol in template");
			return -EINVAL;
		}
	}

	return 0;
}

static int copy_from_user_tmpl(struct xfrm_policy *pol, struct nlattr **attrs)
static int copy_from_user_tmpl(struct xfrm_policy *pol, struct nlattr **attrs,
			       struct netlink_ext_ack *extack)
{
	struct nlattr *rt = attrs[XFRMA_TMPL];

@@ -1680,7 +1691,7 @@ static int copy_from_user_tmpl(struct xfrm_policy *pol, struct nlattr **attrs)
		int nr = nla_len(rt) / sizeof(*utmpl);
		int err;

		err = validate_tmpl(nr, utmpl, pol->family);
		err = validate_tmpl(nr, utmpl, pol->family, extack);
		if (err)
			return err;

@@ -1757,7 +1768,7 @@ static struct xfrm_policy *xfrm_policy_construct(struct net *net,
	if (err)
		goto error;

	if (!(err = copy_from_user_tmpl(xp, attrs)))
	if (!(err = copy_from_user_tmpl(xp, attrs, extack)))
		err = copy_from_user_sec_ctx(xp, attrs);
	if (err)
		goto error;
@@ -3306,7 +3317,7 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
		return NULL;

	nr = ((len - sizeof(*p)) / sizeof(*ut));
	if (validate_tmpl(nr, ut, p->sel.family))
	if (validate_tmpl(nr, ut, p->sel.family, NULL))
		return NULL;

	if (p->dir > XFRM_POLICY_OUT)