mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
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:
commit
2e36cc9545
@ -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
|
||||
|
2
arch/arm64/configs/vendor/sm8150_defconfig
vendored
2
arch/arm64/configs/vendor/sm8150_defconfig
vendored
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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++) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user