aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazunori MIYAZAWA <miyazawa@linux-ipv6.org>2007-04-17 15:32:20 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-17 16:13:21 -0400
commit55569ce256ce29f4624f0007213432c1ed646584 (patch)
treee8c29263844ed733d6d40bbeb871588eaa1a9bd1
parentb4dfa0b1fb39c7ffe74741d60668825de6a47b69 (diff)
[KEY]: Fix conversion between IPSEC_MODE_xxx and XFRM_MODE_xxx.
We should not blindly convert between IPSEC_MODE_xxx and XFRM_MODE_xxx just by incrementing / decrementing because the assumption is not true any longer. Signed-off-by: Kazunori MIYAZAWA <miyazawa@linux-ipv6.org> Singed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
-rw-r--r--net/key/af_key.c90
1 files changed, 75 insertions, 15 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index a4e7e2db0ff3..cf77930ee516 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -630,6 +630,35 @@ pfkey_sockaddr_size(sa_family_t family)
630 /* NOTREACHED */ 630 /* NOTREACHED */
631} 631}
632 632
633static inline int pfkey_mode_from_xfrm(int mode)
634{
635 switch(mode) {
636 case XFRM_MODE_TRANSPORT:
637 return IPSEC_MODE_TRANSPORT;
638 case XFRM_MODE_TUNNEL:
639 return IPSEC_MODE_TUNNEL;
640 case XFRM_MODE_BEET:
641 return IPSEC_MODE_BEET;
642 default:
643 return -1;
644 }
645}
646
647static inline int pfkey_mode_to_xfrm(int mode)
648{
649 switch(mode) {
650 case IPSEC_MODE_ANY: /*XXX*/
651 case IPSEC_MODE_TRANSPORT:
652 return XFRM_MODE_TRANSPORT;
653 case IPSEC_MODE_TUNNEL:
654 return XFRM_MODE_TUNNEL;
655 case IPSEC_MODE_BEET:
656 return XFRM_MODE_BEET;
657 default:
658 return -1;
659 }
660}
661
633static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, int hsc) 662static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, int hsc)
634{ 663{
635 struct sk_buff *skb; 664 struct sk_buff *skb;
@@ -651,6 +680,7 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
651 int encrypt_key_size = 0; 680 int encrypt_key_size = 0;
652 int sockaddr_size; 681 int sockaddr_size;
653 struct xfrm_encap_tmpl *natt = NULL; 682 struct xfrm_encap_tmpl *natt = NULL;
683 int mode;
654 684
655 /* address family check */ 685 /* address family check */
656 sockaddr_size = pfkey_sockaddr_size(x->props.family); 686 sockaddr_size = pfkey_sockaddr_size(x->props.family);
@@ -928,7 +958,11 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
928 sa2 = (struct sadb_x_sa2 *) skb_put(skb, sizeof(struct sadb_x_sa2)); 958 sa2 = (struct sadb_x_sa2 *) skb_put(skb, sizeof(struct sadb_x_sa2));
929 sa2->sadb_x_sa2_len = sizeof(struct sadb_x_sa2)/sizeof(uint64_t); 959 sa2->sadb_x_sa2_len = sizeof(struct sadb_x_sa2)/sizeof(uint64_t);
930 sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2; 960 sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
931 sa2->sadb_x_sa2_mode = x->props.mode + 1; 961 if ((mode = pfkey_mode_from_xfrm(x->props.mode)) < 0) {
962 kfree_skb(skb);
963 return ERR_PTR(-EINVAL);
964 }
965 sa2->sadb_x_sa2_mode = mode;
932 sa2->sadb_x_sa2_reserved1 = 0; 966 sa2->sadb_x_sa2_reserved1 = 0;
933 sa2->sadb_x_sa2_reserved2 = 0; 967 sa2->sadb_x_sa2_reserved2 = 0;
934 sa2->sadb_x_sa2_sequence = 0; 968 sa2->sadb_x_sa2_sequence = 0;
@@ -1155,9 +1189,12 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
1155 1189
1156 if (ext_hdrs[SADB_X_EXT_SA2-1]) { 1190 if (ext_hdrs[SADB_X_EXT_SA2-1]) {
1157 struct sadb_x_sa2 *sa2 = (void*)ext_hdrs[SADB_X_EXT_SA2-1]; 1191 struct sadb_x_sa2 *sa2 = (void*)ext_hdrs[SADB_X_EXT_SA2-1];
1158 x->props.mode = sa2->sadb_x_sa2_mode; 1192 int mode = pfkey_mode_to_xfrm(sa2->sadb_x_sa2_mode);
1159 if (x->props.mode) 1193 if (mode < 0) {
1160 x->props.mode--; 1194 err = -EINVAL;
1195 goto out;
1196 }
1197 x->props.mode = mode;
1161 x->props.reqid = sa2->sadb_x_sa2_reqid; 1198 x->props.reqid = sa2->sadb_x_sa2_reqid;
1162 } 1199 }
1163 1200
@@ -1218,7 +1255,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
1218 struct sadb_address *saddr, *daddr; 1255 struct sadb_address *saddr, *daddr;
1219 struct sadb_msg *out_hdr; 1256 struct sadb_msg *out_hdr;
1220 struct xfrm_state *x = NULL; 1257 struct xfrm_state *x = NULL;
1221 u8 mode; 1258 int mode;
1222 u32 reqid; 1259 u32 reqid;
1223 u8 proto; 1260 u8 proto;
1224 unsigned short family; 1261 unsigned short family;
@@ -1233,7 +1270,9 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
1233 return -EINVAL; 1270 return -EINVAL;
1234 1271
1235 if ((sa2 = ext_hdrs[SADB_X_EXT_SA2-1]) != NULL) { 1272 if ((sa2 = ext_hdrs[SADB_X_EXT_SA2-1]) != NULL) {
1236 mode = sa2->sadb_x_sa2_mode - 1; 1273 mode = pfkey_mode_to_xfrm(sa2->sadb_x_sa2_mode);
1274 if (mode < 0)
1275 return -EINVAL;
1237 reqid = sa2->sadb_x_sa2_reqid; 1276 reqid = sa2->sadb_x_sa2_reqid;
1238 } else { 1277 } else {
1239 mode = 0; 1278 mode = 0;
@@ -1756,6 +1795,7 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1756#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1795#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1757 struct sockaddr_in6 *sin6; 1796 struct sockaddr_in6 *sin6;
1758#endif 1797#endif
1798 int mode;
1759 1799
1760 if (xp->xfrm_nr >= XFRM_MAX_DEPTH) 1800 if (xp->xfrm_nr >= XFRM_MAX_DEPTH)
1761 return -ELOOP; 1801 return -ELOOP;
@@ -1764,7 +1804,9 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1764 return -EINVAL; 1804 return -EINVAL;
1765 1805
1766 t->id.proto = rq->sadb_x_ipsecrequest_proto; /* XXX check proto */ 1806 t->id.proto = rq->sadb_x_ipsecrequest_proto; /* XXX check proto */
1767 t->mode = rq->sadb_x_ipsecrequest_mode-1; 1807 if ((mode = pfkey_mode_to_xfrm(rq->sadb_x_ipsecrequest_mode)) < 0)
1808 return -EINVAL;
1809 t->mode = mode;
1768 if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_USE) 1810 if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_USE)
1769 t->optional = 1; 1811 t->optional = 1;
1770 else if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_UNIQUE) { 1812 else if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_UNIQUE) {
@@ -1877,7 +1919,7 @@ static struct sk_buff * pfkey_xfrm_policy2msg_prep(struct xfrm_policy *xp)
1877 return skb; 1919 return skb;
1878} 1920}
1879 1921
1880static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, int dir) 1922static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, int dir)
1881{ 1923{
1882 struct sadb_msg *hdr; 1924 struct sadb_msg *hdr;
1883 struct sadb_address *addr; 1925 struct sadb_address *addr;
@@ -2014,6 +2056,7 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
2014 struct sadb_x_ipsecrequest *rq; 2056 struct sadb_x_ipsecrequest *rq;
2015 struct xfrm_tmpl *t = xp->xfrm_vec + i; 2057 struct xfrm_tmpl *t = xp->xfrm_vec + i;
2016 int req_size; 2058 int req_size;
2059 int mode;
2017 2060
2018 req_size = sizeof(struct sadb_x_ipsecrequest); 2061 req_size = sizeof(struct sadb_x_ipsecrequest);
2019 if (t->mode == XFRM_MODE_TUNNEL) 2062 if (t->mode == XFRM_MODE_TUNNEL)
@@ -2027,7 +2070,9 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
2027 memset(rq, 0, sizeof(*rq)); 2070 memset(rq, 0, sizeof(*rq));
2028 rq->sadb_x_ipsecrequest_len = req_size; 2071 rq->sadb_x_ipsecrequest_len = req_size;
2029 rq->sadb_x_ipsecrequest_proto = t->id.proto; 2072 rq->sadb_x_ipsecrequest_proto = t->id.proto;
2030 rq->sadb_x_ipsecrequest_mode = t->mode+1; 2073 if ((mode = pfkey_mode_from_xfrm(t->mode)) < 0)
2074 return -EINVAL;
2075 mode = pfkey_mode_from_xfrm(t->mode);
2031 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE; 2076 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE;
2032 if (t->reqid) 2077 if (t->reqid)
2033 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE; 2078 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE;
@@ -2089,6 +2134,8 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
2089 2134
2090 hdr->sadb_msg_len = size / sizeof(uint64_t); 2135 hdr->sadb_msg_len = size / sizeof(uint64_t);
2091 hdr->sadb_msg_reserved = atomic_read(&xp->refcnt); 2136 hdr->sadb_msg_reserved = atomic_read(&xp->refcnt);
2137
2138 return 0;
2092} 2139}
2093 2140
2094static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c) 2141static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c)
@@ -2102,7 +2149,9 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c
2102 err = PTR_ERR(out_skb); 2149 err = PTR_ERR(out_skb);
2103 goto out; 2150 goto out;
2104 } 2151 }
2105 pfkey_xfrm_policy2msg(out_skb, xp, dir); 2152 err = pfkey_xfrm_policy2msg(out_skb, xp, dir);
2153 if (err < 0)
2154 return err;
2106 2155
2107 out_hdr = (struct sadb_msg *) out_skb->data; 2156 out_hdr = (struct sadb_msg *) out_skb->data;
2108 out_hdr->sadb_msg_version = PF_KEY_V2; 2157 out_hdr->sadb_msg_version = PF_KEY_V2;
@@ -2327,7 +2376,9 @@ static int key_pol_get_resp(struct sock *sk, struct xfrm_policy *xp, struct sadb
2327 err = PTR_ERR(out_skb); 2376 err = PTR_ERR(out_skb);
2328 goto out; 2377 goto out;
2329 } 2378 }
2330 pfkey_xfrm_policy2msg(out_skb, xp, dir); 2379 err = pfkey_xfrm_policy2msg(out_skb, xp, dir);
2380 if (err < 0)
2381 goto out;
2331 2382
2332 out_hdr = (struct sadb_msg *) out_skb->data; 2383 out_hdr = (struct sadb_msg *) out_skb->data;
2333 out_hdr->sadb_msg_version = hdr->sadb_msg_version; 2384 out_hdr->sadb_msg_version = hdr->sadb_msg_version;
@@ -2409,6 +2460,7 @@ static int ipsecrequests_to_migrate(struct sadb_x_ipsecrequest *rq1, int len,
2409{ 2460{
2410 int err; 2461 int err;
2411 struct sadb_x_ipsecrequest *rq2; 2462 struct sadb_x_ipsecrequest *rq2;
2463 int mode;
2412 2464
2413 if (len <= sizeof(struct sadb_x_ipsecrequest) || 2465 if (len <= sizeof(struct sadb_x_ipsecrequest) ||
2414 len < rq1->sadb_x_ipsecrequest_len) 2466 len < rq1->sadb_x_ipsecrequest_len)
@@ -2439,7 +2491,9 @@ static int ipsecrequests_to_migrate(struct sadb_x_ipsecrequest *rq1, int len,
2439 return -EINVAL; 2491 return -EINVAL;
2440 2492
2441 m->proto = rq1->sadb_x_ipsecrequest_proto; 2493 m->proto = rq1->sadb_x_ipsecrequest_proto;
2442 m->mode = rq1->sadb_x_ipsecrequest_mode - 1; 2494 if ((mode = pfkey_mode_to_xfrm(rq1->sadb_x_ipsecrequest_mode)) < 0)
2495 return -EINVAL;
2496 m->mode = mode;
2443 m->reqid = rq1->sadb_x_ipsecrequest_reqid; 2497 m->reqid = rq1->sadb_x_ipsecrequest_reqid;
2444 2498
2445 return ((int)(rq1->sadb_x_ipsecrequest_len + 2499 return ((int)(rq1->sadb_x_ipsecrequest_len +
@@ -2579,12 +2633,15 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr)
2579 struct pfkey_dump_data *data = ptr; 2633 struct pfkey_dump_data *data = ptr;
2580 struct sk_buff *out_skb; 2634 struct sk_buff *out_skb;
2581 struct sadb_msg *out_hdr; 2635 struct sadb_msg *out_hdr;
2636 int err;
2582 2637
2583 out_skb = pfkey_xfrm_policy2msg_prep(xp); 2638 out_skb = pfkey_xfrm_policy2msg_prep(xp);
2584 if (IS_ERR(out_skb)) 2639 if (IS_ERR(out_skb))
2585 return PTR_ERR(out_skb); 2640 return PTR_ERR(out_skb);
2586 2641
2587 pfkey_xfrm_policy2msg(out_skb, xp, dir); 2642 err = pfkey_xfrm_policy2msg(out_skb, xp, dir);
2643 if (err < 0)
2644 return err;
2588 2645
2589 out_hdr = (struct sadb_msg *) out_skb->data; 2646 out_hdr = (struct sadb_msg *) out_skb->data;
2590 out_hdr->sadb_msg_version = data->hdr->sadb_msg_version; 2647 out_hdr->sadb_msg_version = data->hdr->sadb_msg_version;
@@ -3513,7 +3570,10 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
3513 3570
3514 for (i = 0, mp = m; i < num_bundles; i++, mp++) { 3571 for (i = 0, mp = m; i < num_bundles; i++, mp++) {
3515 /* old ipsecrequest */ 3572 /* old ipsecrequest */
3516 if (set_ipsecrequest(skb, mp->proto, mp->mode + 1, 3573 int mode = pfkey_mode_from_xfrm(mp->mode);
3574 if (mode < 0)
3575 return -EINVAL;
3576 if (set_ipsecrequest(skb, mp->proto, mode,
3517 (mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE), 3577 (mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE),
3518 mp->reqid, mp->old_family, 3578 mp->reqid, mp->old_family,
3519 &mp->old_saddr, &mp->old_daddr) < 0) { 3579 &mp->old_saddr, &mp->old_daddr) < 0) {
@@ -3521,7 +3581,7 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
3521 } 3581 }
3522 3582
3523 /* new ipsecrequest */ 3583 /* new ipsecrequest */
3524 if (set_ipsecrequest(skb, mp->proto, mp->mode + 1, 3584 if (set_ipsecrequest(skb, mp->proto, mode,
3525 (mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE), 3585 (mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE),
3526 mp->reqid, mp->new_family, 3586 mp->reqid, mp->new_family,
3527 &mp->new_saddr, &mp->new_daddr) < 0) { 3587 &mp->new_saddr, &mp->new_daddr) < 0) {