| .. | .. |
|---|
| 1852 | 1852 | if (ext_hdrs[SADB_X_EXT_FILTER - 1]) { |
|---|
| 1853 | 1853 | struct sadb_x_filter *xfilter = ext_hdrs[SADB_X_EXT_FILTER - 1]; |
|---|
| 1854 | 1854 | |
|---|
| 1855 | | - if ((xfilter->sadb_x_filter_splen >= |
|---|
| 1855 | + if ((xfilter->sadb_x_filter_splen > |
|---|
| 1856 | 1856 | (sizeof(xfrm_address_t) << 3)) || |
|---|
| 1857 | | - (xfilter->sadb_x_filter_dplen >= |
|---|
| 1857 | + (xfilter->sadb_x_filter_dplen > |
|---|
| 1858 | 1858 | (sizeof(xfrm_address_t) << 3))) { |
|---|
| 1859 | 1859 | mutex_unlock(&pfk->dump_lock); |
|---|
| 1860 | 1860 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 1944 | 1944 | } |
|---|
| 1945 | 1945 | |
|---|
| 1946 | 1946 | static int |
|---|
| 1947 | | -parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) |
|---|
| 1947 | +parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_policy *pol, |
|---|
| 1948 | + struct sadb_x_ipsecrequest *rq) |
|---|
| 1948 | 1949 | { |
|---|
| 1949 | 1950 | struct net *net = xp_net(xp); |
|---|
| 1950 | 1951 | struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr; |
|---|
| .. | .. |
|---|
| 1962 | 1963 | if ((mode = pfkey_mode_to_xfrm(rq->sadb_x_ipsecrequest_mode)) < 0) |
|---|
| 1963 | 1964 | return -EINVAL; |
|---|
| 1964 | 1965 | t->mode = mode; |
|---|
| 1965 | | - if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_USE) |
|---|
| 1966 | + if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_USE) { |
|---|
| 1967 | + if ((mode == XFRM_MODE_TUNNEL || mode == XFRM_MODE_BEET) && |
|---|
| 1968 | + pol->sadb_x_policy_dir == IPSEC_DIR_OUTBOUND) |
|---|
| 1969 | + return -EINVAL; |
|---|
| 1966 | 1970 | t->optional = 1; |
|---|
| 1967 | | - else if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_UNIQUE) { |
|---|
| 1971 | + } else if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_UNIQUE) { |
|---|
| 1968 | 1972 | t->reqid = rq->sadb_x_ipsecrequest_reqid; |
|---|
| 1969 | 1973 | if (t->reqid > IPSEC_MANUAL_REQID_MAX) |
|---|
| 1970 | 1974 | t->reqid = 0; |
|---|
| .. | .. |
|---|
| 2006 | 2010 | rq->sadb_x_ipsecrequest_len < sizeof(*rq)) |
|---|
| 2007 | 2011 | return -EINVAL; |
|---|
| 2008 | 2012 | |
|---|
| 2009 | | - if ((err = parse_ipsecrequest(xp, rq)) < 0) |
|---|
| 2013 | + if ((err = parse_ipsecrequest(xp, pol, rq)) < 0) |
|---|
| 2010 | 2014 | return err; |
|---|
| 2011 | 2015 | len -= rq->sadb_x_ipsecrequest_len; |
|---|
| 2012 | 2016 | rq = (void*)((u8*)rq + rq->sadb_x_ipsecrequest_len); |
|---|