Commit 3ffa0b66 authored by Robert Love's avatar Robert Love Committed by Linus Torvalds

[PATCH] 2.5.4-pre1: further llseek cleanup (3/3)

The previous patch did not provide protection for device lseek methods
(drivers/* stuff).  This patch pushes the BKL into each of the remaining
lseek methods -- without them we have a race.

I'd much prefer to have a a better lock to push down than the BKL, but
that will have to wait.

Before you balk at the size, remember patch #2 in this series which
removed much code ;-)

Thanks to Al for assistance, especially a listing of affected files.

	Robert Love
parent a0289e82
...@@ -74,6 +74,7 @@ ...@@ -74,6 +74,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "i2c.h" #include "i2c.h"
...@@ -448,36 +449,39 @@ static loff_t eeprom_lseek(struct file * file, loff_t offset, int orig) ...@@ -448,36 +449,39 @@ static loff_t eeprom_lseek(struct file * file, loff_t offset, int orig)
* orig 1: relative from current position * orig 1: relative from current position
* orig 2: position from last eeprom address * orig 2: position from last eeprom address
*/ */
loff_t ret;
lock_kernel();
switch (orig) switch (orig)
{ {
case 0: case 0:
file->f_pos = offset; ret = file->f_pos = offset;
break; break;
case 1: case 1:
file->f_pos += offset; ret = file->f_pos += offset;
break; break;
case 2: case 2:
file->f_pos = eeprom.size - offset; ret = file->f_pos = eeprom.size - offset;
break; break;
default: default:
return -EINVAL; ret = -EINVAL;
} }
/* truncate position */ /* truncate position */
if (file->f_pos < 0) if (file->f_pos < 0)
{ {
file->f_pos = 0; file->f_pos = 0;
return(-EOVERFLOW); unlock_kernel();
ret = -EOVERFLOW;
} }
if (file->f_pos >= eeprom.size) if (file->f_pos >= eeprom.size)
{ {
file->f_pos = eeprom.size - 1; file->f_pos = eeprom.size - 1;
return(-EOVERFLOW); ret = -EOVERFLOW;
} }
return ( file->f_pos ); return ( ret );
} }
/* Reads data from eeprom. */ /* Reads data from eeprom. */
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/major.h> #include <linux/major.h>
#include <linux/smp_lock.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/msr.h> #include <asm/msr.h>
...@@ -82,16 +83,24 @@ static inline void do_cpuid(int cpu, u32 reg, u32 *data) ...@@ -82,16 +83,24 @@ static inline void do_cpuid(int cpu, u32 reg, u32 *data)
static loff_t cpuid_seek(struct file *file, loff_t offset, int orig) static loff_t cpuid_seek(struct file *file, loff_t offset, int orig)
{ {
loff_t ret;
lock_kernel();
switch (orig) { switch (orig) {
case 0: case 0:
file->f_pos = offset; file->f_pos = offset;
return file->f_pos; ret = file->f_pos;
break;
case 1: case 1:
file->f_pos += offset; file->f_pos += offset;
return file->f_pos; ret = file->f_pos;
default: default:
return -EINVAL; /* SEEK_END not supported */ ret = -EINVAL;
} }
unlock_kernel();
return ret;
} }
static ssize_t cpuid_read(struct file * file, char * buf, static ssize_t cpuid_read(struct file * file, char * buf,
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/major.h> #include <linux/major.h>
#include <asm/processor.h> #include <asm/processor.h>
...@@ -162,16 +163,19 @@ static inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx) ...@@ -162,16 +163,19 @@ static inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx)
static loff_t msr_seek(struct file *file, loff_t offset, int orig) static loff_t msr_seek(struct file *file, loff_t offset, int orig)
{ {
loff_t ret = -EINVAL;
lock_kernel();
switch (orig) { switch (orig) {
case 0: case 0:
file->f_pos = offset; file->f_pos = offset;
return file->f_pos; ret = file->f_pos;
break;
case 1: case 1:
file->f_pos += offset; file->f_pos += offset;
return file->f_pos; ret = file->f_pos;
default:
return -EINVAL; /* SEEK_END not supported */
} }
unlock_kernel();
return ret;
} }
static ssize_t msr_read(struct file * file, char * buf, static ssize_t msr_read(struct file * file, char * buf,
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/sysctl.h> #include <linux/sysctl.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/threads.h> #include <linux/threads.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/bitops.h> #include <asm/bitops.h>
...@@ -430,18 +431,20 @@ static ssize_t ppc_htab_write(struct file * file, const char * buffer, ...@@ -430,18 +431,20 @@ static ssize_t ppc_htab_write(struct file * file, const char * buffer,
static long long static long long
ppc_htab_lseek(struct file * file, loff_t offset, int orig) ppc_htab_lseek(struct file * file, loff_t offset, int orig)
{ {
long long ret = -EINVAL;
lock_kernel();
switch (orig) { switch (orig) {
case 0: case 0:
file->f_pos = offset; file->f_pos = offset;
return(file->f_pos); ret = file->f_pos;
break;
case 1: case 1:
file->f_pos += offset; file->f_pos += offset;
return(file->f_pos); ret = file->f_pos;
case 2:
return(-EINVAL);
default:
return(-EINVAL);
} }
unlock_kernel();
return ret;
} }
int proc_dol2crvec(ctl_table *table, int write, struct file *filp, int proc_dol2crvec(ctl_table *table, int write, struct file *filp,
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/raw.h> #include <linux/raw.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/capability.h> #include <linux/capability.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -466,16 +467,23 @@ static loff_t null_lseek(struct file * file, loff_t offset, int orig) ...@@ -466,16 +467,23 @@ static loff_t null_lseek(struct file * file, loff_t offset, int orig)
*/ */
static loff_t memory_lseek(struct file * file, loff_t offset, int orig) static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
{ {
int ret;
lock_kernel();
switch (orig) { switch (orig) {
case 0: case 0:
file->f_pos = offset; file->f_pos = offset;
return file->f_pos; ret = file->f_pos;
break;
case 1: case 1:
file->f_pos += offset; file->f_pos += offset;
return file->f_pos; ret = file->f_pos;
break;
default: default:
return -EINVAL; ret = -EINVAL;
} }
unlock_kernel();
return ret;
} }
static int open_port(struct inode * inode, struct file * filp) static int open_port(struct inode * inode, struct file * filp)
......
...@@ -216,6 +216,7 @@ void nvram_set_checksum( void ) ...@@ -216,6 +216,7 @@ void nvram_set_checksum( void )
static long long nvram_llseek(struct file *file,loff_t offset, int origin ) static long long nvram_llseek(struct file *file,loff_t offset, int origin )
{ {
lock_kernel();
switch( origin ) { switch( origin ) {
case 0: case 0:
/* nothing to do */ /* nothing to do */
...@@ -227,6 +228,7 @@ static long long nvram_llseek(struct file *file,loff_t offset, int origin ) ...@@ -227,6 +228,7 @@ static long long nvram_llseek(struct file *file,loff_t offset, int origin )
offset += NVRAM_BYTES; offset += NVRAM_BYTES;
break; break;
} }
unlock_kernel();
return( (offset >= 0) ? (file->f_pos = offset) : -EINVAL ); return( (offset >= 0) ? (file->f_pos = offset) : -EINVAL );
} }
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/rwsem.h> #include <linux/rwsem.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/smp_lock.h>
#include <asm/hardware/dec21285.h> #include <asm/hardware/dec21285.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -301,30 +302,45 @@ static ssize_t flash_write(struct file *file, const char *buf, size_t size, loff ...@@ -301,30 +302,45 @@ static ssize_t flash_write(struct file *file, const char *buf, size_t size, loff
*/ */
static long long flash_llseek(struct file *file, long long offset, int orig) static long long flash_llseek(struct file *file, long long offset, int orig)
{ {
long long ret;
lock_kernel();
if (flashdebug) if (flashdebug)
printk(KERN_DEBUG "flash_llseek: offset=0x%X, orig=0x%X.\n", printk(KERN_DEBUG "flash_llseek: offset=0x%X, orig=0x%X.\n",
(unsigned int) offset, orig); (unsigned int) offset, orig);
switch (orig) { switch (orig) {
case 0: case 0:
if (offset < 0) if (offset < 0) {
return -EINVAL; ret = -EINVAL;
break;
}
if ((unsigned int) offset > gbFlashSize) if ((unsigned int) offset > gbFlashSize) {
return -EINVAL; ret = -EINVAL;
break;
}
file->f_pos = (unsigned int) offset; file->f_pos = (unsigned int) offset;
return file->f_pos; ret = file->f_pos;
break;
case 1: case 1:
if ((file->f_pos + offset) > gbFlashSize) if ((file->f_pos + offset) > gbFlashSize) {
return -EINVAL; ret = -EINVAL;
if ((file->f_pos + offset) < 0) break;
return -EINVAL; }
if ((file->f_pos + offset) < 0) {
ret = -EINVAL;
break;
}
file->f_pos += offset; file->f_pos += offset;
return file->f_pos; ret = file->f_pos;
break;
default: default:
return -EINVAL; ret = -EINVAL;
} }
unlock_kernel();
return ret;
} }
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/selection.h> #include <linux/selection.h>
#include <linux/kbd_kern.h> #include <linux/kbd_kern.h>
#include <linux/console.h> #include <linux/console.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
...@@ -67,10 +68,13 @@ vcs_size(struct inode *inode) ...@@ -67,10 +68,13 @@ vcs_size(struct inode *inode)
static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
{ {
int size = vcs_size(file->f_dentry->d_inode); int size;
lock_kernel();
size = vcs_size(file->f_dentry->d_inode);
switch (orig) { switch (orig) {
default: default:
unlock_kernel();
return -EINVAL; return -EINVAL;
case 2: case 2:
offset += size; offset += size;
...@@ -80,9 +84,12 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) ...@@ -80,9 +84,12 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
case 0: case 0:
break; break;
} }
if (offset < 0 || offset > size) if (offset < 0 || offset > size) {
unlock_kernel();
return -EINVAL; return -EINVAL;
}
file->f_pos = offset; file->f_pos = offset;
unlock_kernel();
return file->f_pos; return file->f_pos;
} }
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/smp_lock.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -732,8 +733,9 @@ static unsigned int aux_poll(struct file *file, poll_table *pt) ...@@ -732,8 +733,9 @@ static unsigned int aux_poll(struct file *file, poll_table *pt)
loff_t mem_llseek(struct file *file, loff_t offs, int orig) loff_t mem_llseek(struct file *file, loff_t offs, int orig)
{ {
loff_t newoffs; loff_t newoffs = -1;
lock_kernel();
switch (orig) { switch (orig) {
case 0: case 0:
newoffs = offs; newoffs = offs;
...@@ -743,12 +745,12 @@ loff_t mem_llseek(struct file *file, loff_t offs, int orig) ...@@ -743,12 +745,12 @@ loff_t mem_llseek(struct file *file, loff_t offs, int orig)
break; break;
case 2: case 2:
newoffs = PCILYNX_MAX_MEMORY + 1 + offs; newoffs = PCILYNX_MAX_MEMORY + 1 + offs;
break;
default:
return -EINVAL;
} }
if (newoffs < 0 || newoffs > PCILYNX_MAX_MEMORY + 1) return -EINVAL; if (newoffs < 0 || newoffs > PCILYNX_MAX_MEMORY + 1) {
lock_kernel();
return -EINVAL;
}
file->f_pos = newoffs; file->f_pos = newoffs;
return newoffs; return newoffs;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <linux/nvram.h> #include <linux/nvram.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/nvram.h> #include <asm/nvram.h>
...@@ -20,6 +21,7 @@ ...@@ -20,6 +21,7 @@
static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
{ {
lock_kernel();
switch (origin) { switch (origin) {
case 1: case 1:
offset += file->f_pos; offset += file->f_pos;
...@@ -28,9 +30,12 @@ static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) ...@@ -28,9 +30,12 @@ static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
offset += NVRAM_SIZE; offset += NVRAM_SIZE;
break; break;
} }
if (offset < 0) if (offset < 0) {
unlock_kernel();
return -EINVAL; return -EINVAL;
}
file->f_pos = offset; file->f_pos = offset;
unlock_kernel();
return file->f_pos; return file->f_pos;
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/smp_lock.h>
#include <linux/slab.h> #include <linux/slab.h>
#ifdef CONFIG_DEVFS_FS #ifdef CONFIG_DEVFS_FS
...@@ -31,6 +32,7 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig) ...@@ -31,6 +32,7 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
{ {
struct mtd_info *mtd=(struct mtd_info *)file->private_data; struct mtd_info *mtd=(struct mtd_info *)file->private_data;
lock_kernel();
switch (orig) { switch (orig) {
case 0: case 0:
/* SEEK_SET */ /* SEEK_SET */
...@@ -45,6 +47,7 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig) ...@@ -45,6 +47,7 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
file->f_pos =mtd->size + offset; file->f_pos =mtd->size + offset;
break; break;
default: default:
unlock_kernel();
return -EINVAL; return -EINVAL;
} }
...@@ -53,6 +56,7 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig) ...@@ -53,6 +56,7 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
else if (file->f_pos >= mtd->size) else if (file->f_pos >= mtd->size)
file->f_pos = mtd->size - 1; file->f_pos = mtd->size - 1;
unlock_kernel();
return file->f_pos; return file->f_pos;
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
...@@ -21,8 +22,9 @@ ...@@ -21,8 +22,9 @@
static loff_t static loff_t
proc_bus_pci_lseek(struct file *file, loff_t off, int whence) proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
{ {
loff_t new; loff_t new = -1;
lock_kernel();
switch (whence) { switch (whence) {
case 0: case 0:
new = off; new = off;
...@@ -33,9 +35,8 @@ proc_bus_pci_lseek(struct file *file, loff_t off, int whence) ...@@ -33,9 +35,8 @@ proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
case 2: case 2:
new = PCI_CFG_SPACE_SIZE + off; new = PCI_CFG_SPACE_SIZE + off;
break; break;
default:
return -EINVAL;
} }
unlock_kernel();
if (new < 0 || new > PCI_CFG_SPACE_SIZE) if (new < 0 || new > PCI_CFG_SPACE_SIZE)
return -EINVAL; return -EINVAL;
return (file->f_pos = new); return (file->f_pos = new);
......
...@@ -84,18 +84,26 @@ static void isapnp_devid(char *str, unsigned short vendor, unsigned short device ...@@ -84,18 +84,26 @@ static void isapnp_devid(char *str, unsigned short vendor, unsigned short device
static loff_t isapnp_info_entry_lseek(struct file *file, loff_t offset, int orig) static loff_t isapnp_info_entry_lseek(struct file *file, loff_t offset, int orig)
{ {
loff_t ret;
lock_kernel();
switch (orig) { switch (orig) {
case 0: /* SEEK_SET */ case 0: /* SEEK_SET */
file->f_pos = offset; file->f_pos = offset;
return file->f_pos; ret = file->f_pos;
break;
case 1: /* SEEK_CUR */ case 1: /* SEEK_CUR */
file->f_pos += offset; file->f_pos += offset;
return file->f_pos; ret = file->f_pos;
break;
case 2: /* SEEK_END */ case 2: /* SEEK_END */
default: default:
return -EINVAL; ret = -EINVAL;
} }
return -ENXIO;
unlock_kernel();
return ret;
} }
static ssize_t isapnp_info_entry_read(struct file *file, char *buffer, static ssize_t isapnp_info_entry_read(struct file *file, char *buffer,
...@@ -211,8 +219,9 @@ static struct file_operations isapnp_info_entry_operations = ...@@ -211,8 +219,9 @@ static struct file_operations isapnp_info_entry_operations =
static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence) static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence)
{ {
loff_t new; loff_t new = -1;
lock_kernel();
switch (whence) { switch (whence) {
case 0: case 0:
new = off; new = off;
...@@ -223,11 +232,12 @@ static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence) ...@@ -223,11 +232,12 @@ static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence)
case 2: case 2:
new = 256 + off; new = 256 + off;
break; break;
default:
return -EINVAL;
} }
if (new < 0 || new > 256) if (new < 0 || new > 256) {
unlock_kernel();
return -EINVAL; return -EINVAL;
}
unlock_kernel();
return (file->f_pos = new); return (file->f_pos = new);
} }
......
...@@ -83,6 +83,7 @@ flash_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -83,6 +83,7 @@ flash_mmap(struct file *file, struct vm_area_struct *vma)
static long long static long long
flash_llseek(struct file *file, long long offset, int origin) flash_llseek(struct file *file, long long offset, int origin)
{ {
lock_kernel();
switch (origin) { switch (origin) {
case 0: case 0:
file->f_pos = offset; file->f_pos = offset;
...@@ -96,8 +97,10 @@ flash_llseek(struct file *file, long long offset, int origin) ...@@ -96,8 +97,10 @@ flash_llseek(struct file *file, long long offset, int origin)
file->f_pos = flash.read_size; file->f_pos = flash.read_size;
break; break;
default: default:
unlock_kernel();
return -EINVAL; return -EINVAL;
} }
unlock_kernel();
return file->f_pos; return file->f_pos;
} }
......
...@@ -259,16 +259,23 @@ static void jsfd_do_request(request_queue_t *q) ...@@ -259,16 +259,23 @@ static void jsfd_do_request(request_queue_t *q)
*/ */
static loff_t jsf_lseek(struct file * file, loff_t offset, int orig) static loff_t jsf_lseek(struct file * file, loff_t offset, int orig)
{ {
loff_t ret;
lock_kernel();
switch (orig) { switch (orig) {
case 0: case 0:
file->f_pos = offset; file->f_pos = offset;
return file->f_pos; ret = file->f_pos;
break;
case 1: case 1:
file->f_pos += offset; file->f_pos += offset;
return file->f_pos; ret = file->f_pos;
break;
default: default:
return -EINVAL; ret = -EINVAL;
} }
unlock_kernel();
return ret;
} }
/* /*
......
...@@ -554,21 +554,26 @@ static int usb_device_release(struct inode *inode, struct file *file) ...@@ -554,21 +554,26 @@ static int usb_device_release(struct inode *inode, struct file *file)
static loff_t usb_device_lseek(struct file * file, loff_t offset, int orig) static loff_t usb_device_lseek(struct file * file, loff_t offset, int orig)
{ {
loff_t ret;
lock_kernel();
switch (orig) { switch (orig) {
case 0: case 0:
file->f_pos = offset; file->f_pos = offset;
return file->f_pos; ret = file->f_pos;
break;
case 1: case 1:
file->f_pos += offset; file->f_pos += offset;
return file->f_pos; ret = file->f_pos;
break;
case 2: case 2:
return -EINVAL;
default: default:
return -EINVAL; ret = -EINVAL;
} }
unlock_kernel();
return ret;
} }
struct file_operations usbdevfs_devices_fops = { struct file_operations usbdevfs_devices_fops = {
......
...@@ -58,21 +58,26 @@ struct async { ...@@ -58,21 +58,26 @@ struct async {
static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig) static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig)
{ {
loff_t ret;
lock_kernel();
switch (orig) { switch (orig) {
case 0: case 0:
file->f_pos = offset; file->f_pos = offset;
return file->f_pos; ret = file->f_pos;
break;
case 1: case 1:
file->f_pos += offset; file->f_pos += offset;
return file->f_pos; ret = file->f_pos;
break;
case 2: case 2:
return -EINVAL;
default: default:
return -EINVAL; ret = -EINVAL;
} }
unlock_kernel();
return ret;
} }
static ssize_t usbdev_read(struct file *file, char * buf, size_t nbytes, loff_t *ppos) static ssize_t usbdev_read(struct file *file, char * buf, size_t nbytes, loff_t *ppos)
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/usbdevice_fs.h> #include <linux/usbdevice_fs.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
/*****************************************************************/ /*****************************************************************/
...@@ -96,21 +97,24 @@ static ssize_t usb_driver_read(struct file *file, char *buf, size_t nbytes, loff ...@@ -96,21 +97,24 @@ static ssize_t usb_driver_read(struct file *file, char *buf, size_t nbytes, loff
static loff_t usb_driver_lseek(struct file * file, loff_t offset, int orig) static loff_t usb_driver_lseek(struct file * file, loff_t offset, int orig)
{ {
loff_t ret;
lock_kernel();
switch (orig) { switch (orig) {
case 0: case 0:
file->f_pos = offset; file->f_pos = offset;
return file->f_pos; ret = file->f_pos;
break;
case 1: case 1:
file->f_pos += offset; file->f_pos += offset;
return file->f_pos; ret = file->f_pos;
break;
case 2: case 2:
return -EINVAL;
default: default:
return -EINVAL; ret = -EINVAL;
} }
unlock_kernel();
return ret;
} }
struct file_operations usbdevfs_drivers_fops = { struct file_operations usbdevfs_drivers_fops = {
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/usbdevice_fs.h> #include <linux/usbdevice_fs.h>
#include <linux/smp_lock.h>
static struct super_operations usbfs_ops; static struct super_operations usbfs_ops;
static struct address_space_operations usbfs_aops; static struct address_space_operations usbfs_aops;
...@@ -295,6 +295,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig) ...@@ -295,6 +295,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
{ {
loff_t retval = -EINVAL; loff_t retval = -EINVAL;
lock_kernel();
switch(orig) { switch(orig) {
case 0: case 0:
if (offset > 0) { if (offset > 0) {
...@@ -311,6 +312,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig) ...@@ -311,6 +312,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
default: default:
break; break;
} }
unlock_kernel();
return retval; return retval;
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/smp_lock.h>
#include <asm/io.h> #include <asm/io.h>
#include "uhci.h" #include "uhci.h"
...@@ -507,8 +508,11 @@ static int uhci_proc_open(struct inode *inode, struct file *file) ...@@ -507,8 +508,11 @@ static int uhci_proc_open(struct inode *inode, struct file *file)
static loff_t uhci_proc_lseek(struct file *file, loff_t off, int whence) static loff_t uhci_proc_lseek(struct file *file, loff_t off, int whence)
{ {
struct uhci_proc *up = file->private_data; struct uhci_proc *up;
loff_t new; loff_t new = -1;
lock_kernel();
up = file->private_data;
switch (whence) { switch (whence) {
case 0: case 0:
...@@ -517,12 +521,12 @@ static loff_t uhci_proc_lseek(struct file *file, loff_t off, int whence) ...@@ -517,12 +521,12 @@ static loff_t uhci_proc_lseek(struct file *file, loff_t off, int whence)
case 1: case 1:
new = file->f_pos + off; new = file->f_pos + off;
break; break;
case 2:
default:
return -EINVAL;
} }
if (new < 0 || new > up->size) if (new < 0 || new > up->size) {
unlock_kernel();
return -EINVAL; return -EINVAL;
}
unlock_kernel();
return (file->f_pos = new); return (file->f_pos = new);
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/zorro.h> #include <linux/zorro.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/amigahw.h> #include <asm/amigahw.h>
#include <asm/setup.h> #include <asm/setup.h>
...@@ -21,7 +22,7 @@ ...@@ -21,7 +22,7 @@
static loff_t static loff_t
proc_bus_zorro_lseek(struct file *file, loff_t off, int whence) proc_bus_zorro_lseek(struct file *file, loff_t off, int whence)
{ {
loff_t new; loff_t new = -1;
switch (whence) { switch (whence) {
case 0: case 0:
...@@ -33,11 +34,12 @@ proc_bus_zorro_lseek(struct file *file, loff_t off, int whence) ...@@ -33,11 +34,12 @@ proc_bus_zorro_lseek(struct file *file, loff_t off, int whence)
case 2: case 2:
new = sizeof(struct ConfigDev) + off; new = sizeof(struct ConfigDev) + off;
break; break;
default:
return -EINVAL;
} }
if (new < 0 || new > sizeof(struct ConfigDev)) if (new < 0 || new > sizeof(struct ConfigDev)) {
unlock_kernel();
return -EINVAL; return -EINVAL;
}
unlock_kernel();
return (file->f_pos = new); return (file->f_pos = new);
} }
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -341,6 +342,7 @@ driverfs_file_lseek(struct file *file, loff_t offset, int orig) ...@@ -341,6 +342,7 @@ driverfs_file_lseek(struct file *file, loff_t offset, int orig)
{ {
loff_t retval = -EINVAL; loff_t retval = -EINVAL;
lock_kernel();
switch(orig) { switch(orig) {
case 0: case 0:
if (offset > 0) { if (offset > 0) {
...@@ -357,6 +359,7 @@ driverfs_file_lseek(struct file *file, loff_t offset, int orig) ...@@ -357,6 +359,7 @@ driverfs_file_lseek(struct file *file, loff_t offset, int orig)
default: default:
break; break;
} }
unlock_kernel();
return retval; return retval;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment