aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@mandriva.com>2005-10-28 21:35:02 -0400
committerArnaldo Carvalho de Melo <acme@mandriva.com>2005-10-28 21:35:02 -0400
commit974f7bc5781d3fc16e32d8908c6e48592e767dd2 (patch)
treead36a9c4d93a138fbcd02c1df9fa3a3a321e0cc2 /net/sctp
parent89fbb69c4f285019ba5e029963dc11cc6beb078a (diff)
parent64a0c1c81e300f0f56f26604c81040784e3717f0 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/sridhar/lksctp-2.6
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/sm_make_chunk.c2
-rw-r--r--net/sctp/socket.c90
-rw-r--r--net/sctp/ulpevent.c6
3 files changed, 60 insertions, 38 deletions
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 10e82ec2ebd3..660c61bdf164 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -554,7 +554,7 @@ struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc,
554 dp.ppid = sinfo->sinfo_ppid; 554 dp.ppid = sinfo->sinfo_ppid;
555 555
556 /* Set the flags for an unordered send. */ 556 /* Set the flags for an unordered send. */
557 if (sinfo->sinfo_flags & MSG_UNORDERED) { 557 if (sinfo->sinfo_flags & SCTP_UNORDERED) {
558 flags |= SCTP_DATA_UNORDERED; 558 flags |= SCTP_DATA_UNORDERED;
559 dp.ssn = 0; 559 dp.ssn = 0;
560 } else 560 } else
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
2384static int sctp_setsockopt_adaption_layer(struct sock *sk, char __user *optval, 2408static 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,
3672static int sctp_getsockopt_adaption_layer(struct sock *sk, int len, 3696static 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
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index 057e7fac3af0..e049f41faa47 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -698,7 +698,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
698 event->ssn = ntohs(chunk->subh.data_hdr->ssn); 698 event->ssn = ntohs(chunk->subh.data_hdr->ssn);
699 event->ppid = chunk->subh.data_hdr->ppid; 699 event->ppid = chunk->subh.data_hdr->ppid;
700 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) { 700 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) {
701 event->flags |= MSG_UNORDERED; 701 event->flags |= SCTP_UNORDERED;
702 event->cumtsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map); 702 event->cumtsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
703 } 703 }
704 event->tsn = ntohl(chunk->subh.data_hdr->tsn); 704 event->tsn = ntohl(chunk->subh.data_hdr->tsn);
@@ -824,7 +824,7 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
824 * 824 *
825 * recvmsg() flags: 825 * recvmsg() flags:
826 * 826 *
827 * MSG_UNORDERED - This flag is present when the message was sent 827 * SCTP_UNORDERED - This flag is present when the message was sent
828 * non-ordered. 828 * non-ordered.
829 */ 829 */
830 sinfo.sinfo_flags = event->flags; 830 sinfo.sinfo_flags = event->flags;
@@ -839,7 +839,7 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
839 * This field will hold the current cumulative TSN as 839 * This field will hold the current cumulative TSN as
840 * known by the underlying SCTP layer. Note this field is 840 * known by the underlying SCTP layer. Note this field is
841 * ignored when sending and only valid for a receive 841 * ignored when sending and only valid for a receive
842 * operation when sinfo_flags are set to MSG_UNORDERED. 842 * operation when sinfo_flags are set to SCTP_UNORDERED.
843 */ 843 */
844 sinfo.sinfo_cumtsn = event->cumtsn; 844 sinfo.sinfo_cumtsn = event->cumtsn;
845 /* sinfo_assoc_id: sizeof (sctp_assoc_t) 845 /* sinfo_assoc_id: sizeof (sctp_assoc_t)