Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions drivers/scsi/qla2xxx/qla_isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -3282,6 +3282,18 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) {
/* Sense data lies beyond any FCP RESPONSE data. */
if (IS_FWI2_CAPABLE(ha)) {
/*
* A hostile or buggy target may report an
* rsp_info_len larger than the IOCB data area.
* Clamp it so the par_sense_len subtraction cannot
* underflow and walk sense_data out of bounds.
*/
if (rsp_info_len > par_sense_len) {
ql_log(ql_log_warn, fcport->vha, 0x3107,
"Truncating bogus rsp_info_len 0x%x to 0x%x.\n",
rsp_info_len, par_sense_len);
rsp_info_len = par_sense_len;
}
sense_data += rsp_info_len;
par_sense_len -= rsp_info_len;
}
Expand Down
54 changes: 46 additions & 8 deletions net/ipv6/datagram.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,18 @@ void ip6_datagram_recv_common_ctl(struct sock *sk, struct msghdr *msg,
}
}

static u16 ipv6_get_exthdr_len(const struct sk_buff *skb, const u8 *ptr)
{
u16 len;

if (ptr + 2 > skb_tail_pointer(skb))
return 0;

len = (ptr[1] + 1) << 3;

return (len <= skb_tail_pointer(skb) - ptr) ? len : 0;
}

void ip6_datagram_recv_specific_ctl(struct sock *sk, struct msghdr *msg,
struct sk_buff *skb)
{
Expand All @@ -637,7 +649,10 @@ void ip6_datagram_recv_specific_ctl(struct sock *sk, struct msghdr *msg,
/* HbH is allowed only once */
if (np->rxopt.bits.hopopts && (opt->flags & IP6SKB_HOPBYHOP)) {
u8 *ptr = nh + sizeof(struct ipv6hdr);
put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr);
u16 len = ipv6_get_exthdr_len(skb, ptr);

if (len)
put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, len, ptr);
}

if (opt->lastopt &&
Expand All @@ -658,26 +673,37 @@ void ip6_datagram_recv_specific_ctl(struct sock *sk, struct msghdr *msg,
unsigned int len;
u8 *ptr = nh + off;

if (ptr + 2 > skb_tail_pointer(skb))
return;

switch (nexthdr) {
case IPPROTO_DSTOPTS:
nexthdr = ptr[0];
len = (ptr[1] + 1) << 3;
len = ipv6_get_exthdr_len(skb, ptr);
if (!len)
return;
if (np->rxopt.bits.dstopts)
put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, len, ptr);
break;
case IPPROTO_ROUTING:
nexthdr = ptr[0];
len = (ptr[1] + 1) << 3;
len = ipv6_get_exthdr_len(skb, ptr);
if (!len)
return;
if (np->rxopt.bits.srcrt)
put_cmsg(msg, SOL_IPV6, IPV6_RTHDR, len, ptr);
break;
case IPPROTO_AH:
nexthdr = ptr[0];
len = (ptr[1] + 2) << 2;
if (ptr + len > skb_tail_pointer(skb))
return;
break;
default:
nexthdr = ptr[0];
len = (ptr[1] + 1) << 3;
len = ipv6_get_exthdr_len(skb, ptr);
if (!len)
return;
break;
}

Expand All @@ -699,19 +725,31 @@ void ip6_datagram_recv_specific_ctl(struct sock *sk, struct msghdr *msg,
}
if (np->rxopt.bits.ohopopts && (opt->flags & IP6SKB_HOPBYHOP)) {
u8 *ptr = nh + sizeof(struct ipv6hdr);
put_cmsg(msg, SOL_IPV6, IPV6_2292HOPOPTS, (ptr[1]+1)<<3, ptr);
u16 len = ipv6_get_exthdr_len(skb, ptr);

if (len)
put_cmsg(msg, SOL_IPV6, IPV6_2292HOPOPTS, len, ptr);
}
if (np->rxopt.bits.odstopts && opt->dst0) {
u8 *ptr = nh + opt->dst0;
put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
u16 len = ipv6_get_exthdr_len(skb, ptr);

if (len)
put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, len, ptr);
}
if (np->rxopt.bits.osrcrt && opt->srcrt) {
struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(nh + opt->srcrt);
put_cmsg(msg, SOL_IPV6, IPV6_2292RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
u16 len = ipv6_get_exthdr_len(skb, (u8 *)rthdr);

if (len)
put_cmsg(msg, SOL_IPV6, IPV6_2292RTHDR, len, rthdr);
}
if (np->rxopt.bits.odstopts && opt->dst1) {
u8 *ptr = nh + opt->dst1;
put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
u16 len = ipv6_get_exthdr_len(skb, ptr);

if (len)
put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, len, ptr);
}
if (np->rxopt.bits.rxorigdstaddr) {
struct sockaddr_in6 sin6;
Expand Down
2 changes: 2 additions & 0 deletions net/ipv6/ip6_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *

if (res < 0 || res == LWTUNNEL_XMIT_DONE)
return res;
hdr = ipv6_hdr(skb);
daddr = &hdr->daddr;
}

nexthop = rt6_nexthop((struct rt6_info *)dst, daddr);
Expand Down
14 changes: 14 additions & 0 deletions net/mac802154/llsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,7 @@ int mac802154_llsec_encrypt(struct mac802154_llsec *sec, struct sk_buff *skb)
{
struct ieee802154_hdr hdr;
int rc, authlen, hlen;
struct sk_buff *trailer;
struct mac802154_llsec_key *key;
u32 frame_ctr;

Expand Down Expand Up @@ -766,6 +767,12 @@ int mac802154_llsec_encrypt(struct mac802154_llsec *sec, struct sk_buff *skb)
skb->mac_len = ieee802154_hdr_push(skb, &hdr);
skb_reset_mac_header(skb);

rc = skb_cow_data(skb, 0, &trailer);
if (rc < 0) {
llsec_key_put(key);
return rc;
}

rc = llsec_do_encrypt(skb, sec, &hdr, key);
llsec_key_put(key);

Expand Down Expand Up @@ -905,6 +912,13 @@ llsec_do_decrypt(struct sk_buff *skb, const struct mac802154_llsec *sec,
const struct ieee802154_hdr *hdr,
struct mac802154_llsec_key *key, __le64 dev_addr)
{
struct sk_buff *trailer;
int err;

err = skb_cow_data(skb, 0, &trailer);
if (err < 0)
return err;

if (hdr->sec.level == IEEE802154_SCF_SECLEVEL_ENC)
return llsec_do_decrypt_unauth(skb, sec, hdr, key, dev_addr);
else
Expand Down
19 changes: 18 additions & 1 deletion security/selinux/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -4907,7 +4907,24 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
int size)
{
return sock_has_perm(sock->sk, SOCKET__WRITE);
int rc;
struct sockaddr *const addr = msg->msg_name;
const int addrlen = msg->msg_namelen;

rc = sock_has_perm(sock->sk, SOCKET__WRITE);
if (rc)
return rc;

if (addr && (msg->msg_flags & MSG_FASTOPEN) &&
(sk_is_tcp(sock->sk) ||
(sk_is_inet(sock->sk) && sock->sk->sk_type == SOCK_STREAM &&
sock->sk->sk_protocol == IPPROTO_MPTCP))) {
rc = selinux_socket_connect(sock, addr, addrlen);
if (rc)
return rc;
}

return 0;
}

static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
Expand Down
2 changes: 2 additions & 0 deletions sound/usb/usx2y/usX2Yhwdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ static vm_fault_t snd_us428ctls_vm_fault(struct vm_fault *vmf)
vmf->pgoff);

offset = vmf->pgoff << PAGE_SHIFT;
if (offset >= US428_SHAREDMEM_PAGES)
return VM_FAULT_SIGBUS;
vaddr = (char *)((struct usx2ydev *)vmf->vma->vm_private_data)->us428ctls_sharedmem + offset;
page = virt_to_page(vaddr);
get_page(page);
Expand Down
2 changes: 2 additions & 0 deletions sound/usb/usx2y/usx2yhwdeppcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,8 @@ static vm_fault_t snd_usx2y_hwdep_pcm_vm_fault(struct vm_fault *vmf)
void *vaddr;

offset = vmf->pgoff << PAGE_SHIFT;
if (offset >= USX2Y_HWDEP_PCM_PAGES)
return VM_FAULT_SIGBUS;
vaddr = (char *)((struct usx2ydev *)vmf->vma->vm_private_data)->hwdep_pcm_shm + offset;
vmf->page = virt_to_page(vaddr);
get_page(vmf->page);
Expand Down
Loading