Loading net/sctp/socket.c +81 −39 Original line number Original line Diff line number Diff line Loading @@ -3375,12 +3375,13 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, sctp_assoc_t associd; sctp_assoc_t associd; int retval = 0; int retval = 0; if (len != sizeof(status)) { if (len < sizeof(status)) { retval = -EINVAL; retval = -EINVAL; goto out; goto out; } } if (copy_from_user(&status, optval, sizeof(status))) { len = sizeof(status); if (copy_from_user(&status, optval, len)) { retval = -EFAULT; retval = -EFAULT; goto out; goto out; } } Loading Loading @@ -3452,12 +3453,13 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len, struct sctp_transport *transport; struct sctp_transport *transport; int retval = 0; int retval = 0; if (len != sizeof(pinfo)) { if (len < sizeof(pinfo)) { retval = -EINVAL; retval = -EINVAL; goto out; goto out; } } if (copy_from_user(&pinfo, optval, sizeof(pinfo))) { len = sizeof(pinfo); if (copy_from_user(&pinfo, optval, len)) { retval = -EFAULT; retval = -EFAULT; goto out; goto out; } } Loading Loading @@ -3523,8 +3525,11 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len, static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval, static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval, int __user *optlen) int __user *optlen) { { if (len != sizeof(struct sctp_event_subscribe)) if (len < sizeof(struct sctp_event_subscribe)) return -EINVAL; return -EINVAL; len = sizeof(struct sctp_event_subscribe); if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &sctp_sk(sk)->subscribe, len)) if (copy_to_user(optval, &sctp_sk(sk)->subscribe, len)) return -EFAULT; return -EFAULT; return 0; return 0; Loading @@ -3546,9 +3551,12 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv /* Applicable to UDP-style socket only */ /* Applicable to UDP-style socket only */ if (sctp_style(sk, TCP)) if (sctp_style(sk, TCP)) return -EOPNOTSUPP; return -EOPNOTSUPP; if (len != sizeof(int)) if (len < sizeof(int)) return -EINVAL; return -EINVAL; if (copy_to_user(optval, &sctp_sk(sk)->autoclose, len)) len = sizeof(int); if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &sctp_sk(sk)->autoclose, sizeof(int))) return -EFAULT; return -EFAULT; return 0; return 0; } } Loading Loading @@ -3599,8 +3607,9 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval int retval = 0; int retval = 0; struct sctp_association *asoc; struct sctp_association *asoc; if (len != sizeof(sctp_peeloff_arg_t)) if (len < sizeof(sctp_peeloff_arg_t)) return -EINVAL; return -EINVAL; len = sizeof(sctp_peeloff_arg_t); if (copy_from_user(&peeloff, optval, len)) if (copy_from_user(&peeloff, optval, len)) return -EFAULT; return -EFAULT; Loading Loading @@ -3628,6 +3637,8 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval /* Return the fd mapped to the new socket. */ /* Return the fd mapped to the new socket. */ peeloff.sd = retval; peeloff.sd = retval; if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &peeloff, len)) if (copy_to_user(optval, &peeloff, len)) retval = -EFAULT; retval = -EFAULT; Loading Loading @@ -3736,9 +3747,9 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, struct sctp_association *asoc = NULL; struct sctp_association *asoc = NULL; struct sctp_sock *sp = sctp_sk(sk); struct sctp_sock *sp = sctp_sk(sk); if (len != sizeof(struct sctp_paddrparams)) if (len < sizeof(struct sctp_paddrparams)) return -EINVAL; return -EINVAL; len = sizeof(struct sctp_paddrparams); if (copy_from_user(¶ms, optval, len)) if (copy_from_user(¶ms, optval, len)) return -EFAULT; return -EFAULT; Loading Loading @@ -3837,9 +3848,11 @@ static int sctp_getsockopt_delayed_ack_time(struct sock *sk, int len, struct sctp_association *asoc = NULL; struct sctp_association *asoc = NULL; struct sctp_sock *sp = sctp_sk(sk); struct sctp_sock *sp = sctp_sk(sk); if (len != sizeof(struct sctp_assoc_value)) if (len < sizeof(struct sctp_assoc_value)) return - EINVAL; return - EINVAL; len = sizeof(struct sctp_assoc_value); if (copy_from_user(¶ms, optval, len)) if (copy_from_user(¶ms, optval, len)) return -EFAULT; return -EFAULT; Loading Loading @@ -3888,8 +3901,11 @@ static int sctp_getsockopt_delayed_ack_time(struct sock *sk, int len, */ */ static int sctp_getsockopt_initmsg(struct sock *sk, int len, char __user *optval, int __user *optlen) static int sctp_getsockopt_initmsg(struct sock *sk, int len, char __user *optval, int __user *optlen) { { if (len != sizeof(struct sctp_initmsg)) if (len < sizeof(struct sctp_initmsg)) return -EINVAL; return -EINVAL; len = sizeof(struct sctp_initmsg); if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &sctp_sk(sk)->initmsg, len)) if (copy_to_user(optval, &sctp_sk(sk)->initmsg, len)) return -EFAULT; return -EFAULT; return 0; return 0; Loading @@ -3904,7 +3920,7 @@ static int sctp_getsockopt_peer_addrs_num_old(struct sock *sk, int len, struct list_head *pos; struct list_head *pos; int cnt = 0; int cnt = 0; if (len != sizeof(sctp_assoc_t)) if (len < sizeof(sctp_assoc_t)) return -EINVAL; return -EINVAL; if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) Loading Loading @@ -3940,10 +3956,12 @@ static int sctp_getsockopt_peer_addrs_old(struct sock *sk, int len, struct sctp_sock *sp = sctp_sk(sk); struct sctp_sock *sp = sctp_sk(sk); int addrlen; int addrlen; if (len != sizeof(struct sctp_getaddrs_old)) if (len < sizeof(struct sctp_getaddrs_old)) return -EINVAL; return -EINVAL; if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs_old))) len = sizeof(struct sctp_getaddrs_old); if (copy_from_user(&getaddrs, optval, len)) return -EFAULT; return -EFAULT; if (getaddrs.addr_num <= 0) return -EINVAL; if (getaddrs.addr_num <= 0) return -EINVAL; Loading @@ -3966,7 +3984,9 @@ static int sctp_getsockopt_peer_addrs_old(struct sock *sk, int len, if (cnt >= getaddrs.addr_num) break; if (cnt >= getaddrs.addr_num) break; } } getaddrs.addr_num = cnt; getaddrs.addr_num = cnt; if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs_old))) if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &getaddrs, len)) return -EFAULT; return -EFAULT; return 0; return 0; Loading Loading @@ -3999,8 +4019,7 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, return -EINVAL; return -EINVAL; to = optval + offsetof(struct sctp_getaddrs,addrs); to = optval + offsetof(struct sctp_getaddrs,addrs); space_left = len - sizeof(struct sctp_getaddrs) - space_left = len - offsetof(struct sctp_getaddrs,addrs); offsetof(struct sctp_getaddrs,addrs); list_for_each(pos, &asoc->peer.transport_addr_list) { list_for_each(pos, &asoc->peer.transport_addr_list) { from = list_entry(pos, struct sctp_transport, transports); from = list_entry(pos, struct sctp_transport, transports); Loading Loading @@ -4037,7 +4056,7 @@ static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len, rwlock_t *addr_lock; rwlock_t *addr_lock; int cnt = 0; int cnt = 0; if (len != sizeof(sctp_assoc_t)) if (len < sizeof(sctp_assoc_t)) return -EINVAL; return -EINVAL; if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) Loading Loading @@ -4179,10 +4198,11 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, void *buf; void *buf; int bytes_copied = 0; int bytes_copied = 0; if (len != sizeof(struct sctp_getaddrs_old)) if (len < sizeof(struct sctp_getaddrs_old)) return -EINVAL; return -EINVAL; if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs_old))) len = sizeof(struct sctp_getaddrs_old); if (copy_from_user(&getaddrs, optval, len)) return -EFAULT; return -EFAULT; if (getaddrs.addr_num <= 0) return -EINVAL; if (getaddrs.addr_num <= 0) return -EINVAL; Loading Loading @@ -4254,7 +4274,7 @@ copy_getaddrs: /* copy the leading structure back to user */ /* copy the leading structure back to user */ getaddrs.addr_num = cnt; getaddrs.addr_num = cnt; if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs_old))) if (copy_to_user(optval, &getaddrs, len)) err = -EFAULT; err = -EFAULT; error: error: Loading Loading @@ -4282,7 +4302,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, void *addrs; void *addrs; void *buf; void *buf; if (len <= sizeof(struct sctp_getaddrs)) if (len < sizeof(struct sctp_getaddrs)) return -EINVAL; return -EINVAL; if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs))) if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs))) Loading @@ -4306,8 +4326,8 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, } } to = optval + offsetof(struct sctp_getaddrs,addrs); to = optval + offsetof(struct sctp_getaddrs,addrs); space_left = len - sizeof(struct sctp_getaddrs) - space_left = len - offsetof(struct sctp_getaddrs,addrs); offsetof(struct sctp_getaddrs,addrs); addrs = kmalloc(space_left, GFP_KERNEL); addrs = kmalloc(space_left, GFP_KERNEL); if (!addrs) if (!addrs) return -ENOMEM; return -ENOMEM; Loading Loading @@ -4379,10 +4399,12 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len, struct sctp_association *asoc; struct sctp_association *asoc; struct sctp_sock *sp = sctp_sk(sk); struct sctp_sock *sp = sctp_sk(sk); if (len != sizeof(struct sctp_prim)) if (len < sizeof(struct sctp_prim)) return -EINVAL; return -EINVAL; if (copy_from_user(&prim, optval, sizeof(struct sctp_prim))) len = sizeof(struct sctp_prim); if (copy_from_user(&prim, optval, len)) return -EFAULT; return -EFAULT; asoc = sctp_id2assoc(sk, prim.ssp_assoc_id); asoc = sctp_id2assoc(sk, prim.ssp_assoc_id); Loading @@ -4398,7 +4420,9 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len, sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, (union sctp_addr *)&prim.ssp_addr); (union sctp_addr *)&prim.ssp_addr); if (copy_to_user(optval, &prim, sizeof(struct sctp_prim))) if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &prim, len)) return -EFAULT; return -EFAULT; return 0; return 0; Loading @@ -4415,10 +4439,15 @@ static int sctp_getsockopt_adaptation_layer(struct sock *sk, int len, { { struct sctp_setadaptation adaptation; struct sctp_setadaptation adaptation; if (len != sizeof(struct sctp_setadaptation)) if (len < sizeof(struct sctp_setadaptation)) return -EINVAL; return -EINVAL; len = sizeof(struct sctp_setadaptation); adaptation.ssb_adaptation_ind = sctp_sk(sk)->adaptation_ind; adaptation.ssb_adaptation_ind = sctp_sk(sk)->adaptation_ind; if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &adaptation, len)) if (copy_to_user(optval, &adaptation, len)) return -EFAULT; return -EFAULT; Loading Loading @@ -4452,9 +4481,12 @@ static int sctp_getsockopt_default_send_param(struct sock *sk, struct sctp_association *asoc; struct sctp_association *asoc; struct sctp_sock *sp = sctp_sk(sk); struct sctp_sock *sp = sctp_sk(sk); if (len != sizeof(struct sctp_sndrcvinfo)) if (len < sizeof(struct sctp_sndrcvinfo)) return -EINVAL; return -EINVAL; if (copy_from_user(&info, optval, sizeof(struct sctp_sndrcvinfo))) len = sizeof(struct sctp_sndrcvinfo); if (copy_from_user(&info, optval, len)) return -EFAULT; return -EFAULT; asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); Loading @@ -4475,7 +4507,9 @@ static int sctp_getsockopt_default_send_param(struct sock *sk, info.sinfo_timetolive = sp->default_timetolive; info.sinfo_timetolive = sp->default_timetolive; } } if (copy_to_user(optval, &info, sizeof(struct sctp_sndrcvinfo))) if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &info, len)) return -EFAULT; return -EFAULT; return 0; return 0; Loading Loading @@ -4526,10 +4560,12 @@ static int sctp_getsockopt_rtoinfo(struct sock *sk, int len, struct sctp_rtoinfo rtoinfo; struct sctp_rtoinfo rtoinfo; struct sctp_association *asoc; struct sctp_association *asoc; if (len != sizeof (struct sctp_rtoinfo)) if (len < sizeof (struct sctp_rtoinfo)) return -EINVAL; return -EINVAL; if (copy_from_user(&rtoinfo, optval, sizeof (struct sctp_rtoinfo))) len = sizeof(struct sctp_rtoinfo); if (copy_from_user(&rtoinfo, optval, len)) return -EFAULT; return -EFAULT; asoc = sctp_id2assoc(sk, rtoinfo.srto_assoc_id); asoc = sctp_id2assoc(sk, rtoinfo.srto_assoc_id); Loading Loading @@ -4581,11 +4617,12 @@ static int sctp_getsockopt_associnfo(struct sock *sk, int len, struct list_head *pos; struct list_head *pos; int cnt = 0; int cnt = 0; if (len != sizeof (struct sctp_assocparams)) if (len < sizeof (struct sctp_assocparams)) return -EINVAL; return -EINVAL; if (copy_from_user(&assocparams, optval, len = sizeof(struct sctp_assocparams); sizeof (struct sctp_assocparams))) if (copy_from_user(&assocparams, optval, len)) return -EFAULT; return -EFAULT; asoc = sctp_id2assoc(sk, assocparams.sasoc_assoc_id); asoc = sctp_id2assoc(sk, assocparams.sasoc_assoc_id); Loading Loading @@ -4671,9 +4708,11 @@ static int sctp_getsockopt_context(struct sock *sk, int len, struct sctp_sock *sp; struct sctp_sock *sp; struct sctp_association *asoc; struct sctp_association *asoc; if (len != sizeof(struct sctp_assoc_value)) if (len < sizeof(struct sctp_assoc_value)) return -EINVAL; return -EINVAL; len = sizeof(struct sctp_assoc_value); if (copy_from_user(¶ms, optval, len)) if (copy_from_user(¶ms, optval, len)) return -EFAULT; return -EFAULT; Loading Loading @@ -6084,8 +6123,11 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, * queued to the backlog. This prevents a potential race between * queued to the backlog. This prevents a potential race between * backlog processing on the old socket and new-packet processing * backlog processing on the old socket and new-packet processing * on the new socket. * on the new socket. * * The caller has just allocated newsk so we can guarantee that other * paths won't try to lock it and then oldsk. */ */ sctp_lock_sock(newsk); lock_sock_nested(newsk, SINGLE_DEPTH_NESTING); sctp_assoc_migrate(assoc, newsk); sctp_assoc_migrate(assoc, newsk); /* If the association on the newsk is already closed before accept() /* If the association on the newsk is already closed before accept() Loading Loading
net/sctp/socket.c +81 −39 Original line number Original line Diff line number Diff line Loading @@ -3375,12 +3375,13 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, sctp_assoc_t associd; sctp_assoc_t associd; int retval = 0; int retval = 0; if (len != sizeof(status)) { if (len < sizeof(status)) { retval = -EINVAL; retval = -EINVAL; goto out; goto out; } } if (copy_from_user(&status, optval, sizeof(status))) { len = sizeof(status); if (copy_from_user(&status, optval, len)) { retval = -EFAULT; retval = -EFAULT; goto out; goto out; } } Loading Loading @@ -3452,12 +3453,13 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len, struct sctp_transport *transport; struct sctp_transport *transport; int retval = 0; int retval = 0; if (len != sizeof(pinfo)) { if (len < sizeof(pinfo)) { retval = -EINVAL; retval = -EINVAL; goto out; goto out; } } if (copy_from_user(&pinfo, optval, sizeof(pinfo))) { len = sizeof(pinfo); if (copy_from_user(&pinfo, optval, len)) { retval = -EFAULT; retval = -EFAULT; goto out; goto out; } } Loading Loading @@ -3523,8 +3525,11 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len, static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval, static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval, int __user *optlen) int __user *optlen) { { if (len != sizeof(struct sctp_event_subscribe)) if (len < sizeof(struct sctp_event_subscribe)) return -EINVAL; return -EINVAL; len = sizeof(struct sctp_event_subscribe); if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &sctp_sk(sk)->subscribe, len)) if (copy_to_user(optval, &sctp_sk(sk)->subscribe, len)) return -EFAULT; return -EFAULT; return 0; return 0; Loading @@ -3546,9 +3551,12 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv /* Applicable to UDP-style socket only */ /* Applicable to UDP-style socket only */ if (sctp_style(sk, TCP)) if (sctp_style(sk, TCP)) return -EOPNOTSUPP; return -EOPNOTSUPP; if (len != sizeof(int)) if (len < sizeof(int)) return -EINVAL; return -EINVAL; if (copy_to_user(optval, &sctp_sk(sk)->autoclose, len)) len = sizeof(int); if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &sctp_sk(sk)->autoclose, sizeof(int))) return -EFAULT; return -EFAULT; return 0; return 0; } } Loading Loading @@ -3599,8 +3607,9 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval int retval = 0; int retval = 0; struct sctp_association *asoc; struct sctp_association *asoc; if (len != sizeof(sctp_peeloff_arg_t)) if (len < sizeof(sctp_peeloff_arg_t)) return -EINVAL; return -EINVAL; len = sizeof(sctp_peeloff_arg_t); if (copy_from_user(&peeloff, optval, len)) if (copy_from_user(&peeloff, optval, len)) return -EFAULT; return -EFAULT; Loading Loading @@ -3628,6 +3637,8 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval /* Return the fd mapped to the new socket. */ /* Return the fd mapped to the new socket. */ peeloff.sd = retval; peeloff.sd = retval; if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &peeloff, len)) if (copy_to_user(optval, &peeloff, len)) retval = -EFAULT; retval = -EFAULT; Loading Loading @@ -3736,9 +3747,9 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, struct sctp_association *asoc = NULL; struct sctp_association *asoc = NULL; struct sctp_sock *sp = sctp_sk(sk); struct sctp_sock *sp = sctp_sk(sk); if (len != sizeof(struct sctp_paddrparams)) if (len < sizeof(struct sctp_paddrparams)) return -EINVAL; return -EINVAL; len = sizeof(struct sctp_paddrparams); if (copy_from_user(¶ms, optval, len)) if (copy_from_user(¶ms, optval, len)) return -EFAULT; return -EFAULT; Loading Loading @@ -3837,9 +3848,11 @@ static int sctp_getsockopt_delayed_ack_time(struct sock *sk, int len, struct sctp_association *asoc = NULL; struct sctp_association *asoc = NULL; struct sctp_sock *sp = sctp_sk(sk); struct sctp_sock *sp = sctp_sk(sk); if (len != sizeof(struct sctp_assoc_value)) if (len < sizeof(struct sctp_assoc_value)) return - EINVAL; return - EINVAL; len = sizeof(struct sctp_assoc_value); if (copy_from_user(¶ms, optval, len)) if (copy_from_user(¶ms, optval, len)) return -EFAULT; return -EFAULT; Loading Loading @@ -3888,8 +3901,11 @@ static int sctp_getsockopt_delayed_ack_time(struct sock *sk, int len, */ */ static int sctp_getsockopt_initmsg(struct sock *sk, int len, char __user *optval, int __user *optlen) static int sctp_getsockopt_initmsg(struct sock *sk, int len, char __user *optval, int __user *optlen) { { if (len != sizeof(struct sctp_initmsg)) if (len < sizeof(struct sctp_initmsg)) return -EINVAL; return -EINVAL; len = sizeof(struct sctp_initmsg); if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &sctp_sk(sk)->initmsg, len)) if (copy_to_user(optval, &sctp_sk(sk)->initmsg, len)) return -EFAULT; return -EFAULT; return 0; return 0; Loading @@ -3904,7 +3920,7 @@ static int sctp_getsockopt_peer_addrs_num_old(struct sock *sk, int len, struct list_head *pos; struct list_head *pos; int cnt = 0; int cnt = 0; if (len != sizeof(sctp_assoc_t)) if (len < sizeof(sctp_assoc_t)) return -EINVAL; return -EINVAL; if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) Loading Loading @@ -3940,10 +3956,12 @@ static int sctp_getsockopt_peer_addrs_old(struct sock *sk, int len, struct sctp_sock *sp = sctp_sk(sk); struct sctp_sock *sp = sctp_sk(sk); int addrlen; int addrlen; if (len != sizeof(struct sctp_getaddrs_old)) if (len < sizeof(struct sctp_getaddrs_old)) return -EINVAL; return -EINVAL; if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs_old))) len = sizeof(struct sctp_getaddrs_old); if (copy_from_user(&getaddrs, optval, len)) return -EFAULT; return -EFAULT; if (getaddrs.addr_num <= 0) return -EINVAL; if (getaddrs.addr_num <= 0) return -EINVAL; Loading @@ -3966,7 +3984,9 @@ static int sctp_getsockopt_peer_addrs_old(struct sock *sk, int len, if (cnt >= getaddrs.addr_num) break; if (cnt >= getaddrs.addr_num) break; } } getaddrs.addr_num = cnt; getaddrs.addr_num = cnt; if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs_old))) if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &getaddrs, len)) return -EFAULT; return -EFAULT; return 0; return 0; Loading Loading @@ -3999,8 +4019,7 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, return -EINVAL; return -EINVAL; to = optval + offsetof(struct sctp_getaddrs,addrs); to = optval + offsetof(struct sctp_getaddrs,addrs); space_left = len - sizeof(struct sctp_getaddrs) - space_left = len - offsetof(struct sctp_getaddrs,addrs); offsetof(struct sctp_getaddrs,addrs); list_for_each(pos, &asoc->peer.transport_addr_list) { list_for_each(pos, &asoc->peer.transport_addr_list) { from = list_entry(pos, struct sctp_transport, transports); from = list_entry(pos, struct sctp_transport, transports); Loading Loading @@ -4037,7 +4056,7 @@ static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len, rwlock_t *addr_lock; rwlock_t *addr_lock; int cnt = 0; int cnt = 0; if (len != sizeof(sctp_assoc_t)) if (len < sizeof(sctp_assoc_t)) return -EINVAL; return -EINVAL; if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) Loading Loading @@ -4179,10 +4198,11 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, void *buf; void *buf; int bytes_copied = 0; int bytes_copied = 0; if (len != sizeof(struct sctp_getaddrs_old)) if (len < sizeof(struct sctp_getaddrs_old)) return -EINVAL; return -EINVAL; if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs_old))) len = sizeof(struct sctp_getaddrs_old); if (copy_from_user(&getaddrs, optval, len)) return -EFAULT; return -EFAULT; if (getaddrs.addr_num <= 0) return -EINVAL; if (getaddrs.addr_num <= 0) return -EINVAL; Loading Loading @@ -4254,7 +4274,7 @@ copy_getaddrs: /* copy the leading structure back to user */ /* copy the leading structure back to user */ getaddrs.addr_num = cnt; getaddrs.addr_num = cnt; if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs_old))) if (copy_to_user(optval, &getaddrs, len)) err = -EFAULT; err = -EFAULT; error: error: Loading Loading @@ -4282,7 +4302,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, void *addrs; void *addrs; void *buf; void *buf; if (len <= sizeof(struct sctp_getaddrs)) if (len < sizeof(struct sctp_getaddrs)) return -EINVAL; return -EINVAL; if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs))) if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs))) Loading @@ -4306,8 +4326,8 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, } } to = optval + offsetof(struct sctp_getaddrs,addrs); to = optval + offsetof(struct sctp_getaddrs,addrs); space_left = len - sizeof(struct sctp_getaddrs) - space_left = len - offsetof(struct sctp_getaddrs,addrs); offsetof(struct sctp_getaddrs,addrs); addrs = kmalloc(space_left, GFP_KERNEL); addrs = kmalloc(space_left, GFP_KERNEL); if (!addrs) if (!addrs) return -ENOMEM; return -ENOMEM; Loading Loading @@ -4379,10 +4399,12 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len, struct sctp_association *asoc; struct sctp_association *asoc; struct sctp_sock *sp = sctp_sk(sk); struct sctp_sock *sp = sctp_sk(sk); if (len != sizeof(struct sctp_prim)) if (len < sizeof(struct sctp_prim)) return -EINVAL; return -EINVAL; if (copy_from_user(&prim, optval, sizeof(struct sctp_prim))) len = sizeof(struct sctp_prim); if (copy_from_user(&prim, optval, len)) return -EFAULT; return -EFAULT; asoc = sctp_id2assoc(sk, prim.ssp_assoc_id); asoc = sctp_id2assoc(sk, prim.ssp_assoc_id); Loading @@ -4398,7 +4420,9 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len, sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, (union sctp_addr *)&prim.ssp_addr); (union sctp_addr *)&prim.ssp_addr); if (copy_to_user(optval, &prim, sizeof(struct sctp_prim))) if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &prim, len)) return -EFAULT; return -EFAULT; return 0; return 0; Loading @@ -4415,10 +4439,15 @@ static int sctp_getsockopt_adaptation_layer(struct sock *sk, int len, { { struct sctp_setadaptation adaptation; struct sctp_setadaptation adaptation; if (len != sizeof(struct sctp_setadaptation)) if (len < sizeof(struct sctp_setadaptation)) return -EINVAL; return -EINVAL; len = sizeof(struct sctp_setadaptation); adaptation.ssb_adaptation_ind = sctp_sk(sk)->adaptation_ind; adaptation.ssb_adaptation_ind = sctp_sk(sk)->adaptation_ind; if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &adaptation, len)) if (copy_to_user(optval, &adaptation, len)) return -EFAULT; return -EFAULT; Loading Loading @@ -4452,9 +4481,12 @@ static int sctp_getsockopt_default_send_param(struct sock *sk, struct sctp_association *asoc; struct sctp_association *asoc; struct sctp_sock *sp = sctp_sk(sk); struct sctp_sock *sp = sctp_sk(sk); if (len != sizeof(struct sctp_sndrcvinfo)) if (len < sizeof(struct sctp_sndrcvinfo)) return -EINVAL; return -EINVAL; if (copy_from_user(&info, optval, sizeof(struct sctp_sndrcvinfo))) len = sizeof(struct sctp_sndrcvinfo); if (copy_from_user(&info, optval, len)) return -EFAULT; return -EFAULT; asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); Loading @@ -4475,7 +4507,9 @@ static int sctp_getsockopt_default_send_param(struct sock *sk, info.sinfo_timetolive = sp->default_timetolive; info.sinfo_timetolive = sp->default_timetolive; } } if (copy_to_user(optval, &info, sizeof(struct sctp_sndrcvinfo))) if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &info, len)) return -EFAULT; return -EFAULT; return 0; return 0; Loading Loading @@ -4526,10 +4560,12 @@ static int sctp_getsockopt_rtoinfo(struct sock *sk, int len, struct sctp_rtoinfo rtoinfo; struct sctp_rtoinfo rtoinfo; struct sctp_association *asoc; struct sctp_association *asoc; if (len != sizeof (struct sctp_rtoinfo)) if (len < sizeof (struct sctp_rtoinfo)) return -EINVAL; return -EINVAL; if (copy_from_user(&rtoinfo, optval, sizeof (struct sctp_rtoinfo))) len = sizeof(struct sctp_rtoinfo); if (copy_from_user(&rtoinfo, optval, len)) return -EFAULT; return -EFAULT; asoc = sctp_id2assoc(sk, rtoinfo.srto_assoc_id); asoc = sctp_id2assoc(sk, rtoinfo.srto_assoc_id); Loading Loading @@ -4581,11 +4617,12 @@ static int sctp_getsockopt_associnfo(struct sock *sk, int len, struct list_head *pos; struct list_head *pos; int cnt = 0; int cnt = 0; if (len != sizeof (struct sctp_assocparams)) if (len < sizeof (struct sctp_assocparams)) return -EINVAL; return -EINVAL; if (copy_from_user(&assocparams, optval, len = sizeof(struct sctp_assocparams); sizeof (struct sctp_assocparams))) if (copy_from_user(&assocparams, optval, len)) return -EFAULT; return -EFAULT; asoc = sctp_id2assoc(sk, assocparams.sasoc_assoc_id); asoc = sctp_id2assoc(sk, assocparams.sasoc_assoc_id); Loading Loading @@ -4671,9 +4708,11 @@ static int sctp_getsockopt_context(struct sock *sk, int len, struct sctp_sock *sp; struct sctp_sock *sp; struct sctp_association *asoc; struct sctp_association *asoc; if (len != sizeof(struct sctp_assoc_value)) if (len < sizeof(struct sctp_assoc_value)) return -EINVAL; return -EINVAL; len = sizeof(struct sctp_assoc_value); if (copy_from_user(¶ms, optval, len)) if (copy_from_user(¶ms, optval, len)) return -EFAULT; return -EFAULT; Loading Loading @@ -6084,8 +6123,11 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, * queued to the backlog. This prevents a potential race between * queued to the backlog. This prevents a potential race between * backlog processing on the old socket and new-packet processing * backlog processing on the old socket and new-packet processing * on the new socket. * on the new socket. * * The caller has just allocated newsk so we can guarantee that other * paths won't try to lock it and then oldsk. */ */ sctp_lock_sock(newsk); lock_sock_nested(newsk, SINGLE_DEPTH_NESTING); sctp_assoc_migrate(assoc, newsk); sctp_assoc_migrate(assoc, newsk); /* If the association on the newsk is already closed before accept() /* If the association on the newsk is already closed before accept() Loading