Merge tag 'LA.UM.9.1.r1-15900.01-SMxxx0.QSSI14.0' of https://git.codelinaro.org/clo/la/kernel/msm-4.14 into HEAD

"LA.UM.9.1.r1-15900.01-SMxxx0.QSSI14.0"

* tag 'LA.UM.9.1.r1-15900.01-SMxxx0.QSSI14.0' of https://git.codelinaro.org/clo/la/kernel/msm-4.14:
  soc: qcom: smem: Add boundary checks for partitions
  msm: kgsl: Do not release dma and anon buffers if unmap fails
  BACKPORT: media: venus: hfi: fix the check to handle buffer requirement
  qseecom: Change in buffer sharing mechanism in qseecom
  securemsm-kernel: Fix multiple listener registration on same fd
  BACKPORT: media: venus: hfi: fix the check in session buffer requirement
  Revert "BACKPORT: bpf: add bpf_ktime_get_boot_ns()"
  defconfig: sm8150: Fix for SonyDualSenseEdge cts failures
  UPSTREAM: net: bpf: Make bpf_ktime_get_ns() available to non GPL programs
  UPSTREAM: net: bpf: Make bpf_ktime_get_ns() available to non GPL programs
  BACKPORT: bpf: add bpf_ktime_get_boot_ns()
  defconfig: sm8150: Fix for SonyDualSenseEdge cts failures
  BACKPORT: bpf: add bpf_ktime_get_boot_ns()
  msm: adsprpc: Handle UAF in process shell memory
  msm: npu: Fix use after free issue
  soc: qcom: qmi_encdec: out of bound check for input buffer
  msm: kgsl: Prevent wrap around during user address mapping

Change-Id: I4dedb53f2445ddad6cf74cdac6a5dac9aa574f8c
Signed-off-by: Richard Raya <rdxzv.dev@gmail.com>
This commit is contained in:
Richard Raya 2024-03-25 23:12:40 -03:00
commit 2e36cc9545
6 changed files with 140 additions and 37 deletions

View File

@ -456,8 +456,6 @@ CONFIG_HID_MICROSOFT=y
CONFIG_HID_MULTITOUCH=y
CONFIG_HID_NINTENDO=y
CONFIG_HID_PLANTRONICS=y
CONFIG_HID_PLAYSTATION=y
CONFIG_PLAYSTATION_FF=y
CONFIG_HID_SONY=y
CONFIG_SONY_FF=y
CONFIG_HID_QVR=y

View File

@ -471,8 +471,6 @@ CONFIG_HID_MICROSOFT=y
CONFIG_HID_MULTITOUCH=y
CONFIG_HID_NINTENDO=y
CONFIG_HID_PLANTRONICS=y
CONFIG_HID_PLAYSTATION=y
CONFIG_PLAYSTATION_FF=y
CONFIG_HID_SONY=y
CONFIG_SONY_FF=y
CONFIG_HID_QVR=y

View File

@ -2347,6 +2347,8 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
VERIFY(err, !fastrpc_mmap_create(fl, -1, 0, init->mem,
init->memlen, ADSP_MMAP_REMOTE_HEAP_ADDR,
&mem));
if (mem)
mem->is_filemap = true;
mutex_unlock(&fl->map_mutex);
if (err)
goto bail;

View File

@ -346,6 +346,9 @@ static void kgsl_destroy_ion(struct kgsl_memdesc *memdesc)
struct kgsl_mem_entry, memdesc);
struct kgsl_dma_buf_meta *meta = entry->priv_data;
if (memdesc->priv & KGSL_MEMDESC_MAPPED)
return;
if (meta != NULL) {
remove_dmabuf_list(meta);
dma_buf_unmap_attachment(meta->attach, meta->table,
@ -374,6 +377,9 @@ static void kgsl_destroy_anon(struct kgsl_memdesc *memdesc)
struct scatterlist *sg;
struct page *page;
if (memdesc->priv & KGSL_MEMDESC_MAPPED)
return;
for_each_sg(memdesc->sgt->sgl, sg, memdesc->sgt->nents, i) {
page = sg_page(sg);
for (j = 0; j < (sg->length >> PAGE_SHIFT); j++) {

View File

@ -371,7 +371,7 @@ struct qseecom_client_handle {
struct qseecom_listener_handle {
u32 id;
bool unregister_pending;
bool register_pending;
bool release_called;
};
@ -454,6 +454,10 @@ static int get_qseecom_keymaster_status(char *str)
}
__setup("androidboot.keymaster=", get_qseecom_keymaster_status);
static int __qseecom_alloc_coherent_buf(
uint32_t size, u8 **vaddr, phys_addr_t *paddr);
static void __qseecom_free_coherent_buf(uint32_t size,
u8 *vaddr, phys_addr_t paddr);
#define QSEECOM_SCM_EBUSY_WAIT_MS 30
#define QSEECOM_SCM_EBUSY_MAX_RETRY 67
@ -1390,6 +1394,11 @@ static int qseecom_register_listener(struct qseecom_dev_handle *data,
struct qseecom_registered_listener_list *new_entry;
struct qseecom_registered_listener_list *ptr_svc;
if (data->listener.register_pending) {
pr_err("Already a listner registration is in process on this FD\n");
return -EINVAL;
}
ret = copy_from_user(&rcvd_lstnr, argp, sizeof(rcvd_lstnr));
if (ret) {
pr_err("copy_from_user failed\n");
@ -1399,6 +1408,13 @@ static int qseecom_register_listener(struct qseecom_dev_handle *data,
rcvd_lstnr.sb_size))
return -EFAULT;
ptr_svc = __qseecom_find_svc(data->listener.id);
if (ptr_svc) {
pr_err("Already a listener registered on this data: lid=%d\n",
data->listener.id);
return -EINVAL;
}
ptr_svc = __qseecom_find_svc(rcvd_lstnr.listener_id);
if (ptr_svc) {
if (ptr_svc->unregister_pending == false) {
@ -1433,12 +1449,15 @@ static int qseecom_register_listener(struct qseecom_dev_handle *data,
new_entry->svc.listener_id = rcvd_lstnr.listener_id;
new_entry->sb_length = rcvd_lstnr.sb_size;
new_entry->user_virt_sb_base = rcvd_lstnr.virt_sb_base;
data->listener.register_pending = true;
if (__qseecom_set_sb_memory(new_entry, data, &rcvd_lstnr)) {
pr_err("qseecom_set_sb_memory failed for listener %d, size %d\n",
rcvd_lstnr.listener_id, rcvd_lstnr.sb_size);
kzfree(new_entry);
data->listener.register_pending = false;
return -ENOMEM;
}
data->listener.register_pending = false;
init_waitqueue_head(&new_entry->rcv_req_wq);
init_waitqueue_head(&new_entry->listener_block_app_wq);
@ -3565,7 +3584,8 @@ int __qseecom_process_reentrancy(struct qseecom_command_scm_resp *resp,
}
static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
struct qseecom_send_cmd_req *req)
struct qseecom_send_cmd_req *req,
bool is_phys_adr)
{
int ret = 0;
u32 reqd_len_sb_in = 0;
@ -3607,11 +3627,20 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
if (qseecom.qsee_version < QSEE_VERSION_40) {
send_data_req.app_id = data->client.app_id;
send_data_req.req_ptr = (uint32_t)(__qseecom_uvirt_to_kphys(
data, (uintptr_t)req->cmd_req_buf));
if (!is_phys_adr) {
send_data_req.req_ptr =
(uint32_t)(__qseecom_uvirt_to_kphys
(data, (uintptr_t)req->cmd_req_buf));
send_data_req.rsp_ptr =
(uint32_t)(__qseecom_uvirt_to_kphys(
data, (uintptr_t)req->resp_buf));
} else {
send_data_req.req_ptr = (uint32_t)req->cmd_req_buf;
send_data_req.rsp_ptr = (uint32_t)req->resp_buf;
}
send_data_req.req_len = req->cmd_req_len;
send_data_req.rsp_ptr = (uint32_t)(__qseecom_uvirt_to_kphys(
data, (uintptr_t)req->resp_buf));
send_data_req.rsp_len = req->resp_len;
send_data_req.sglistinfo_ptr =
(uint32_t)virt_to_phys(table);
@ -3622,11 +3651,21 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
cmd_len = sizeof(struct qseecom_client_send_data_ireq);
} else {
send_data_req_64bit.app_id = data->client.app_id;
send_data_req_64bit.req_ptr = __qseecom_uvirt_to_kphys(data,
(uintptr_t)req->cmd_req_buf);
if (!is_phys_adr) {
send_data_req_64bit.req_ptr =
__qseecom_uvirt_to_kphys(data,
(uintptr_t)req->cmd_req_buf);
send_data_req_64bit.rsp_ptr =
__qseecom_uvirt_to_kphys(data,
(uintptr_t)req->resp_buf);
} else {
send_data_req_64bit.req_ptr =
(uintptr_t)req->cmd_req_buf;
send_data_req_64bit.rsp_ptr =
(uintptr_t)req->resp_buf;
}
send_data_req_64bit.req_len = req->cmd_req_len;
send_data_req_64bit.rsp_ptr = __qseecom_uvirt_to_kphys(data,
(uintptr_t)req->resp_buf);
send_data_req_64bit.rsp_len = req->resp_len;
/* check if 32bit app's phys_addr region is under 4GB.*/
if ((data->client.app_arch == ELFCLASS32) &&
@ -3723,7 +3762,7 @@ static int qseecom_send_cmd(struct qseecom_dev_handle *data, void __user *argp)
if (__validate_send_cmd_inputs(data, &req))
return -EINVAL;
ret = __qseecom_send_cmd(data, &req);
ret = __qseecom_send_cmd(data, &req, false);
if (ret)
return ret;
@ -4213,6 +4252,9 @@ static int __qseecom_send_modfd_cmd(struct qseecom_dev_handle *data,
int i;
struct qseecom_send_modfd_cmd_req req;
struct qseecom_send_cmd_req send_cmd_req;
void *origin_req_buf_kvirt, *origin_rsp_buf_kvirt;
phys_addr_t pa;
u8 *va = NULL;
ret = copy_from_user(&req, argp, sizeof(req));
if (ret) {
@ -4236,33 +4278,57 @@ static int __qseecom_send_modfd_cmd(struct qseecom_dev_handle *data,
return -EINVAL;
}
}
req.cmd_req_buf = (void *)__qseecom_uvirt_to_kvirt(data,
(uintptr_t)req.cmd_req_buf);
req.resp_buf = (void *)__qseecom_uvirt_to_kvirt(data,
(uintptr_t)req.resp_buf);
/*Back up original address */
origin_req_buf_kvirt = (void *)__qseecom_uvirt_to_kvirt(data,
(uintptr_t)req.cmd_req_buf);
origin_rsp_buf_kvirt = (void *)__qseecom_uvirt_to_kvirt(data,
(uintptr_t)req.resp_buf);
/* Allocate kernel buffer for request and response*/
ret = __qseecom_alloc_coherent_buf(req.cmd_req_len + req.resp_len,
&va, &pa);
req.cmd_req_buf = va;
send_cmd_req.cmd_req_buf = (void *)pa;
req.resp_buf = va + req.cmd_req_len;
send_cmd_req.resp_buf = (void *)pa + req.cmd_req_len;
/* Copy the data to kernel request and response buffers*/
memcpy(req.cmd_req_buf, origin_req_buf_kvirt, req.cmd_req_len);
memcpy(req.resp_buf, origin_rsp_buf_kvirt, req.resp_len);
if (!is_64bit_addr) {
ret = __qseecom_update_cmd_buf(&req, false, data);
if (ret)
return ret;
ret = __qseecom_send_cmd(data, &send_cmd_req);
goto out;
ret = __qseecom_send_cmd(data, &send_cmd_req, true);
if (ret)
return ret;
goto out;
ret = __qseecom_update_cmd_buf(&req, true, data);
if (ret)
return ret;
goto out;
} else {
ret = __qseecom_update_cmd_buf_64(&req, false, data);
if (ret)
return ret;
ret = __qseecom_send_cmd(data, &send_cmd_req);
goto out;
ret = __qseecom_send_cmd(data, &send_cmd_req, true);
if (ret)
return ret;
goto out;
ret = __qseecom_update_cmd_buf_64(&req, true, data);
if (ret)
return ret;
goto out;
}
/*Copy the response back to the userspace buffer*/
memcpy(origin_rsp_buf_kvirt, req.resp_buf, req.resp_len);
memcpy(origin_req_buf_kvirt, req.cmd_req_buf, req.cmd_req_len);
out:
if (req.cmd_req_buf)
__qseecom_free_coherent_buf(req.cmd_req_len + req.resp_len,
req.cmd_req_buf, (phys_addr_t)send_cmd_req.cmd_req_buf);
return ret;
}
@ -5132,7 +5198,7 @@ int qseecom_send_command(struct qseecom_handle *handle, void *send_buf,
dmac_flush_range(req.cmd_req_buf, req.cmd_req_buf + req.cmd_req_len);
ret = __qseecom_send_cmd(data, &req);
ret = __qseecom_send_cmd(data, &req, false);
dmac_flush_range(req.resp_buf, req.resp_buf + req.resp_len);

View File

@ -435,6 +435,7 @@ static int qmi_encode(struct qmi_elem_info *ei_array, void *out_buf,
* @buf_src: Buffer containing the elements in QMI wire format.
* @elem_len: Number of elements to be decoded.
* @elem_size: Size of a single instance of the element to be decoded.
* @src_len: Source buffer length.
*
* Returns the total size of the decoded data elements, in bytes.
*
@ -445,10 +446,13 @@ static int qmi_encode(struct qmi_elem_info *ei_array, void *out_buf,
* function returns the number of bytes of decoded information.
*/
static int qmi_decode_basic_elem(void *buf_dst, const void *buf_src,
u32 elem_len, u32 elem_size)
u32 elem_len, u32 elem_size, u32 src_len)
{
u32 i, rc = 0;
if (elem_len * elem_size > src_len)
return -EINVAL;
for (i = 0; i < elem_len; i++) {
QMI_ENCDEC_DECODE_N_BYTES(buf_dst, buf_src, elem_size);
rc += elem_size;
@ -466,6 +470,7 @@ static int qmi_decode_basic_elem(void *buf_dst, const void *buf_src,
* @tlv_len: Total size of the encoded inforation corresponding to
* this struct element.
* @dec_level: Depth of the nested structure from the main structure.
* @src_len: Source buffer length.
*
* Returns the total size of the decoded data elements on success, negative
* errno on error.
@ -479,16 +484,20 @@ static int qmi_decode_basic_elem(void *buf_dst, const void *buf_src,
static int qmi_decode_struct_elem(struct qmi_elem_info *ei_array,
void *buf_dst, const void *buf_src,
u32 elem_len, u32 tlv_len,
int dec_level)
int dec_level, u32 src_len)
{
int i, rc, decoded_bytes = 0;
struct qmi_elem_info *temp_ei = ei_array;
if (tlv_len > src_len)
return -EINVAL;
for (i = 0; i < elem_len && decoded_bytes < tlv_len; i++) {
rc = qmi_decode(temp_ei->ei_array, buf_dst, buf_src,
tlv_len - decoded_bytes, dec_level);
if (rc < 0)
return rc;
buf_src = buf_src + rc;
buf_dst = buf_dst + temp_ei->elem_size;
decoded_bytes += rc;
@ -512,6 +521,7 @@ static int qmi_decode_struct_elem(struct qmi_elem_info *ei_array,
* @tlv_len: Total size of the encoded inforation corresponding to
* this string element.
* @dec_level: Depth of the string element from the main structure.
* @src_len: Source buffer length.
*
* Returns the total size of the decoded data elements on success, negative
@ -525,7 +535,7 @@ static int qmi_decode_struct_elem(struct qmi_elem_info *ei_array,
*/
static int qmi_decode_string_elem(struct qmi_elem_info *ei_array,
void *buf_dst, const void *buf_src,
u32 tlv_len, int dec_level)
u32 tlv_len, int dec_level, u32 src_len)
{
int rc;
int decoded_bytes = 0;
@ -539,7 +549,10 @@ static int qmi_decode_string_elem(struct qmi_elem_info *ei_array,
string_len_sz = temp_ei->elem_len <= U8_MAX ?
sizeof(u8) : sizeof(u16);
rc = qmi_decode_basic_elem(&string_len, buf_src,
1, string_len_sz);
1, string_len_sz, src_len);
if (rc < 0)
return rc;
decoded_bytes += rc;
}
@ -554,7 +567,11 @@ static int qmi_decode_string_elem(struct qmi_elem_info *ei_array,
}
rc = qmi_decode_basic_elem(buf_dst, buf_src + decoded_bytes,
string_len, temp_ei->elem_size);
string_len, temp_ei->elem_size,
src_len - decoded_bytes);
if (rc < 0)
return rc;
*((char *)buf_dst + string_len) = '\0';
decoded_bytes += rc;
return decoded_bytes;
@ -618,6 +635,10 @@ static int qmi_decode(struct qmi_elem_info *ei_array, void *out_c_struct,
if (dec_level == 1) {
tlv_pointer = buf_src;
if (decoded_bytes + TLV_TYPE_SIZE + TLV_LEN_SIZE >
in_buf_len)
return -EINVAL;
QMI_ENCDEC_DECODE_TLV(&tlv_type,
&tlv_len, tlv_pointer);
buf_src += (TLV_TYPE_SIZE + TLV_LEN_SIZE);
@ -650,7 +671,11 @@ static int qmi_decode(struct qmi_elem_info *ei_array, void *out_c_struct,
data_len_sz = temp_ei->elem_size == sizeof(u8) ?
sizeof(u8) : sizeof(u16);
rc = qmi_decode_basic_elem(&data_len_value, buf_src,
1, data_len_sz);
1, data_len_sz,
in_buf_len - decoded_bytes);
if (rc < 0)
return rc;
memcpy(buf_dst, &data_len_value, sizeof(u32));
temp_ei = temp_ei + 1;
buf_dst = out_c_struct + temp_ei->offset;
@ -677,24 +702,32 @@ static int qmi_decode(struct qmi_elem_info *ei_array, void *out_c_struct,
case QMI_SIGNED_4_BYTE_ENUM:
rc = qmi_decode_basic_elem(buf_dst, buf_src,
data_len_value,
temp_ei->elem_size);
temp_ei->elem_size,
in_buf_len - decoded_bytes);
if (rc < 0)
return rc;
UPDATE_DECODE_VARIABLES(buf_src, decoded_bytes, rc);
break;
case QMI_STRUCT:
rc = qmi_decode_struct_elem(temp_ei, buf_dst, buf_src,
data_len_value, tlv_len,
dec_level + 1);
dec_level + 1,
in_buf_len - decoded_bytes);
if (rc < 0)
return rc;
UPDATE_DECODE_VARIABLES(buf_src, decoded_bytes, rc);
break;
case QMI_STRING:
rc = qmi_decode_string_elem(temp_ei, buf_dst, buf_src,
tlv_len, dec_level);
tlv_len, dec_level,
in_buf_len - decoded_bytes);
if (rc < 0)
return rc;
UPDATE_DECODE_VARIABLES(buf_src, decoded_bytes, rc);
break;