Skip to content

Commit

Permalink
Merge remote-tracking branch 'sdm845/lineage-20' into lineage-21
Browse files Browse the repository at this point in the history
* sdm845/lineage-20:
  BACKPORT: net: fix __dst_negative_advice() race
  qcacmn: Fix out of bound read issue in ESP ie parse
  memshare: Prevent possible integer overflow
  Revert "BACKPORT: memshare: Prevent possible integer overflow"
  BACKPORT: ASoC: msm-pcm-q6-v2: Add dsp buf check
  asoc: Update copy_to_user to requested buffer size
  asoc: msm-pcm-q6-v2: Update memset for period size
  asoc: Reset the buffer if size is partial or zero
  af_unix: Suppress false-positive lockdep splat for spin_lock() in __unix_gc().
  af_unix: fix lockdep positive in sk_diag_dump_icons()

Change-Id: Iba044024f0019d5351861497d7146d15f46dabc0
  • Loading branch information
mikeNG committed Aug 19, 2024
2 parents 8aa9957 + 2d3c6a3 commit fc66952
Show file tree
Hide file tree
Showing 13 changed files with 75 additions and 69 deletions.
13 changes: 7 additions & 6 deletions drivers/soc/qcom/memshare/msm_memshare.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
Expand Down Expand Up @@ -565,9 +566,8 @@ static int handle_alloc_generic_req(void *req_h, void *req, void *conn_h)
}

if (!memblock[client_id].allotted && alloc_req->num_bytes > 0) {

if (alloc_req->num_bytes > memblock[client_id].size)
alloc_req->num_bytes = memblock[client_id].size;
if (alloc_req->num_bytes > memblock[client_id].init_size)
alloc_req->num_bytes = memblock[client_id].init_size;

if (alloc_req->client_id == 1)
size = alloc_req->num_bytes + MEMSHARE_GUARD_BYTES;
Expand Down Expand Up @@ -755,9 +755,9 @@ static int handle_query_size_req(void *req_h, void *req, void *conn_h)
return -EINVAL;
}

if (memblock[client_id].size) {
if (memblock[client_id].init_size) {
query_resp->size_valid = 1;
query_resp->size = memblock[client_id].size;
query_resp->size = memblock[client_id].init_size;
} else {
query_resp->size_valid = 1;
query_resp->size = 0;
Expand Down Expand Up @@ -1017,7 +1017,7 @@ static int memshare_child_probe(struct platform_device *pdev)
else if (strcmp(name, "wcnss") == 0)
memblock[num_clients].peripheral = DHMS_MEM_PROC_WCNSS_V01;

memblock[num_clients].size = size;
memblock[num_clients].init_size = size;
memblock[num_clients].client_id = client_id;

/*
Expand All @@ -1034,6 +1034,7 @@ static int memshare_child_probe(struct platform_device *pdev)
__func__, rc);
return rc;
}
memblock[num_clients].size = size;
memblock[num_clients].allotted = 1;
shared_hyp_mapping(num_clients);
}
Expand Down
3 changes: 3 additions & 0 deletions drivers/soc/qcom/memshare/msm_memshare.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
Expand Down Expand Up @@ -45,6 +46,8 @@ struct mem_blocks {
uint32_t client_request;
/* Size required for client */
uint32_t size;
/* Available memory size for client */
uint32_t init_size;
/*
* start address of the memory block reserved by server memory
* subsystem to client
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -737,7 +737,8 @@ static void util_scan_update_esp_data(struct wlan_esp_ie *esp_information,
esp_ie = (struct wlan_esp_ie *)
util_scan_entry_esp_info(scan_entry);

total_elements = esp_ie->esp_len;
// Ignore ESP_ID_EXTN element
total_elements = esp_ie->esp_len - 1;
data = (uint8_t *)esp_ie + 3;
do_div(total_elements, ESP_INFORMATION_LIST_LENGTH);

Expand All @@ -747,7 +748,7 @@ static void util_scan_update_esp_data(struct wlan_esp_ie *esp_information,
}

for (i = 0; i < total_elements &&
data < ((uint8_t *)esp_ie + esp_ie->esp_len + 3); i++) {
data < ((uint8_t *)esp_ie + esp_ie->esp_len); i++) {
esp_info = (struct wlan_esp_info *)data;
if (esp_info->access_category == ESP_AC_BK) {
qdf_mem_copy(&esp_information->esp_info_AC_BK,
Expand Down
23 changes: 17 additions & 6 deletions include/net/af_unix.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,6 @@ struct unix_skb_parms {

#define UNIXCB(skb) (*(struct unix_skb_parms *)&((skb)->cb))

#define unix_state_lock(s) spin_lock(&unix_sk(s)->lock)
#define unix_state_unlock(s) spin_unlock(&unix_sk(s)->lock)
#define unix_state_lock_nested(s) \
spin_lock_nested(&unix_sk(s)->lock, \
SINGLE_DEPTH_NESTING)

/* The AF_UNIX socket */
struct unix_sock {
/* WARNING: sk has to be the first member */
Expand All @@ -71,6 +65,23 @@ static inline struct unix_sock *unix_sk(const struct sock *sk)
return (struct unix_sock *)sk;
}

#define unix_state_lock(s) spin_lock(&unix_sk(s)->lock)
#define unix_state_unlock(s) spin_unlock(&unix_sk(s)->lock)
enum unix_socket_lock_class {
U_LOCK_NORMAL,
U_LOCK_SECOND, /* for double locking, see unix_state_double_lock(). */
U_LOCK_DIAG, /* used while dumping icons, see sk_diag_dump_icons(). */
U_LOCK_GC_LISTENER, /* used for listening socket while determining gc
* candidates to close a small race window.
*/
};

static inline void unix_state_lock_nested(struct sock *sk,
enum unix_socket_lock_class subclass)
{
spin_lock_nested(&unix_sk(sk)->lock, subclass);
}

#define peer_wait peer_wq.wait

long unix_inq_len(struct sock *sk);
Expand Down
2 changes: 1 addition & 1 deletion include/net/dst_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct dst_ops {
void (*destroy)(struct dst_entry *);
void (*ifdown)(struct dst_entry *,
struct net_device *dev, int how);
struct dst_entry * (*negative_advice)(struct dst_entry *);
void (*negative_advice)(struct sock *sk, struct dst_entry *);
void (*link_failure)(struct sk_buff *);
void (*update_pmtu)(struct dst_entry *dst, struct sock *sk,
struct sk_buff *skb, u32 mtu);
Expand Down
12 changes: 3 additions & 9 deletions include/net/sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -1722,18 +1722,12 @@ sk_dst_get(struct sock *sk)

static inline void dst_negative_advice(struct sock *sk)
{
struct dst_entry *ndst, *dst = __sk_dst_get(sk);
struct dst_entry *dst = __sk_dst_get(sk);

sk_rethink_txhash(sk);

if (dst && dst->ops->negative_advice) {
ndst = dst->ops->negative_advice(dst);

if (ndst != dst) {
rcu_assign_pointer(sk->sk_dst_cache, ndst);
sk_tx_queue_clear(sk);
}
}
if (dst && dst->ops->negative_advice)
dst->ops->negative_advice(sk, dst);
}

static inline void
Expand Down
22 changes: 8 additions & 14 deletions net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ static int ip_rt_gc_timeout __read_mostly = RT_GC_TIMEOUT;
static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie);
static unsigned int ipv4_default_advmss(const struct dst_entry *dst);
static unsigned int ipv4_mtu(const struct dst_entry *dst);
static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
static void ipv4_negative_advice(struct sock *sk,
struct dst_entry *dst);
static void ipv4_link_failure(struct sk_buff *skb);
static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
struct sk_buff *skb, u32 mtu);
Expand Down Expand Up @@ -842,22 +843,15 @@ static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buf
__ip_do_redirect(rt, skb, &fl4, true);
}

static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
static void ipv4_negative_advice(struct sock *sk,
struct dst_entry *dst)
{
struct rtable *rt = (struct rtable *)dst;
struct dst_entry *ret = dst;

if (rt) {
if (dst->obsolete > 0) {
ip_rt_put(rt);
ret = NULL;
} else if ((rt->rt_flags & RTCF_REDIRECTED) ||
rt->dst.expires) {
ip_rt_put(rt);
ret = NULL;
}
}
return ret;
if ((dst->obsolete > 0) ||
(rt->rt_flags & RTCF_REDIRECTED) ||
rt->dst.expires)
sk_dst_reset(sk);
}

/*
Expand Down
25 changes: 13 additions & 12 deletions net/ipv6/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ static void ip6_rt_copy_init(struct rt6_info *rt, struct rt6_info *ort);
static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie);
static unsigned int ip6_default_advmss(const struct dst_entry *dst);
static unsigned int ip6_mtu(const struct dst_entry *dst);
static struct dst_entry *ip6_negative_advice(struct dst_entry *);
static void ip6_negative_advice(struct sock *sk,
struct dst_entry *dst);
static void ip6_dst_destroy(struct dst_entry *);
static void ip6_dst_ifdown(struct dst_entry *,
struct net_device *dev, int how);
Expand Down Expand Up @@ -1302,22 +1303,22 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
return rt6_check(rt, cookie);
}

static struct dst_entry *ip6_negative_advice(struct dst_entry *dst)
static void ip6_negative_advice(struct sock *sk,
struct dst_entry *dst)
{
struct rt6_info *rt = (struct rt6_info *) dst;

if (rt) {
if (rt->rt6i_flags & RTF_CACHE) {
if (rt6_check_expired(rt)) {
ip6_del_rt(rt);
dst = NULL;
}
} else {
dst_release(dst);
dst = NULL;
if (rt->rt6i_flags & RTF_CACHE) {
if (rt6_check_expired(rt)) {
/* counteract the dst_release() in sk_dst_reset() */
dst_hold(dst);
sk_dst_reset(sk);

ip6_del_rt(rt);
}
return;
}
return dst;
sk_dst_reset(sk);
}

static void ip6_link_failure(struct sk_buff *skb)
Expand Down
14 changes: 6 additions & 8 deletions net/unix/af_unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -1114,13 +1114,11 @@ static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
unix_state_lock(sk1);
return;
}
if (sk1 < sk2) {
unix_state_lock(sk1);
unix_state_lock_nested(sk2);
} else {
unix_state_lock(sk2);
unix_state_lock_nested(sk1);
}
if (sk1 > sk2)
swap(sk1, sk2);

unix_state_lock(sk1);
unix_state_lock_nested(sk2, U_LOCK_SECOND);
}

static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
Expand Down Expand Up @@ -1339,7 +1337,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
goto out_unlock;
}

unix_state_lock_nested(sk);
unix_state_lock_nested(sk, U_LOCK_SECOND);

if (sk->sk_state != st) {
unix_state_unlock(sk);
Expand Down
2 changes: 1 addition & 1 deletion net/unix/diag.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ static int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb)
* queue lock. With the other's queue locked it's
* OK to lock the state.
*/
unix_state_lock_nested(req);
unix_state_lock_nested(req, U_LOCK_DIAG);
peer = unix_sk(req)->peer;
buf[i++] = (peer ? sock_i_ino(peer) : 0);
unix_state_unlock(req);
Expand Down
2 changes: 1 addition & 1 deletion net/unix/garbage.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ void unix_gc(void)
__set_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags);

if (sk->sk_state == TCP_LISTEN) {
unix_state_lock(sk);
unix_state_lock_nested(sk, U_LOCK_GC_LISTENER);
unix_state_unlock(sk);
}
}
Expand Down
11 changes: 3 additions & 8 deletions net/xfrm/xfrm_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -2724,15 +2724,10 @@ static void xfrm_link_failure(struct sk_buff *skb)
/* Impossible. Such dst must be popped before reaches point of failure. */
}

static struct dst_entry *xfrm_negative_advice(struct dst_entry *dst)
static void xfrm_negative_advice(struct sock *sk, struct dst_entry *dst)
{
if (dst) {
if (dst->obsolete) {
dst_release(dst);
dst = NULL;
}
}
return dst;
if (dst->obsolete)
sk_dst_reset(sk);
}

void xfrm_garbage_collect(struct net *net)
Expand Down
10 changes: 9 additions & 1 deletion techpack/audio/asoc/msm-pcm-q6-v2.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
Expand Down Expand Up @@ -953,6 +953,14 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream,
goto fail;
}

if ((size == 0 || size < prtd->pcm_count) && ((offset + size) < prtd->pcm_count)) {
memset(bufptr + offset + size, 0, prtd->pcm_count - size);
if (fbytes > prtd->pcm_count)
size = xfer = prtd->pcm_count;
else
size = xfer = fbytes;
}

if (copy_to_user(buf, bufptr+offset, xfer)) {
pr_err("Failed to copy buf to user\n");
ret = -EFAULT;
Expand Down

0 comments on commit fc66952

Please sign in to comment.