]> rtime.felk.cvut.cz Git - can-eth-gw-linux.git/blobdiff - net/can/canethgw.c
canethgw: Premature release of job when garbage is received on UDP
[can-eth-gw-linux.git] / net / can / canethgw.c
index 6c9c8aae64c7aa1b6c2ab6c1af42cbed85149cf1..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;
 
@@ -366,7 +369,8 @@ static const struct file_operations cegw_fops = {
        .owner = THIS_MODULE,
        .open = cegw_open,
        .release = cegw_release,
-       .unlocked_ioctl = cegw_ioctl
+       .unlocked_ioctl = cegw_ioctl,
+       .compat_ioctl = cegw_ioctl,
 };
 
 static struct miscdevice cegw_device = {