Messages in this thread Patch in this message |  | | Date | Sun, 27 Aug 2000 19:21:20 -0300 | From | Arnaldo Carvalho de Melo <> | Subject | [PATCH] ixj.c: check put_user, get rid of check_region, etc |
| |
Hi,
Please consider applying.
- Arnaldo
--- linux-2.4.0-test7/drivers/telephony/ixj.c Thu Jul 13 01:58:43 2000 +++ linux-2.4.0-test7.acme/drivers/telephony/ixj.c Sun Aug 27 19:17:42 2000 @@ -17,10 +17,16 @@ * David W. Erhart, <derhart@quicknet.net> * John Sellers, <jsellers@quicknet.net> * Mike Preston, <mpreston@quicknet.net> + * Arnaldo Carvalho de Melo <acme@conectiva.com.br> * * Fixes: * * 2.3.x port : Alan Cox + * check put_user return, + * resource release on failure in + * ixj_build_cadence, get rid of + * check_region (race in 2.4), + * some cleanups : Arnaldo Carvalho de Melo * * More information about the hardware related to this driver can be found * at our website: http://www.quicknet.net @@ -1306,10 +1312,7 @@ /* Don't ever copy more than the user asks */ i = copy_to_user(buf, j->read_buffer, min(length, j->read_buffer_size)); j->read_buffer_ready = 0; - if (i) - return -EFAULT; - else - return min(length, j->read_buffer_size); + return i ? -EFAULT : min(length, j->read_buffer_size); } ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length, @@ -1373,10 +1376,7 @@ if (j->write_buffer_wp + count >= j->write_buffer_end) j->write_buffer_wp = j->write_buffer; i = copy_from_user(j->write_buffer_wp, buf, min(count, j->write_buffer_size)); - if (i) - return -EFAULT; - - return min(count, j->write_buffer_size); + return i ? -EFAULT : min(count, j->write_buffer_size); } ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count, @@ -3391,21 +3391,22 @@ IXJ_CADENCE_ELEMENT *lcep; IXJ_TONE ti; IXJ *j = &ixj[board]; + int ret = -EFAULT; lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL); if (lcp == NULL) return -ENOMEM; if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE))) - return -EFAULT; + goto cleanup_lcp; lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL); if (lcep == NULL) { - kfree(lcp); - return -ENOMEM; + ret = -ENOMEM; + goto cleanup_lcp; } if (copy_from_user(lcep, lcp->ce, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used)) - return -EFAULT; + goto cleanup_lcep; if(j->cadence_t) { @@ -3429,6 +3430,9 @@ ixj_play_tone(board, lcp->ce[0].index); return 1; +cleanup_lcep: kfree(lcep); +cleanup_lcp: kfree(lcp); + return ret; } static void add_caps(int board) @@ -3668,22 +3672,22 @@ samplerate = arg; break; case IXJCTL_DRYBUFFER_READ: - put_user(j->drybuffer, (unsigned long *) arg); + retval = put_user(j->drybuffer, (unsigned long *) arg); break; case IXJCTL_DRYBUFFER_CLEAR: j->drybuffer = 0; break; case IXJCTL_FRAMES_READ: - put_user(j->framesread, (unsigned long *) arg); + retval = put_user(j->framesread, (unsigned long *) arg); break; case IXJCTL_FRAMES_WRITTEN: - put_user(j->frameswritten, (unsigned long *) arg); + retval = put_user(j->frameswritten, (unsigned long *) arg); break; case IXJCTL_READ_WAIT: - put_user(j->read_wait, (unsigned long *) arg); + retval = put_user(j->read_wait, (unsigned long *) arg); break; case IXJCTL_WRITE_WAIT: - put_user(j->write_wait, (unsigned long *) arg); + retval = put_user(j->write_wait, (unsigned long *) arg); break; case PHONE_MAXRINGS: j->maxrings = arg; @@ -3814,9 +3818,7 @@ default:val=proto_size[pd.type]*3;break; } pd.buf_min=pd.buf_max=pd.buf_opt=val; - if(copy_to_user((void *)arg, &pd, sizeof(pd))) - return -EFAULT; - return 0; + return copy_to_user((void *)arg, &pd, sizeof(pd)) ? -EFAULT : 0; } case IXJCTL_DSP_IDLE: idle(board); @@ -3904,7 +3906,8 @@ retval = j->filter_hist[arg]; break; case IXJCTL_INIT_TONE: - copy_from_user(&ti, (char *) arg, sizeof(ti)); + if (copy_from_user(&ti, (char *) arg, sizeof(ti))) + return -EFAULT; retval = ixj_init_tone(board, &ti); break; case IXJCTL_TONE_CADENCE: @@ -4101,26 +4104,27 @@ { j->cardtype = 400; // Internet PhoneJACK Lite - if (check_region(j->XILINXbase, 4)) { + if (!request_region(j->XILINXbase, 4, "ixj control")) { printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); return -1; } - request_region(j->XILINXbase, 4, "ixj control"); j->pld_slicw.pcib.e1 = 1; outb_p(j->pld_slicw.byte, j->XILINXbase); } else { j->cardtype = 300; // Internet LineJACK - if (check_region(j->XILINXbase, 8)) { + if (!request_region(j->XILINXbase, 8, "ixj control")) { printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); return -1; } - request_region(j->XILINXbase, 8, "ixj control"); } } else if (j->dsp.low == 0x22) { j->cardtype = 500; // Internet PhoneJACK PCI - request_region(j->XILINXbase, 4, "ixj control"); + if (!request_region(j->XILINXbase, 4, "ixj control")) { + printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); + return -1; + } j->pld_slicw.pcib.e1 = 1; outb_p(j->pld_slicw.byte, j->XILINXbase); } else @@ -4140,21 +4144,18 @@ break; case 300: // Internet LineJACK - if (check_region(j->XILINXbase, 8)) { + if (!request_region(j->XILINXbase, 8, "ixj control")) { printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); return -1; } - request_region(j->XILINXbase, 8, "ixj control"); break; case 400: //Internet PhoneJACK Lite case 500: //Internet PhoneJACK PCI - - if (check_region(j->XILINXbase, 4)) { + if (!request_region(j->XILINXbase, 4, "ixj control")) { printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); return -1; } - request_region(j->XILINXbase, 4, "ixj control"); j->pld_slicw.pcib.e1 = 1; outb_p(j->pld_slicw.byte, j->XILINXbase); break; @@ -4549,13 +4550,11 @@ if (func != 0x110) ixj[cnt].XILINXbase = dev->resource[1].start; /* get real port */ - result = check_region(ixj[cnt].DSPbase, 16); - if (result) { + if (!request_region(ixj[cnt].DSPbase, 16, "ixj DSP")) { printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", ixj[cnt].DSPbase); cleanup(); - return result; + return -EBUSY; } - request_region(ixj[cnt].DSPbase, 16, "ixj DSP"); switch (func) { case (0x110): ixj[cnt].cardtype = 100; @@ -4591,13 +4590,11 @@ ixj[cnt].DSPbase = dspio[cnt]; ixj[cnt].XILINXbase = xio[cnt]; ixj[cnt].cardtype = 0; - result = check_region(ixj[cnt].DSPbase, 16); - if (result) { + if (!request_region(ixj[cnt].DSPbase, 16, "ixj DSP")) { printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", ixj[cnt].DSPbase); cleanup(); - return result; + return -EBUSY; } - request_region(ixj[cnt].DSPbase, 16, "ixj DSP"); probe = ixj_selfprobe(cnt); ixj[cnt].dev = NULL; } @@ -4616,13 +4613,11 @@ ixj[cnt].XILINXbase = ixj[cnt].DSPbase + 0x10; ixj[cnt].serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2); - result = check_region(ixj[cnt].DSPbase, 16); - if (result) { + if (!request_region(ixj[cnt].DSPbase, 16, "ixj DSP")) { printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", ixj[cnt].DSPbase); cleanup(); - return result; + return -EBUSY; } - request_region(ixj[cnt].DSPbase, 16, "ixj DSP"); ixj[cnt].cardtype = 500; probe = ixj_selfprobe(cnt); cnt++; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/
|  |