]> rtime.felk.cvut.cz Git - can-eth-gw-linux.git/commitdiff
canethgw: Premature release of job when garbage is received on UDP
authorMichal Sojka <sojkam1@fel.cvut.cz>
Fri, 4 Apr 2014 18:21:37 +0000 (20:21 +0200)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Fri, 4 Apr 2014 18:21:37 +0000 (20:21 +0200)
net/can/canethgw.c

index 283d75846a80ad27b9d8323e75ff19c295d6f208..532ce9540a9db78ea896835bf487c215de428df0 100644 (file)
@@ -196,8 +196,7 @@ static int cegw_thread_start(void *data)
        struct task_struct *task = NULL;
        struct cegw_job *job = (struct cegw_job *)data;
 
-       kref_init(&job->refcount);
-
+       kref_get(&job->refcount);
        task = kthread_run(cegw_udp2can, data, "canethgw_udp2can");
        if (IS_ERR(task)) {
                kref_put(&job->refcount, cegw_job_release);
@@ -225,7 +224,8 @@ static int cegw_thread_stop(struct cegw_job *job)
        struct socket *udp_sock = job->udp_sock;
        struct socket *can_sock = job->can_sock;
 
-       kernel_sock_shutdown(udp_sock, SHUT_RDWR);
+       if (udp_sock)
+               kernel_sock_shutdown(udp_sock, SHUT_RDWR);
 
        /* PF_CAN sockets do not implement shutdown - do it manualy */
        sk = can_sock->sk;
@@ -255,6 +255,7 @@ static int cegw_release(struct inode *inode, struct file *file)
        if (job) {
                cegw_thread_stop(job);
        }
+       kref_put(&job->refcount, cegw_job_release);
 
        module_put(THIS_MODULE);
        return 0;
@@ -327,6 +328,8 @@ static long cegw_ioctl_start(struct file *file, unsigned long arg)
                goto err_put_all;
        }
 
+       kref_init(&job->refcount);
+
        job->udp_dstcnt = dstcnt;
        job->udp_addrlen = addrlen;