aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ip.h4
-rw-r--r--net/ipv4/ip_options.c14
-rw-r--r--net/ipv4/ip_sockglue.c4
3 files changed, 12 insertions, 10 deletions
diff --git a/include/net/ip.h b/include/net/ip.h
index bcc3afa3df36..531270dc48a6 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -349,9 +349,9 @@ extern int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb);
349extern void ip_options_fragment(struct sk_buff *skb); 349extern void ip_options_fragment(struct sk_buff *skb);
350extern int ip_options_compile(struct net *net, 350extern int ip_options_compile(struct net *net,
351 struct ip_options *opt, struct sk_buff *skb); 351 struct ip_options *opt, struct sk_buff *skb);
352extern int ip_options_get(struct ip_options **optp, 352extern int ip_options_get(struct net *net, struct ip_options **optp,
353 unsigned char *data, int optlen); 353 unsigned char *data, int optlen);
354extern int ip_options_get_from_user(struct ip_options **optp, 354extern int ip_options_get_from_user(struct net *net, struct ip_options **optp,
355 unsigned char __user *data, int optlen); 355 unsigned char __user *data, int optlen);
356extern void ip_options_undo(struct ip_options * opt); 356extern void ip_options_undo(struct ip_options * opt);
357extern void ip_forward_options(struct sk_buff *skb); 357extern void ip_forward_options(struct sk_buff *skb);
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index f0949b42e79e..59f7ddfb29bf 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -507,13 +507,13 @@ static struct ip_options *ip_options_get_alloc(const int optlen)
507 GFP_KERNEL); 507 GFP_KERNEL);
508} 508}
509 509
510static int ip_options_get_finish(struct ip_options **optp, 510static int ip_options_get_finish(struct net *net, struct ip_options **optp,
511 struct ip_options *opt, int optlen) 511 struct ip_options *opt, int optlen)
512{ 512{
513 while (optlen & 3) 513 while (optlen & 3)
514 opt->__data[optlen++] = IPOPT_END; 514 opt->__data[optlen++] = IPOPT_END;
515 opt->optlen = optlen; 515 opt->optlen = optlen;
516 if (optlen && ip_options_compile(&init_net, opt, NULL)) { 516 if (optlen && ip_options_compile(net, opt, NULL)) {
517 kfree(opt); 517 kfree(opt);
518 return -EINVAL; 518 return -EINVAL;
519 } 519 }
@@ -522,7 +522,8 @@ static int ip_options_get_finish(struct ip_options **optp,
522 return 0; 522 return 0;
523} 523}
524 524
525int ip_options_get_from_user(struct ip_options **optp, unsigned char __user *data, int optlen) 525int ip_options_get_from_user(struct net *net, struct ip_options **optp,
526 unsigned char __user *data, int optlen)
526{ 527{
527 struct ip_options *opt = ip_options_get_alloc(optlen); 528 struct ip_options *opt = ip_options_get_alloc(optlen);
528 529
@@ -532,10 +533,11 @@ int ip_options_get_from_user(struct ip_options **optp, unsigned char __user *dat
532 kfree(opt); 533 kfree(opt);
533 return -EFAULT; 534 return -EFAULT;
534 } 535 }
535 return ip_options_get_finish(optp, opt, optlen); 536 return ip_options_get_finish(net, optp, opt, optlen);
536} 537}
537 538
538int ip_options_get(struct ip_options **optp, unsigned char *data, int optlen) 539int ip_options_get(struct net *net, struct ip_options **optp,
540 unsigned char *data, int optlen)
539{ 541{
540 struct ip_options *opt = ip_options_get_alloc(optlen); 542 struct ip_options *opt = ip_options_get_alloc(optlen);
541 543
@@ -543,7 +545,7 @@ int ip_options_get(struct ip_options **optp, unsigned char *data, int optlen)
543 return -ENOMEM; 545 return -ENOMEM;
544 if (optlen) 546 if (optlen)
545 memcpy(opt->__data, data, optlen); 547 memcpy(opt->__data, data, optlen);
546 return ip_options_get_finish(optp, opt, optlen); 548 return ip_options_get_finish(net, optp, opt, optlen);
547} 549}
548 550
549void ip_forward_options(struct sk_buff *skb) 551void ip_forward_options(struct sk_buff *skb)
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index bb3cbe5ec36d..1b86a50269bc 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -176,7 +176,7 @@ int ip_cmsg_send(struct msghdr *msg, struct ipcm_cookie *ipc)
176 switch (cmsg->cmsg_type) { 176 switch (cmsg->cmsg_type) {
177 case IP_RETOPTS: 177 case IP_RETOPTS:
178 err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)); 178 err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr));
179 err = ip_options_get(&ipc->opt, CMSG_DATA(cmsg), err < 40 ? err : 40); 179 err = ip_options_get(&init_net, &ipc->opt, CMSG_DATA(cmsg), err < 40 ? err : 40);
180 if (err) 180 if (err)
181 return err; 181 return err;
182 break; 182 break;
@@ -449,7 +449,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
449 struct ip_options * opt = NULL; 449 struct ip_options * opt = NULL;
450 if (optlen > 40 || optlen < 0) 450 if (optlen > 40 || optlen < 0)
451 goto e_inval; 451 goto e_inval;
452 err = ip_options_get_from_user(&opt, optval, optlen); 452 err = ip_options_get_from_user(&init_net, &opt, optval, optlen);
453 if (err) 453 if (err)
454 break; 454 break;
455 if (inet->is_icsk) { 455 if (inet->is_icsk) {