- fix copy_{to,from}_user error handling, thanks to Rusty to pointing this out on lkml
----------------------------------------------------------------- */
- copy_from_user(ch->tmp_buf, buf, bytesAvailable);
+ if (copy_from_user(ch->tmp_buf, buf,
+ bytesAvailable))
+ return -EFAULT;
} /* End if area verified */
di.port = boards[brd].port ;
di.membase = boards[brd].membase ;
- copy_to_user((char *)arg, &di, sizeof (di));
+ if (copy_to_user((char *)arg, &di, sizeof (di)))
+ return -EFAULT;
break;
} /* End case DIGI_GETINFO */
{ /* Begin switch cmd */
case TCGETS:
- retval = verify_area(VERIFY_WRITE, (void *)arg,
- sizeof(struct termios));
-
- if (retval)
- return(retval);
-
- copy_to_user((struct termios *)arg,
- tty->termios, sizeof(struct termios));
+ if (copy_to_user((struct termios *)arg,
+ tty->termios, sizeof(struct termios)))
+ return -EFAULT;
return(0);
case TCGETA:
break;
case DIGI_GETA:
- if ((error=
- verify_area(VERIFY_WRITE, (char*)arg, sizeof(digi_t))))
- {
- printk(KERN_ERR "<Error> - Digi GETA failed\n");
- return(error);
- }
-
- copy_to_user((char*)arg, &ch->digiext, sizeof(digi_t));
+ if (copy_to_user((char*)arg, &ch->digiext,
+ sizeof(digi_t)))
+ return -EFAULT;
break;
case DIGI_SETAW:
/* Fall Thru */
case DIGI_SETA:
- if ((error =
- verify_area(VERIFY_READ, (char*)arg,sizeof(digi_t))))
- return(error);
-
- copy_from_user(&ch->digiext, (char*)arg, sizeof(digi_t));
+ if (copy_from_user(&ch->digiext, (char*)arg,
+ sizeof(digi_t)))
+ return -EFAULT;
if (ch->digiext.digi_flags & DIGI_ALTPIN)
{
memoff(ch);
restore_flags(flags);
- if ((error = verify_area(VERIFY_WRITE, (char*)arg,sizeof(dflow))))
- return(error);
-
- copy_to_user((char*)arg, &dflow, sizeof(dflow));
+ if (copy_to_user((char*)arg, &dflow, sizeof(dflow)))
+ return -EFAULT;
break;
case DIGI_SETAFLOW:
stopc = ch->stopca;
}
- if ((error = verify_area(VERIFY_READ, (char*)arg,sizeof(dflow))))
- return(error);
-
- copy_from_user(&dflow, (char*)arg, sizeof(dflow));
+ if (copy_from_user(&dflow, (char*)arg, sizeof(dflow)))
+ return -EFAULT;
if (dflow.startc != startc || dflow.stopc != stopc)
{ /* Begin if setflow toggled */
printk("stli_setserial(portp=%x,sp=%x)\n", (int) portp, (int) sp);
#endif
- copy_from_user(&sio, sp, sizeof(struct serial_struct));
+ if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
+ return -EFAULT;
if (!capable(CAP_SYS_ADMIN)) {
if ((sio.baud_base != portp->baud_base) ||
(sio.close_delay != portp->close_delay) ||
while (size > 0) {
memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos);
n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize)));
- copy_to_user(buf, memptr, n);
+ if (copy_to_user(buf, memptr, n)) {
+ count = -EFAULT;
+ goto out;
+ }
fp->f_pos += n;
buf += n;
size -= n;
}
+out:
EBRDDISABLE(brdp);
restore_flags(flags);
while (size > 0) {
memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos);
n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize)));
- copy_from_user(memptr, chbuf, n);
+ if (copy_from_user(memptr, chbuf, n)) {
+ count = -EFAULT;
+ goto out;
+ }
fp->f_pos += n;
chbuf += n;
size -= n;
}
+out:
EBRDDISABLE(brdp);
restore_flags(flags);
static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
- int ret;
-
switch(cmd){
case WDIOC_GETSUPPORT:
- ret = copy_to_user((struct watchdog_info *)arg,
- &zf_info, sizeof(zf_info));
- if(ret)
+ if (copy_to_user((struct watchdog_info *)arg,
+ &zf_info, sizeof(zf_info)))
return -EFAULT;
break;
case WDIOC_GETSTATUS:
- ret = copy_to_user((int *)arg, &zf_is_open,
- sizeof(int));
- if(ret)
+ if (copy_to_user((int *)arg, &zf_is_open, sizeof(int)))
return -EFAULT;
break;
tmp.closing_wait = info->closing_wait;
tmp.custom_divisor = info->custom_divisor;
tmp.hub6 = 0;
- copy_to_user(retinfo, &tmp, sizeof(*retinfo));
- return (0);
+ return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
}
static int mxser_set_serial_info(struct mxser_struct *info,
if (!new_info || !info->base)
return (-EFAULT);
- copy_from_user(&new_serial, new_info, sizeof(new_serial));
+ if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
+ return -EFAULT;
if ((new_serial.irq != info->irq) ||
(new_serial.port != info->base) ||
pHeader->owner = pClient;
}
- copy_from_user (pHeader->data, data, count); /* We already verified this */
+ __copy_from_user(pHeader->data, data, count); /* We already verified this */
if(pInfo->flags & R3964_DEBUG)
{
if (ret == 0) {
ret = count;
*ppos += count;
- }
+ } else
+ ret = -EFAULT;
up(&nwflash_sem);
}
return ret;
/* First, find out which raw minor we want */
- err = copy_from_user(&rq, (void *) arg, sizeof(rq));
- if (err)
+ if (copy_from_user(&rq, (void *) arg, sizeof(rq))) {
+ err = -EFAULT;
break;
+ }
minor = rq.raw_minor;
if (minor <= 0 || minor > MINORMASK) {
rq.block_major = rq.block_minor = 0;
}
err = copy_to_user((void *) arg, &rq, sizeof(rq));
+ if (err)
+ err = -EFAULT;
}
break;
printk("stl_setserial(portp=%x,sp=%x)\n", (int) portp, (int) sp);
#endif
- copy_from_user(&sio, sp, sizeof(struct serial_struct));
+ if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
+ return -EFAULT;
if (!capable(CAP_SYS_ADMIN)) {
if ((sio.baud_base != portp->baud_base) ||
(sio.close_delay != portp->close_delay) ||
stlpanel_t *panelp;
int i;
- copy_from_user(&stl_brdstats, bp, sizeof(combrd_t));
+ if (copy_from_user(&stl_brdstats, bp, sizeof(combrd_t)))
+ return -EFAULT;
if (stl_brdstats.brd >= STL_MAXBRDS)
return(-ENODEV);
brdp = stl_brds[stl_brdstats.brd];
stl_brdstats.panels[i].nrports = panelp->nrports;
}
- copy_to_user(bp, &stl_brdstats, sizeof(combrd_t));
- return(0);
+ return copy_to_user(bp, &stl_brdstats, sizeof(combrd_t)) ? -EFAULT : 0;
}
/*****************************************************************************/
unsigned long flags;
if (portp == (stlport_t *) NULL) {
- copy_from_user(&stl_comstats, cp, sizeof(comstats_t));
+ if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t)))
+ return -EFAULT;
portp = stl_getport(stl_comstats.brd, stl_comstats.panel,
stl_comstats.port);
if (portp == (stlport_t *) NULL)
portp->stats.signals = (unsigned long) stl_getsignals(portp);
- copy_to_user(cp, &portp->stats, sizeof(comstats_t));
- return(0);
+ return copy_to_user(cp, &portp->stats,
+ sizeof(comstats_t)) ? -EFAULT : 0;
}
/*****************************************************************************/
static int stl_clrportstats(stlport_t *portp, comstats_t *cp)
{
if (portp == (stlport_t *) NULL) {
- copy_from_user(&stl_comstats, cp, sizeof(comstats_t));
+ if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t)))
+ return -EFAULT;
portp = stl_getport(stl_comstats.brd, stl_comstats.panel,
stl_comstats.port);
if (portp == (stlport_t *) NULL)
portp->stats.brd = portp->brdnr;
portp->stats.panel = portp->panelnr;
portp->stats.port = portp->portnr;
- copy_to_user(cp, &portp->stats, sizeof(comstats_t));
- return(0);
+ return copy_to_user(cp, &portp->stats,
+ sizeof(comstats_t)) ? -EFAULT : 0;
}
/*****************************************************************************/
{
stlport_t *portp;
- copy_from_user(&stl_dummyport, (void *) arg, sizeof(stlport_t));
+ if (copy_from_user(&stl_dummyport, (void *) arg, sizeof(stlport_t)))
+ return -EFAULT;
portp = stl_getport(stl_dummyport.brdnr, stl_dummyport.panelnr,
stl_dummyport.portnr);
if (portp == (stlport_t *) NULL)
return(-ENODEV);
- copy_to_user((void *) arg, portp, sizeof(stlport_t));
- return(0);
+ return copy_to_user((void *)arg, portp,
+ sizeof(stlport_t)) ? -EFAULT : 0;
}
/*****************************************************************************/
{
stlbrd_t *brdp;
- copy_from_user(&stl_dummybrd, (void *) arg, sizeof(stlbrd_t));
+ if (copy_from_user(&stl_dummybrd, (void *) arg, sizeof(stlbrd_t)))
+ return -EFAULT;
if ((stl_dummybrd.brdnr < 0) || (stl_dummybrd.brdnr >= STL_MAXBRDS))
return(-ENODEV);
brdp = stl_brds[stl_dummybrd.brdnr];
if (brdp == (stlbrd_t *) NULL)
return(-ENODEV);
- copy_to_user((void *) arg, brdp, sizeof(stlbrd_t));
- return(0);
+ return copy_to_user((void *)arg, brdp, sizeof(stlbrd_t)) ? -EFAULT : 0;
}
/*****************************************************************************/
Get_user (data, descr++);
while (nbytes && data) {
for (i=0;i<nbytes;i += SX_CHUNK_SIZE) {
- copy_from_user (tmp, (char *)data+i,
- (i+SX_CHUNK_SIZE>nbytes)?nbytes-i:SX_CHUNK_SIZE);
+ if (copy_from_user(tmp, (char *)data + i,
+ (i + SX_CHUNK_SIZE >
+ nbytes) ? nbytes - i :
+ SX_CHUNK_SIZE))
+ return -EFAULT;
memcpy_toio ((char *) (board->base2 + offset + i), tmp,
(i+SX_CHUNK_SIZE>nbytes)?nbytes-i:SX_CHUNK_SIZE);
}
}
/* copy buffer to user-space in one go */
if (bytes_done > 0) {
- err =
- copy_to_user(buf, buffaddr,
- bytes_done);
- if (err) {
+ if (copy_to_user(buf, buffaddr, bytes_done))
return -EFAULT;
- }
}
#if 1
/* Checks Ton's patch below */
/* copy from user to DMA buffer and initiate transfer. */
if (bytes_todo > 0) {
- err = copy_from_user(buffaddr, buf, bytes_todo);
- if (err) {
+ if (copy_from_user(buffaddr, buf, bytes_todo))
return -EFAULT;
- }
/****************** similar problem with read() at FM could happen here at EOT.
******************/