diff options
| -rw-r--r-- | include/linux/xfrm.h | 7 | ||||
| -rw-r--r-- | include/net/xfrm.h | 1 | ||||
| -rw-r--r-- | net/key/af_key.c | 18 | ||||
| -rw-r--r-- | net/xfrm/xfrm_user.c | 134 |
4 files changed, 142 insertions, 18 deletions
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 492fb9818747..14ecd19f4cdc 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h | |||
| @@ -230,6 +230,12 @@ enum xfrm_ae_ftype_t { | |||
| 230 | #define XFRM_AE_MAX (__XFRM_AE_MAX - 1) | 230 | #define XFRM_AE_MAX (__XFRM_AE_MAX - 1) |
| 231 | }; | 231 | }; |
| 232 | 232 | ||
| 233 | struct xfrm_userpolicy_type { | ||
| 234 | __u8 type; | ||
| 235 | __u16 reserved1; | ||
| 236 | __u8 reserved2; | ||
| 237 | }; | ||
| 238 | |||
| 233 | /* Netlink message attributes. */ | 239 | /* Netlink message attributes. */ |
| 234 | enum xfrm_attr_type_t { | 240 | enum xfrm_attr_type_t { |
| 235 | XFRMA_UNSPEC, | 241 | XFRMA_UNSPEC, |
| @@ -248,6 +254,7 @@ enum xfrm_attr_type_t { | |||
| 248 | XFRMA_SRCADDR, /* xfrm_address_t */ | 254 | XFRMA_SRCADDR, /* xfrm_address_t */ |
| 249 | XFRMA_COADDR, /* xfrm_address_t */ | 255 | XFRMA_COADDR, /* xfrm_address_t */ |
| 250 | XFRMA_LASTUSED, | 256 | XFRMA_LASTUSED, |
| 257 | XFRMA_POLICY_TYPE, /* struct xfrm_userpolicy_type */ | ||
| 251 | __XFRMA_MAX | 258 | __XFRMA_MAX |
| 252 | 259 | ||
| 253 | #define XFRMA_MAX (__XFRMA_MAX - 1) | 260 | #define XFRMA_MAX (__XFRMA_MAX - 1) |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index d341603e4ba8..c75b3287d8f8 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
| @@ -203,6 +203,7 @@ struct km_event | |||
| 203 | u32 proto; | 203 | u32 proto; |
| 204 | u32 byid; | 204 | u32 byid; |
| 205 | u32 aevent; | 205 | u32 aevent; |
| 206 | u32 type; | ||
| 206 | } data; | 207 | } data; |
| 207 | 208 | ||
| 208 | u32 seq; | 209 | u32 seq; |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 19e047b0e678..83b443ddc72f 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
| @@ -1731,7 +1731,8 @@ static u32 gen_reqid(void) | |||
| 1731 | ++reqid; | 1731 | ++reqid; |
| 1732 | if (reqid == 0) | 1732 | if (reqid == 0) |
| 1733 | reqid = IPSEC_MANUAL_REQID_MAX+1; | 1733 | reqid = IPSEC_MANUAL_REQID_MAX+1; |
| 1734 | if (xfrm_policy_walk(check_reqid, (void*)&reqid) != -EEXIST) | 1734 | if (xfrm_policy_walk(XFRM_POLICY_TYPE_MAIN, check_reqid, |
| 1735 | (void*)&reqid) != -EEXIST) | ||
| 1735 | return reqid; | 1736 | return reqid; |
| 1736 | } while (reqid != start); | 1737 | } while (reqid != start); |
| 1737 | return 0; | 1738 | return 0; |
| @@ -2268,7 +2269,8 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
| 2268 | return err; | 2269 | return err; |
| 2269 | } | 2270 | } |
| 2270 | 2271 | ||
| 2271 | xp = xfrm_policy_bysel_ctx(pol->sadb_x_policy_dir-1, &sel, tmp.security, 1); | 2272 | xp = xfrm_policy_bysel_ctx(XFRM_POLICY_TYPE_MAIN, pol->sadb_x_policy_dir-1, |
| 2273 | &sel, tmp.security, 1); | ||
| 2272 | security_xfrm_policy_free(&tmp); | 2274 | security_xfrm_policy_free(&tmp); |
| 2273 | if (xp == NULL) | 2275 | if (xp == NULL) |
| 2274 | return -ENOENT; | 2276 | return -ENOENT; |
| @@ -2330,7 +2332,7 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
| 2330 | if (dir >= XFRM_POLICY_MAX) | 2332 | if (dir >= XFRM_POLICY_MAX) |
| 2331 | return -EINVAL; | 2333 | return -EINVAL; |
| 2332 | 2334 | ||
| 2333 | xp = xfrm_policy_byid(dir, pol->sadb_x_policy_id, | 2335 | xp = xfrm_policy_byid(XFRM_POLICY_TYPE_MAIN, dir, pol->sadb_x_policy_id, |
| 2334 | hdr->sadb_msg_type == SADB_X_SPDDELETE2); | 2336 | hdr->sadb_msg_type == SADB_X_SPDDELETE2); |
| 2335 | if (xp == NULL) | 2337 | if (xp == NULL) |
| 2336 | return -ENOENT; | 2338 | return -ENOENT; |
| @@ -2378,7 +2380,7 @@ static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, struct sadb_msg * | |||
| 2378 | { | 2380 | { |
| 2379 | struct pfkey_dump_data data = { .skb = skb, .hdr = hdr, .sk = sk }; | 2381 | struct pfkey_dump_data data = { .skb = skb, .hdr = hdr, .sk = sk }; |
| 2380 | 2382 | ||
| 2381 | return xfrm_policy_walk(dump_sp, &data); | 2383 | return xfrm_policy_walk(XFRM_POLICY_TYPE_MAIN, dump_sp, &data); |
| 2382 | } | 2384 | } |
| 2383 | 2385 | ||
| 2384 | static int key_notify_policy_flush(struct km_event *c) | 2386 | static int key_notify_policy_flush(struct km_event *c) |
| @@ -2405,7 +2407,8 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
| 2405 | { | 2407 | { |
| 2406 | struct km_event c; | 2408 | struct km_event c; |
| 2407 | 2409 | ||
| 2408 | xfrm_policy_flush(); | 2410 | xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN); |
| 2411 | c.data.type = XFRM_POLICY_TYPE_MAIN; | ||
| 2409 | c.event = XFRM_MSG_FLUSHPOLICY; | 2412 | c.event = XFRM_MSG_FLUSHPOLICY; |
| 2410 | c.pid = hdr->sadb_msg_pid; | 2413 | c.pid = hdr->sadb_msg_pid; |
| 2411 | c.seq = hdr->sadb_msg_seq; | 2414 | c.seq = hdr->sadb_msg_seq; |
| @@ -2667,6 +2670,9 @@ static int pfkey_send_notify(struct xfrm_state *x, struct km_event *c) | |||
| 2667 | 2670 | ||
| 2668 | static int pfkey_send_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c) | 2671 | static int pfkey_send_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c) |
| 2669 | { | 2672 | { |
| 2673 | if (xp && xp->type != XFRM_POLICY_TYPE_MAIN) | ||
| 2674 | return 0; | ||
| 2675 | |||
| 2670 | switch (c->event) { | 2676 | switch (c->event) { |
| 2671 | case XFRM_MSG_POLEXPIRE: | 2677 | case XFRM_MSG_POLEXPIRE: |
| 2672 | return key_notify_policy_expire(xp, c); | 2678 | return key_notify_policy_expire(xp, c); |
| @@ -2675,6 +2681,8 @@ static int pfkey_send_policy_notify(struct xfrm_policy *xp, int dir, struct km_e | |||
| 2675 | case XFRM_MSG_UPDPOLICY: | 2681 | case XFRM_MSG_UPDPOLICY: |
| 2676 | return key_notify_policy(xp, dir, c); | 2682 | return key_notify_policy(xp, dir, c); |
| 2677 | case XFRM_MSG_FLUSHPOLICY: | 2683 | case XFRM_MSG_FLUSHPOLICY: |
| 2684 | if (c->data.type != XFRM_POLICY_TYPE_MAIN) | ||
| 2685 | break; | ||
| 2678 | return key_notify_policy_flush(c); | 2686 | return key_notify_policy_flush(c); |
| 2679 | default: | 2687 | default: |
| 2680 | printk("pfkey: Unknown policy event %d\n", c->event); | 2688 | printk("pfkey: Unknown policy event %d\n", c->event); |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 7303b820bea4..c59a78d2923a 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -786,6 +786,22 @@ static int verify_policy_dir(__u8 dir) | |||
| 786 | return 0; | 786 | return 0; |
| 787 | } | 787 | } |
| 788 | 788 | ||
| 789 | static int verify_policy_type(__u8 type) | ||
| 790 | { | ||
| 791 | switch (type) { | ||
| 792 | case XFRM_POLICY_TYPE_MAIN: | ||
| 793 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
| 794 | case XFRM_POLICY_TYPE_SUB: | ||
| 795 | #endif | ||
| 796 | break; | ||
| 797 | |||
| 798 | default: | ||
| 799 | return -EINVAL; | ||
| 800 | }; | ||
| 801 | |||
| 802 | return 0; | ||
| 803 | } | ||
| 804 | |||
| 789 | static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) | 805 | static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) |
| 790 | { | 806 | { |
| 791 | switch (p->share) { | 807 | switch (p->share) { |
| @@ -879,6 +895,29 @@ static int copy_from_user_tmpl(struct xfrm_policy *pol, struct rtattr **xfrma) | |||
| 879 | return 0; | 895 | return 0; |
| 880 | } | 896 | } |
| 881 | 897 | ||
| 898 | static int copy_from_user_policy_type(u8 *tp, struct rtattr **xfrma) | ||
| 899 | { | ||
| 900 | struct rtattr *rt = xfrma[XFRMA_POLICY_TYPE-1]; | ||
| 901 | struct xfrm_userpolicy_type *upt; | ||
| 902 | __u8 type = XFRM_POLICY_TYPE_MAIN; | ||
| 903 | int err; | ||
| 904 | |||
| 905 | if (rt) { | ||
| 906 | if (rt->rta_len < sizeof(*upt)) | ||
| 907 | return -EINVAL; | ||
| 908 | |||
| 909 | upt = RTA_DATA(rt); | ||
| 910 | type = upt->type; | ||
| 911 | } | ||
| 912 | |||
| 913 | err = verify_policy_type(type); | ||
| 914 | if (err) | ||
| 915 | return err; | ||
| 916 | |||
| 917 | *tp = type; | ||
| 918 | return 0; | ||
| 919 | } | ||
| 920 | |||
| 882 | static void copy_from_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_info *p) | 921 | static void copy_from_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_info *p) |
| 883 | { | 922 | { |
| 884 | xp->priority = p->priority; | 923 | xp->priority = p->priority; |
| @@ -917,16 +956,20 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p, | |||
| 917 | 956 | ||
| 918 | copy_from_user_policy(xp, p); | 957 | copy_from_user_policy(xp, p); |
| 919 | 958 | ||
| 959 | err = copy_from_user_policy_type(&xp->type, xfrma); | ||
| 960 | if (err) | ||
| 961 | goto error; | ||
| 962 | |||
| 920 | if (!(err = copy_from_user_tmpl(xp, xfrma))) | 963 | if (!(err = copy_from_user_tmpl(xp, xfrma))) |
| 921 | err = copy_from_user_sec_ctx(xp, xfrma); | 964 | err = copy_from_user_sec_ctx(xp, xfrma); |
| 922 | 965 | if (err) | |
| 923 | if (err) { | 966 | goto error; |
| 924 | *errp = err; | ||
| 925 | kfree(xp); | ||
| 926 | xp = NULL; | ||
| 927 | } | ||
| 928 | 967 | ||
| 929 | return xp; | 968 | return xp; |
| 969 | error: | ||
| 970 | *errp = err; | ||
| 971 | kfree(xp); | ||
| 972 | return NULL; | ||
| 930 | } | 973 | } |
| 931 | 974 | ||
| 932 | static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) | 975 | static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) |
| @@ -1037,6 +1080,29 @@ static inline int copy_to_user_sec_ctx(struct xfrm_policy *xp, struct sk_buff *s | |||
| 1037 | return 0; | 1080 | return 0; |
| 1038 | } | 1081 | } |
| 1039 | 1082 | ||
| 1083 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
| 1084 | static int copy_to_user_policy_type(struct xfrm_policy *xp, struct sk_buff *skb) | ||
| 1085 | { | ||
| 1086 | struct xfrm_userpolicy_type upt; | ||
| 1087 | |||
| 1088 | memset(&upt, 0, sizeof(upt)); | ||
| 1089 | upt.type = xp->type; | ||
| 1090 | |||
| 1091 | RTA_PUT(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt); | ||
| 1092 | |||
| 1093 | return 0; | ||
| 1094 | |||
| 1095 | rtattr_failure: | ||
| 1096 | return -1; | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | #else | ||
| 1100 | static inline int copy_to_user_policy_type(struct xfrm_policy *xp, struct sk_buff *skb) | ||
| 1101 | { | ||
| 1102 | return 0; | ||
| 1103 | } | ||
| 1104 | #endif | ||
| 1105 | |||
| 1040 | static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr) | 1106 | static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr) |
| 1041 | { | 1107 | { |
| 1042 | struct xfrm_dump_info *sp = ptr; | 1108 | struct xfrm_dump_info *sp = ptr; |
| @@ -1060,6 +1126,8 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr | |||
| 1060 | goto nlmsg_failure; | 1126 | goto nlmsg_failure; |
| 1061 | if (copy_to_user_sec_ctx(xp, skb)) | 1127 | if (copy_to_user_sec_ctx(xp, skb)) |
| 1062 | goto nlmsg_failure; | 1128 | goto nlmsg_failure; |
| 1129 | if (copy_to_user_policy_type(xp, skb) < 0) | ||
| 1130 | goto nlmsg_failure; | ||
| 1063 | 1131 | ||
| 1064 | nlh->nlmsg_len = skb->tail - b; | 1132 | nlh->nlmsg_len = skb->tail - b; |
| 1065 | out: | 1133 | out: |
| @@ -1081,7 +1149,10 @@ static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1081 | info.nlmsg_flags = NLM_F_MULTI; | 1149 | info.nlmsg_flags = NLM_F_MULTI; |
| 1082 | info.this_idx = 0; | 1150 | info.this_idx = 0; |
| 1083 | info.start_idx = cb->args[0]; | 1151 | info.start_idx = cb->args[0]; |
| 1084 | (void) xfrm_policy_walk(dump_one_policy, &info); | 1152 | (void) xfrm_policy_walk(XFRM_POLICY_TYPE_MAIN, dump_one_policy, &info); |
| 1153 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
| 1154 | (void) xfrm_policy_walk(XFRM_POLICY_TYPE_SUB, dump_one_policy, &info); | ||
| 1155 | #endif | ||
| 1085 | cb->args[0] = info.this_idx; | 1156 | cb->args[0] = info.this_idx; |
| 1086 | 1157 | ||
| 1087 | return skb->len; | 1158 | return skb->len; |
| @@ -1117,6 +1188,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr | |||
| 1117 | { | 1188 | { |
| 1118 | struct xfrm_policy *xp; | 1189 | struct xfrm_policy *xp; |
| 1119 | struct xfrm_userpolicy_id *p; | 1190 | struct xfrm_userpolicy_id *p; |
| 1191 | __u8 type = XFRM_POLICY_TYPE_MAIN; | ||
| 1120 | int err; | 1192 | int err; |
| 1121 | struct km_event c; | 1193 | struct km_event c; |
| 1122 | int delete; | 1194 | int delete; |
| @@ -1124,12 +1196,16 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr | |||
| 1124 | p = NLMSG_DATA(nlh); | 1196 | p = NLMSG_DATA(nlh); |
| 1125 | delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY; | 1197 | delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY; |
| 1126 | 1198 | ||
| 1199 | err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma); | ||
| 1200 | if (err) | ||
| 1201 | return err; | ||
| 1202 | |||
| 1127 | err = verify_policy_dir(p->dir); | 1203 | err = verify_policy_dir(p->dir); |
| 1128 | if (err) | 1204 | if (err) |
| 1129 | return err; | 1205 | return err; |
| 1130 | 1206 | ||
| 1131 | if (p->index) | 1207 | if (p->index) |
| 1132 | xp = xfrm_policy_byid(p->dir, p->index, delete); | 1208 | xp = xfrm_policy_byid(type, p->dir, p->index, delete); |
| 1133 | else { | 1209 | else { |
| 1134 | struct rtattr **rtattrs = (struct rtattr **)xfrma; | 1210 | struct rtattr **rtattrs = (struct rtattr **)xfrma; |
| 1135 | struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1]; | 1211 | struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1]; |
| @@ -1146,7 +1222,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr | |||
| 1146 | if ((err = security_xfrm_policy_alloc(&tmp, uctx))) | 1222 | if ((err = security_xfrm_policy_alloc(&tmp, uctx))) |
| 1147 | return err; | 1223 | return err; |
| 1148 | } | 1224 | } |
| 1149 | xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, delete); | 1225 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, delete); |
| 1150 | security_xfrm_policy_free(&tmp); | 1226 | security_xfrm_policy_free(&tmp); |
| 1151 | } | 1227 | } |
| 1152 | if (xp == NULL) | 1228 | if (xp == NULL) |
| @@ -1329,9 +1405,16 @@ out: | |||
| 1329 | 1405 | ||
| 1330 | static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) | 1406 | static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) |
| 1331 | { | 1407 | { |
| 1332 | struct km_event c; | 1408 | struct km_event c; |
| 1409 | __u8 type = XFRM_POLICY_TYPE_MAIN; | ||
| 1410 | int err; | ||
| 1411 | |||
| 1412 | err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma); | ||
| 1413 | if (err) | ||
| 1414 | return err; | ||
| 1333 | 1415 | ||
| 1334 | xfrm_policy_flush(); | 1416 | xfrm_policy_flush(type); |
| 1417 | c.data.type = type; | ||
| 1335 | c.event = nlh->nlmsg_type; | 1418 | c.event = nlh->nlmsg_type; |
| 1336 | c.seq = nlh->nlmsg_seq; | 1419 | c.seq = nlh->nlmsg_seq; |
| 1337 | c.pid = nlh->nlmsg_pid; | 1420 | c.pid = nlh->nlmsg_pid; |
| @@ -1344,10 +1427,15 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void * | |||
| 1344 | struct xfrm_policy *xp; | 1427 | struct xfrm_policy *xp; |
| 1345 | struct xfrm_user_polexpire *up = NLMSG_DATA(nlh); | 1428 | struct xfrm_user_polexpire *up = NLMSG_DATA(nlh); |
| 1346 | struct xfrm_userpolicy_info *p = &up->pol; | 1429 | struct xfrm_userpolicy_info *p = &up->pol; |
| 1430 | __u8 type = XFRM_POLICY_TYPE_MAIN; | ||
| 1347 | int err = -ENOENT; | 1431 | int err = -ENOENT; |
| 1348 | 1432 | ||
| 1433 | err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma); | ||
| 1434 | if (err) | ||
| 1435 | return err; | ||
| 1436 | |||
| 1349 | if (p->index) | 1437 | if (p->index) |
| 1350 | xp = xfrm_policy_byid(p->dir, p->index, 0); | 1438 | xp = xfrm_policy_byid(type, p->dir, p->index, 0); |
| 1351 | else { | 1439 | else { |
| 1352 | struct rtattr **rtattrs = (struct rtattr **)xfrma; | 1440 | struct rtattr **rtattrs = (struct rtattr **)xfrma; |
| 1353 | struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1]; | 1441 | struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1]; |
| @@ -1364,7 +1452,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void * | |||
| 1364 | if ((err = security_xfrm_policy_alloc(&tmp, uctx))) | 1452 | if ((err = security_xfrm_policy_alloc(&tmp, uctx))) |
| 1365 | return err; | 1453 | return err; |
| 1366 | } | 1454 | } |
| 1367 | xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, 0); | 1455 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, 0); |
| 1368 | security_xfrm_policy_free(&tmp); | 1456 | security_xfrm_policy_free(&tmp); |
| 1369 | } | 1457 | } |
| 1370 | 1458 | ||
| @@ -1818,6 +1906,8 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x, | |||
| 1818 | goto nlmsg_failure; | 1906 | goto nlmsg_failure; |
| 1819 | if (copy_to_user_state_sec_ctx(x, skb)) | 1907 | if (copy_to_user_state_sec_ctx(x, skb)) |
| 1820 | goto nlmsg_failure; | 1908 | goto nlmsg_failure; |
| 1909 | if (copy_to_user_policy_type(xp, skb) < 0) | ||
| 1910 | goto nlmsg_failure; | ||
| 1821 | 1911 | ||
| 1822 | nlh->nlmsg_len = skb->tail - b; | 1912 | nlh->nlmsg_len = skb->tail - b; |
| 1823 | return skb->len; | 1913 | return skb->len; |
| @@ -1898,6 +1988,7 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt, | |||
| 1898 | } | 1988 | } |
| 1899 | 1989 | ||
| 1900 | copy_from_user_policy(xp, p); | 1990 | copy_from_user_policy(xp, p); |
| 1991 | xp->type = XFRM_POLICY_TYPE_MAIN; | ||
| 1901 | copy_templates(xp, ut, nr); | 1992 | copy_templates(xp, ut, nr); |
| 1902 | 1993 | ||
| 1903 | if (!xp->security) { | 1994 | if (!xp->security) { |
| @@ -1931,6 +2022,8 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp, | |||
| 1931 | goto nlmsg_failure; | 2022 | goto nlmsg_failure; |
| 1932 | if (copy_to_user_sec_ctx(xp, skb)) | 2023 | if (copy_to_user_sec_ctx(xp, skb)) |
| 1933 | goto nlmsg_failure; | 2024 | goto nlmsg_failure; |
| 2025 | if (copy_to_user_policy_type(xp, skb) < 0) | ||
| 2026 | goto nlmsg_failure; | ||
| 1934 | upe->hard = !!hard; | 2027 | upe->hard = !!hard; |
| 1935 | 2028 | ||
| 1936 | nlh->nlmsg_len = skb->tail - b; | 2029 | nlh->nlmsg_len = skb->tail - b; |
| @@ -2002,6 +2095,8 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * | |||
| 2002 | copy_to_user_policy(xp, p, dir); | 2095 | copy_to_user_policy(xp, p, dir); |
| 2003 | if (copy_to_user_tmpl(xp, skb) < 0) | 2096 | if (copy_to_user_tmpl(xp, skb) < 0) |
| 2004 | goto nlmsg_failure; | 2097 | goto nlmsg_failure; |
| 2098 | if (copy_to_user_policy_type(xp, skb) < 0) | ||
| 2099 | goto nlmsg_failure; | ||
| 2005 | 2100 | ||
| 2006 | nlh->nlmsg_len = skb->tail - b; | 2101 | nlh->nlmsg_len = skb->tail - b; |
| 2007 | 2102 | ||
| @@ -2019,6 +2114,9 @@ static int xfrm_notify_policy_flush(struct km_event *c) | |||
| 2019 | struct nlmsghdr *nlh; | 2114 | struct nlmsghdr *nlh; |
| 2020 | struct sk_buff *skb; | 2115 | struct sk_buff *skb; |
| 2021 | unsigned char *b; | 2116 | unsigned char *b; |
| 2117 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
| 2118 | struct xfrm_userpolicy_type upt; | ||
| 2119 | #endif | ||
| 2022 | int len = NLMSG_LENGTH(0); | 2120 | int len = NLMSG_LENGTH(0); |
| 2023 | 2121 | ||
| 2024 | skb = alloc_skb(len, GFP_ATOMIC); | 2122 | skb = alloc_skb(len, GFP_ATOMIC); |
| @@ -2028,6 +2126,13 @@ static int xfrm_notify_policy_flush(struct km_event *c) | |||
| 2028 | 2126 | ||
| 2029 | 2127 | ||
| 2030 | nlh = NLMSG_PUT(skb, c->pid, c->seq, XFRM_MSG_FLUSHPOLICY, 0); | 2128 | nlh = NLMSG_PUT(skb, c->pid, c->seq, XFRM_MSG_FLUSHPOLICY, 0); |
| 2129 | nlh->nlmsg_flags = 0; | ||
| 2130 | |||
| 2131 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
| 2132 | memset(&upt, 0, sizeof(upt)); | ||
| 2133 | upt.type = c->data.type; | ||
| 2134 | RTA_PUT(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt); | ||
| 2135 | #endif | ||
| 2031 | 2136 | ||
| 2032 | nlh->nlmsg_len = skb->tail - b; | 2137 | nlh->nlmsg_len = skb->tail - b; |
| 2033 | 2138 | ||
| @@ -2035,6 +2140,9 @@ static int xfrm_notify_policy_flush(struct km_event *c) | |||
| 2035 | return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); | 2140 | return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); |
| 2036 | 2141 | ||
| 2037 | nlmsg_failure: | 2142 | nlmsg_failure: |
| 2143 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
| 2144 | rtattr_failure: | ||
| 2145 | #endif | ||
| 2038 | kfree_skb(skb); | 2146 | kfree_skb(skb); |
| 2039 | return -1; | 2147 | return -1; |
| 2040 | } | 2148 | } |
