OSDN Git Service

soc: hab: fix uninitialized variable and relocate vchan refcnt
authorYajun Li <yajunl@codeaurora.org>
Thu, 25 Oct 2018 03:08:25 +0000 (11:08 +0800)
committerYajun Li <yajunl@codeaurora.org>
Tue, 30 Oct 2018 07:54:26 +0000 (15:54 +0800)
Init hab msg pointer to avoid accessing an uninitialized
pointer.

The format specifier "%p" can leak kernel addresses. Use
"%pK" instead.

Check the status of the pfn_table, because of wrong pagetable
coming from the corresponding hab client unexpectedly.

Change-Id: Ic8c6ba0243d27007d014165f2869a5775a96c09d
Signed-off-by: Yajun Li <yajunl@codeaurora.org>
drivers/soc/qcom/hab/hab.c
drivers/soc/qcom/hab/hab.h
drivers/soc/qcom/hab/hab_mem_linux.c
drivers/soc/qcom/hab/hab_mimex.c
drivers/soc/qcom/hab/hab_msg.c
drivers/soc/qcom/hab/hab_stat.c
drivers/soc/qcom/hab/hab_vchan.c

index ebe7dfc..ee7e988 100644 (file)
@@ -599,7 +599,7 @@ int hab_vchan_recv(struct uhab_context *ctx,
 
        vchan = hab_get_vchan_fromvcid(vcid, ctx);
        if (!vchan) {
-               pr_err("vcid %X, vchan %p ctx %p\n", vcid, vchan, ctx);
+               pr_err("vcid %X vchan 0x%pK ctx %pK\n", vcid, vchan, ctx);
                return -ENODEV;
        }
 
@@ -1134,7 +1134,7 @@ static long hab_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
        struct hab_recv *recv_param;
        struct hab_send *send_param;
        struct hab_info *info_param;
-       struct hab_message *msg;
+       struct hab_message *msg = NULL;
        void *send_data;
        unsigned char data[256] = { 0 };
        long ret = 0;
index cbc049e..18bcd0a 100644 (file)
@@ -214,6 +214,7 @@ struct physical_channel {
        /* debug only */
        uint32_t sequence_tx;
        uint32_t sequence_rx;
+       uint32_t status;
 
        /* vchans on this pchan */
        struct list_head vchannels;
@@ -255,8 +256,8 @@ struct hab_export_ack_recvd {
 };
 
 struct hab_message {
-       size_t sizebytes;
        struct list_head node;
+       size_t sizebytes;
        uint32_t data[];
 };
 
index 60156c6..670efde 100644 (file)
@@ -53,6 +53,14 @@ static struct pages_list *pages_list_create(
        if (!pfn_table)
                return ERR_PTR(-EINVAL);
 
+       pfn = pfn_table->first_pfn;
+       if (pfn_valid(pfn) == 0 || page_is_ram(pfn) == 0) {
+               pr_err("imp sanity failed pfn %lx valid %d ram %d pchan %s\n",
+                       pfn, pfn_valid(pfn),
+                       page_is_ram(pfn), exp->pchan->name);
+               return ERR_PTR(-EINVAL);
+       }
+
        size = exp->payload_count * sizeof(struct page *);
        pages = kmalloc(size, GFP_KERNEL);
        if (!pages)
@@ -64,7 +72,6 @@ static struct pages_list *pages_list_create(
                return ERR_PTR(-ENOMEM);
        }
 
-       pfn = pfn_table->first_pfn;
        for (i = 0; i < pfn_table->nregions; i++) {
                for (j = 0; j < pfn_table->region[i].size; j++) {
                        pages[k] = pfn_to_page(pfn+j);
index efa4bb3..e7ce3eb 100644 (file)
@@ -277,8 +277,8 @@ int hab_mem_export(struct uhab_context *ctx,
                        &pdata_size);
        }
        if (ret < 0) {
-               pr_err("habmem_hyp_grant failed size=%d ret=%d\n",
-                       pdata_size, ret);
+               pr_err("habmem_hyp_grant vc %x failed size=%d ret=%d\n",
+                          param->vcid, pdata_size, ret);
                goto err;
        }
 
index 71010be..9323cf9 100644 (file)
@@ -210,7 +210,7 @@ int hab_msg_recv(struct physical_channel *pchan,
                 */
                vchan = hab_vchan_get(pchan, header);
                if (!vchan) {
-                       pr_info("vchan is not found, payload type %d, vchan id %x, sizebytes %zx, session %d\n",
+                       pr_debug("vchan not found type %d vcid %x sz %zx sesn %d\n",
                                payload_type, vchan_id, sizebytes, session_id);
 
                        if (sizebytes) {
@@ -313,7 +313,7 @@ int hab_msg_recv(struct physical_channel *pchan,
 
        case HAB_PAYLOAD_TYPE_CLOSE:
                /* remote request close */
-               pr_info("remote request close vcid %pK %X other id %X session %d refcnt %d\n",
+               pr_debug("remote close vcid %pK %X other id %X session %d refcnt %d\n",
                        vchan, vchan->id, vchan->otherend_id,
                        session_id, get_refcnt(vchan->refcount));
                hab_vchan_stop(vchan);
index f0a4207..b78e5e7 100644 (file)
@@ -61,14 +61,17 @@ int hab_stat_show_vchan(struct hab_driver *driver,
                                continue;
 
                        ret = hab_stat_buffer_print(buf, size,
-                               "mmid %s role %d local %d remote %d vcnt %d:\n",
+                               "nm %s r %d lc %d rm %d sq_t %d sq_r %d st 0x%x vn %d:\n",
                                pchan->name, pchan->is_be, pchan->vmid_local,
-                               pchan->vmid_remote, pchan->vcnt);
+                               pchan->vmid_remote, pchan->sequence_tx,
+                               pchan->sequence_rx, pchan->status, pchan->vcnt);
 
                        read_lock(&pchan->vchans_lock);
                        list_for_each_entry(vc, &pchan->vchannels, pnode) {
                                ret = hab_stat_buffer_print(buf, size,
-                                                "%08X ", vc->id);
+                                       "%08X(%d:%d) ", vc->id,
+                                       get_refcnt(vc->refcount),
+                                       vc->otherend_closed);
                        }
                        ret = hab_stat_buffer_print(buf, size, "\n");
                        read_unlock(&pchan->vchans_lock);
index 8d818b8..f4145c5 100644 (file)
@@ -167,6 +167,7 @@ hab_vchan_get(struct physical_channel *pchan, struct hab_header *header)
        return vchan;
 }
 
+/* wake up local waiting Q, so stop-vchan can be processed */
 void hab_vchan_stop(struct virtual_channel *vchan)
 {
        if (vchan) {
@@ -190,6 +191,7 @@ void hab_vchans_stop(struct physical_channel *pchan)
        read_unlock(&pchan->vchans_lock);
 }
 
+/* send vchan close to remote and stop receiving anything locally */
 void hab_vchan_stop_notify(struct virtual_channel *vchan)
 {
        hab_send_close_msg(vchan);