diff options
author | Arnaldo Carvalho de Melo <acme@mandriva.com> | 2005-10-28 21:35:02 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@mandriva.com> | 2005-10-28 21:35:02 -0400 |
commit | 974f7bc5781d3fc16e32d8908c6e48592e767dd2 (patch) | |
tree | ad36a9c4d93a138fbcd02c1df9fa3a3a321e0cc2 /net/sctp/socket.c | |
parent | 89fbb69c4f285019ba5e029963dc11cc6beb078a (diff) | |
parent | 64a0c1c81e300f0f56f26604c81040784e3717f0 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/sridhar/lksctp-2.6
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 90 |
1 files changed, 56 insertions, 34 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 02e068d3450d..b529af5e6f2a 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -1010,6 +1010,19 @@ static int __sctp_connect(struct sock* sk, | |||
1010 | err = -EAGAIN; | 1010 | err = -EAGAIN; |
1011 | goto out_free; | 1011 | goto out_free; |
1012 | } | 1012 | } |
1013 | } else { | ||
1014 | /* | ||
1015 | * If an unprivileged user inherits a 1-many | ||
1016 | * style socket with open associations on a | ||
1017 | * privileged port, it MAY be permitted to | ||
1018 | * accept new associations, but it SHOULD NOT | ||
1019 | * be permitted to open new associations. | ||
1020 | */ | ||
1021 | if (ep->base.bind_addr.port < PROT_SOCK && | ||
1022 | !capable(CAP_NET_BIND_SERVICE)) { | ||
1023 | err = -EACCES; | ||
1024 | goto out_free; | ||
1025 | } | ||
1013 | } | 1026 | } |
1014 | 1027 | ||
1015 | scope = sctp_scope(&to); | 1028 | scope = sctp_scope(&to); |
@@ -1389,27 +1402,27 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1389 | SCTP_DEBUG_PRINTK("msg_len: %zu, sinfo_flags: 0x%x\n", | 1402 | SCTP_DEBUG_PRINTK("msg_len: %zu, sinfo_flags: 0x%x\n", |
1390 | msg_len, sinfo_flags); | 1403 | msg_len, sinfo_flags); |
1391 | 1404 | ||
1392 | /* MSG_EOF or MSG_ABORT cannot be set on a TCP-style socket. */ | 1405 | /* SCTP_EOF or SCTP_ABORT cannot be set on a TCP-style socket. */ |
1393 | if (sctp_style(sk, TCP) && (sinfo_flags & (MSG_EOF | MSG_ABORT))) { | 1406 | if (sctp_style(sk, TCP) && (sinfo_flags & (SCTP_EOF | SCTP_ABORT))) { |
1394 | err = -EINVAL; | 1407 | err = -EINVAL; |
1395 | goto out_nounlock; | 1408 | goto out_nounlock; |
1396 | } | 1409 | } |
1397 | 1410 | ||
1398 | /* If MSG_EOF is set, no data can be sent. Disallow sending zero | 1411 | /* If SCTP_EOF is set, no data can be sent. Disallow sending zero |
1399 | * length messages when MSG_EOF|MSG_ABORT is not set. | 1412 | * length messages when SCTP_EOF|SCTP_ABORT is not set. |
1400 | * If MSG_ABORT is set, the message length could be non zero with | 1413 | * If SCTP_ABORT is set, the message length could be non zero with |
1401 | * the msg_iov set to the user abort reason. | 1414 | * the msg_iov set to the user abort reason. |
1402 | */ | 1415 | */ |
1403 | if (((sinfo_flags & MSG_EOF) && (msg_len > 0)) || | 1416 | if (((sinfo_flags & SCTP_EOF) && (msg_len > 0)) || |
1404 | (!(sinfo_flags & (MSG_EOF|MSG_ABORT)) && (msg_len == 0))) { | 1417 | (!(sinfo_flags & (SCTP_EOF|SCTP_ABORT)) && (msg_len == 0))) { |
1405 | err = -EINVAL; | 1418 | err = -EINVAL; |
1406 | goto out_nounlock; | 1419 | goto out_nounlock; |
1407 | } | 1420 | } |
1408 | 1421 | ||
1409 | /* If MSG_ADDR_OVER is set, there must be an address | 1422 | /* If SCTP_ADDR_OVER is set, there must be an address |
1410 | * specified in msg_name. | 1423 | * specified in msg_name. |
1411 | */ | 1424 | */ |
1412 | if ((sinfo_flags & MSG_ADDR_OVER) && (!msg->msg_name)) { | 1425 | if ((sinfo_flags & SCTP_ADDR_OVER) && (!msg->msg_name)) { |
1413 | err = -EINVAL; | 1426 | err = -EINVAL; |
1414 | goto out_nounlock; | 1427 | goto out_nounlock; |
1415 | } | 1428 | } |
@@ -1458,14 +1471,14 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1458 | goto out_unlock; | 1471 | goto out_unlock; |
1459 | } | 1472 | } |
1460 | 1473 | ||
1461 | if (sinfo_flags & MSG_EOF) { | 1474 | if (sinfo_flags & SCTP_EOF) { |
1462 | SCTP_DEBUG_PRINTK("Shutting down association: %p\n", | 1475 | SCTP_DEBUG_PRINTK("Shutting down association: %p\n", |
1463 | asoc); | 1476 | asoc); |
1464 | sctp_primitive_SHUTDOWN(asoc, NULL); | 1477 | sctp_primitive_SHUTDOWN(asoc, NULL); |
1465 | err = 0; | 1478 | err = 0; |
1466 | goto out_unlock; | 1479 | goto out_unlock; |
1467 | } | 1480 | } |
1468 | if (sinfo_flags & MSG_ABORT) { | 1481 | if (sinfo_flags & SCTP_ABORT) { |
1469 | SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc); | 1482 | SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc); |
1470 | sctp_primitive_ABORT(asoc, msg); | 1483 | sctp_primitive_ABORT(asoc, msg); |
1471 | err = 0; | 1484 | err = 0; |
@@ -1477,7 +1490,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1477 | if (!asoc) { | 1490 | if (!asoc) { |
1478 | SCTP_DEBUG_PRINTK("There is no association yet.\n"); | 1491 | SCTP_DEBUG_PRINTK("There is no association yet.\n"); |
1479 | 1492 | ||
1480 | if (sinfo_flags & (MSG_EOF | MSG_ABORT)) { | 1493 | if (sinfo_flags & (SCTP_EOF | SCTP_ABORT)) { |
1481 | err = -EINVAL; | 1494 | err = -EINVAL; |
1482 | goto out_unlock; | 1495 | goto out_unlock; |
1483 | } | 1496 | } |
@@ -1515,6 +1528,19 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1515 | err = -EAGAIN; | 1528 | err = -EAGAIN; |
1516 | goto out_unlock; | 1529 | goto out_unlock; |
1517 | } | 1530 | } |
1531 | } else { | ||
1532 | /* | ||
1533 | * If an unprivileged user inherits a one-to-many | ||
1534 | * style socket with open associations on a privileged | ||
1535 | * port, it MAY be permitted to accept new associations, | ||
1536 | * but it SHOULD NOT be permitted to open new | ||
1537 | * associations. | ||
1538 | */ | ||
1539 | if (ep->base.bind_addr.port < PROT_SOCK && | ||
1540 | !capable(CAP_NET_BIND_SERVICE)) { | ||
1541 | err = -EACCES; | ||
1542 | goto out_unlock; | ||
1543 | } | ||
1518 | } | 1544 | } |
1519 | 1545 | ||
1520 | scope = sctp_scope(&to); | 1546 | scope = sctp_scope(&to); |
@@ -1611,10 +1637,10 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1611 | 1637 | ||
1612 | /* If an address is passed with the sendto/sendmsg call, it is used | 1638 | /* If an address is passed with the sendto/sendmsg call, it is used |
1613 | * to override the primary destination address in the TCP model, or | 1639 | * to override the primary destination address in the TCP model, or |
1614 | * when MSG_ADDR_OVER flag is set in the UDP model. | 1640 | * when SCTP_ADDR_OVER flag is set in the UDP model. |
1615 | */ | 1641 | */ |
1616 | if ((sctp_style(sk, TCP) && msg_name) || | 1642 | if ((sctp_style(sk, TCP) && msg_name) || |
1617 | (sinfo_flags & MSG_ADDR_OVER)) { | 1643 | (sinfo_flags & SCTP_ADDR_OVER)) { |
1618 | chunk_tp = sctp_assoc_lookup_paddr(asoc, &to); | 1644 | chunk_tp = sctp_assoc_lookup_paddr(asoc, &to); |
1619 | if (!chunk_tp) { | 1645 | if (!chunk_tp) { |
1620 | err = -EINVAL; | 1646 | err = -EINVAL; |
@@ -2306,16 +2332,14 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optl | |||
2306 | return -EINVAL; | 2332 | return -EINVAL; |
2307 | if (get_user(val, (int __user *)optval)) | 2333 | if (get_user(val, (int __user *)optval)) |
2308 | return -EFAULT; | 2334 | return -EFAULT; |
2309 | if ((val < 8) || (val > SCTP_MAX_CHUNK_LEN)) | 2335 | if ((val != 0) && ((val < 8) || (val > SCTP_MAX_CHUNK_LEN))) |
2310 | return -EINVAL; | 2336 | return -EINVAL; |
2311 | sp->user_frag = val; | 2337 | sp->user_frag = val; |
2312 | 2338 | ||
2313 | if (val) { | 2339 | /* Update the frag_point of the existing associations. */ |
2314 | /* Update the frag_point of the existing associations. */ | 2340 | list_for_each(pos, &(sp->ep->asocs)) { |
2315 | list_for_each(pos, &(sp->ep->asocs)) { | 2341 | asoc = list_entry(pos, struct sctp_association, asocs); |
2316 | asoc = list_entry(pos, struct sctp_association, asocs); | 2342 | asoc->frag_point = sctp_frag_point(sp, asoc->pmtu); |
2317 | asoc->frag_point = sctp_frag_point(sp, asoc->pmtu); | ||
2318 | } | ||
2319 | } | 2343 | } |
2320 | 2344 | ||
2321 | return 0; | 2345 | return 0; |
@@ -2384,14 +2408,14 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva | |||
2384 | static int sctp_setsockopt_adaption_layer(struct sock *sk, char __user *optval, | 2408 | static int sctp_setsockopt_adaption_layer(struct sock *sk, char __user *optval, |
2385 | int optlen) | 2409 | int optlen) |
2386 | { | 2410 | { |
2387 | __u32 val; | 2411 | struct sctp_setadaption adaption; |
2388 | 2412 | ||
2389 | if (optlen < sizeof(__u32)) | 2413 | if (optlen != sizeof(struct sctp_setadaption)) |
2390 | return -EINVAL; | 2414 | return -EINVAL; |
2391 | if (copy_from_user(&val, optval, sizeof(__u32))) | 2415 | if (copy_from_user(&adaption, optval, optlen)) |
2392 | return -EFAULT; | 2416 | return -EFAULT; |
2393 | 2417 | ||
2394 | sctp_sk(sk)->adaption_ind = val; | 2418 | sctp_sk(sk)->adaption_ind = adaption.ssb_adaption_ind; |
2395 | 2419 | ||
2396 | return 0; | 2420 | return 0; |
2397 | } | 2421 | } |
@@ -3672,17 +3696,15 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len, | |||
3672 | static int sctp_getsockopt_adaption_layer(struct sock *sk, int len, | 3696 | static int sctp_getsockopt_adaption_layer(struct sock *sk, int len, |
3673 | char __user *optval, int __user *optlen) | 3697 | char __user *optval, int __user *optlen) |
3674 | { | 3698 | { |
3675 | __u32 val; | 3699 | struct sctp_setadaption adaption; |
3676 | 3700 | ||
3677 | if (len < sizeof(__u32)) | 3701 | if (len != sizeof(struct sctp_setadaption)) |
3678 | return -EINVAL; | 3702 | return -EINVAL; |
3679 | 3703 | ||
3680 | len = sizeof(__u32); | 3704 | adaption.ssb_adaption_ind = sctp_sk(sk)->adaption_ind; |
3681 | val = sctp_sk(sk)->adaption_ind; | 3705 | if (copy_to_user(optval, &adaption, len)) |
3682 | if (put_user(len, optlen)) | ||
3683 | return -EFAULT; | ||
3684 | if (copy_to_user(optval, &val, len)) | ||
3685 | return -EFAULT; | 3706 | return -EFAULT; |
3707 | |||
3686 | return 0; | 3708 | return 0; |
3687 | } | 3709 | } |
3688 | 3710 | ||
@@ -4640,8 +4662,8 @@ SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *msg, | |||
4640 | 4662 | ||
4641 | /* Minimally, validate the sinfo_flags. */ | 4663 | /* Minimally, validate the sinfo_flags. */ |
4642 | if (cmsgs->info->sinfo_flags & | 4664 | if (cmsgs->info->sinfo_flags & |
4643 | ~(MSG_UNORDERED | MSG_ADDR_OVER | | 4665 | ~(SCTP_UNORDERED | SCTP_ADDR_OVER | |
4644 | MSG_ABORT | MSG_EOF)) | 4666 | SCTP_ABORT | SCTP_EOF)) |
4645 | return -EINVAL; | 4667 | return -EINVAL; |
4646 | break; | 4668 | break; |
4647 | 4669 | ||