Bugzilla – Attachment 21767 Details for
Bug 56074
VUL-0: CVE-2004-0415: kernel: /proc info leak
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
IDP Log In
|
Forgot Password
[patch]
preliminary, from Al Viro, against 2.4 kernels.
proc-info-leak-preliminary-patch-2.4.diff (text/plain), 95.75 KB, created by
Roman Drahtmueller
on 2004-06-29 18:13:54 UTC
(
hide
)
Description:
preliminary, from Al Viro, against 2.4 kernels.
Filename:
MIME Type:
Creator:
Roman Drahtmueller
Created:
2004-06-29 18:13:54 UTC
Size:
95.75 KB
patch
obsolete
>From viro@parcelfarce.linux.theplanet.co.uk Tue Jun 29 12:13:10 2004 >From: viro@parcelfarce.linux.theplanet.co.uk >To: vendor-sec@lst.de >Date: Tue, 29 Jun 2004 09:36:45 +0100 >Subject: [vendor-sec] 2.4 preliminary patch for read/write/lseek crap (aka > "signedness issues") > > *NOTE* *NOTE* *NOTE* - that is *NOT* against 2.4-latest and would >require porting and probably extra bits for new method instances to be >used for 2.4.27. Hopefully would be a useful starting point, though. > > Patch below is for 2.4.21-based tree we have for RHEL3. For all >practical purposes it should be considered as untested, obviously. That >any corrections would be welcome also goes without saying... > >diff -urN linux-2.4.21/arch/cris/drivers/eeprom.c linux-2.4.21-fix/arch/cris/drivers/eeprom.c >--- linux-2.4.21/arch/cris/drivers/eeprom.c 2003-06-13 10:51:29.000000000 -0400 >+++ linux-2.4.21-fix/arch/cris/drivers/eeprom.c 2004-06-28 17:01:05.000000000 -0400 >@@ -494,7 +494,7 @@ > static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t *off) > { > int i, read=0; >- unsigned long p = file->f_pos; >+ unsigned long p = *off; > > unsigned char page; > >@@ -528,7 +528,7 @@ > return -EFAULT; > } > >- if( (p + count) > eeprom.size) >+ if (count > eeprom.size - p) > { > /* truncate count */ > count = eeprom.size - p; >@@ -548,7 +548,7 @@ > > if(read > 0) > { >- file->f_pos += read; >+ *off = p + read; > } > > eeprom.busy--; >@@ -593,7 +593,7 @@ > { > restart = 0; > written = 0; >- p = file->f_pos; >+ p = *off; > > > while( (written < count) && (p < eeprom.size)) >@@ -721,10 +721,10 @@ > > eeprom.busy--; > wake_up_interruptible(&eeprom.wait_q); >- if (written == 0 && file->f_pos >= eeprom.size){ >+ if (written == 0 && p >= eeprom.size){ > return -ENOSPC; > } >- file->f_pos += written; >+ *off = p; > return written; > } > >diff -urN linux-2.4.21/arch/i386/kernel/mtrr.c linux-2.4.21-fix/arch/i386/kernel/mtrr.c >--- linux-2.4.21/arch/i386/kernel/mtrr.c 2003-06-13 10:51:29.000000000 -0400 >+++ linux-2.4.21-fix/arch/i386/kernel/mtrr.c 2004-06-28 17:01:05.000000000 -0400 >@@ -1648,11 +1648,16 @@ > static ssize_t mtrr_read (struct file *file, char *buf, size_t len, > loff_t *ppos) > { >- if (*ppos >= ascii_buf_bytes) return 0; >- if (*ppos + len > ascii_buf_bytes) len = ascii_buf_bytes - *ppos; >- if ( copy_to_user (buf, ascii_buffer + *ppos, len) ) return -EFAULT; >- *ppos += len; >- return len; >+ loff_t pos = *ppos; >+ if (pos < 0 || pos >= ascii_buf_bytes) >+ return 0; >+ if (len > ascii_buf_bytes - pos) >+ len = ascii_buf_bytes - pos; >+ if (copy_to_user(buf, ascii_buffer + pos, len)) >+ return -EFAULT; >+ pos += len; >+ *ppos = pos; >+ return len; > } /* End Function mtrr_read */ > > static ssize_t mtrr_write (struct file *file, const char *buf, size_t len, >diff -urN linux-2.4.21/arch/ia64/kernel/efivars.c linux-2.4.21-fix/arch/ia64/kernel/efivars.c >--- linux-2.4.21/arch/ia64/kernel/efivars.c 2004-06-28 16:34:44.000000000 -0400 >+++ linux-2.4.21-fix/arch/ia64/kernel/efivars.c 2004-06-28 17:01:05.000000000 -0400 >@@ -352,6 +352,7 @@ > efi_sys_table_read(struct file *file, char *buffer, size_t count, loff_t *ppos) > { > void *data; >+ loff_t pos = *ppos; > > ssize_t size; > int max_nr_entries = 7; /* num ptrs to tables we could expose */ >@@ -381,18 +382,18 @@ > if( efi.boot_info > 0 ) > length += sprintf(proc_buffer+length, "BootInfo=0x%lx\n", __pa(efi.boot_info)); > >- if( *ppos >= length ) >+ if (pos != (unsigned)pos || pos >= length) > return 0; > >- data = (u8 *) proc_buffer + file->f_pos; >- size = length - file->f_pos; >+ data = (u8 *) proc_buffer + pos; >+ size = length - pos; > if (size > count) > size = count; > if (copy_to_user(buffer, data, size)) > return -EFAULT; > > kfree(proc_buffer); >- *ppos += size; >+ *ppos = pos + size; > return size; > } > >diff -urN linux-2.4.21/arch/ia64/kernel/salinfo.c linux-2.4.21-fix/arch/ia64/kernel/salinfo.c >--- linux-2.4.21/arch/ia64/kernel/salinfo.c 2004-06-28 16:34:46.000000000 -0400 >+++ linux-2.4.21-fix/arch/ia64/kernel/salinfo.c 2004-06-28 17:04:09.000000000 -0400 >@@ -475,6 +475,7 @@ > size_t size; > u8 *buf; > u64 bufsize; >+ loff_t pos = *ppos; > > if (data->state == STATE_LOG_RECORD) { > buf = data->log_buffer; >@@ -486,17 +487,17 @@ > buf = NULL; > bufsize = 0; > } >- if (*ppos >= bufsize) >+ if (pos != (unsigned)pos || pos >= bufsize) > return 0; > >- saldata = buf + file->f_pos; >- size = bufsize - file->f_pos; >+ saldata = buf + pos; >+ size = bufsize - pos; > if (size > count) > size = count; > if (copy_to_user(buffer, saldata, size)) > return -EFAULT; > >- *ppos += size; >+ *ppos = pos + size; > return size; > } > >diff -urN linux-2.4.21/arch/mips/sibyte/sb1250/bcm1250_tbprof.c linux-2.4.21-fix/arch/mips/sibyte/sb1250/bcm1250_tbprof.c >--- linux-2.4.21/arch/mips/sibyte/sb1250/bcm1250_tbprof.c 2002-11-28 18:53:10.000000000 -0500 >+++ linux-2.4.21-fix/arch/mips/sibyte/sb1250/bcm1250_tbprof.c 2004-06-28 17:01:05.000000000 -0400 >@@ -284,7 +284,9 @@ > char *dest = buf; > long cur_off = *offp; > >- count = 0; >+ if (cur_off < 0) >+ return -EINVAL; >+ > cur_sample = cur_off / TB_SAMPLE_SIZE; > sample_off = cur_off % TB_SAMPLE_SIZE; > sample_left = TB_SAMPLE_SIZE - sample_off; >diff -urN linux-2.4.21/arch/ppc/kernel/ppc_htab.c linux-2.4.21-fix/arch/ppc/kernel/ppc_htab.c >--- linux-2.4.21/arch/ppc/kernel/ppc_htab.c 2003-06-13 10:51:31.000000000 -0400 >+++ linux-2.4.21-fix/arch/ppc/kernel/ppc_htab.c 2004-06-28 17:01:05.000000000 -0400 >@@ -112,6 +112,7 @@ > size_t count, loff_t *ppos) > { > unsigned long mmcr0 = 0, pmc1 = 0, pmc2 = 0; >+ loff_t pos = *ppos; > int n = 0; > #ifdef CONFIG_PPC_STD_MMU > int valid; >@@ -213,14 +214,14 @@ > "Non-error misses: %lu\n" > "Error misses\t: %lu\n", > pte_misses, pte_errors); >- if (*ppos >= strlen(buffer)) >+ if (pos != (unsigned)pos || pos >= strlen(buffer)) > return 0; >- if (n > strlen(buffer) - *ppos) >- n = strlen(buffer) - *ppos; >+ if (n > strlen(buffer) - pos) >+ n = strlen(buffer) - pos; > if (n > count) > n = count; >- copy_to_user(buf, buffer + *ppos, n); >- *ppos += n; >+ copy_to_user(buf, buffer + pos, n); >+ *ppos = pos + n; > return n; > } > >diff -urN linux-2.4.21/arch/ppc/platforms/proc_rtas.c linux-2.4.21-fix/arch/ppc/platforms/proc_rtas.c >--- linux-2.4.21/arch/ppc/platforms/proc_rtas.c 2003-06-13 10:51:31.000000000 -0400 >+++ linux-2.4.21-fix/arch/ppc/platforms/proc_rtas.c 2004-06-28 17:01:05.000000000 -0400 >@@ -261,18 +261,19 @@ > size_t count, loff_t *ppos) > { > int n; >+ loff_t pos = *ppos; > if (power_on_time == 0) > n = sprintf(buf, "Power on time not set\n"); > else > n = sprintf(buf, "%lu\n", power_on_time); > >- if (*ppos >= strlen(buf)) >+ if (pos != (unsigned)pos || pos >= strlen(buf)) > return 0; >- if (n > strlen(buf) - *ppos) >- n = strlen(buf) - *ppos; >+ if (n > strlen(buf) - pos) >+ n = strlen(buf) - pos; > if (n > count) > n = count; >- *ppos += n; >+ *ppos = pos + n; > return n; > } > >@@ -298,15 +299,16 @@ > size_t count, loff_t *ppos) > { > int n = 0; >+ loff_t pos = *ppos; > if (progress_led != NULL) > n = sprintf (buf, "%s\n", progress_led); >- if (*ppos >= strlen(buf)) >+ if (pos != (unsigned)pos || pos >= strlen(buf)) > return 0; >- if (n > strlen(buf) - *ppos) >- n = strlen(buf) - *ppos; >+ if (n > strlen(buf) - pos) >+ n = strlen(buf) - pos; > if (n > count) > n = count; >- *ppos += n; >+ *ppos = pos + n; > return n; > } > >@@ -342,6 +344,7 @@ > { > unsigned int year, mon, day, hour, min, sec; > unsigned long *ret = kmalloc(4*8, GFP_KERNEL); >+ loff_t pos = *ppos; > int n, error; > > error = call_rtas("get-time-of-day", 0, 8, ret); >@@ -358,13 +361,13 @@ > } > kfree(ret); > >- if (*ppos >= strlen(buf)) >+ if (pos != (unsigned)pos || pos >= strlen(buf)) > return 0; >- if (n > strlen(buf) - *ppos) >- n = strlen(buf) - *ppos; >+ if (n > strlen(buf) - pos) >+ n = strlen(buf) - pos; > if (n > count) > n = count; >- *ppos += n; >+ *ppos = pos + n; > return n; > } > >@@ -729,16 +732,16 @@ > static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf, > size_t count, loff_t *ppos) > { >- int n; >- n = sprintf(buf, "%lu\n", rtas_tone_frequency); >+ int n = sprintf(buf, "%lu\n", rtas_tone_frequency); >+ loff_t pos = *ppos; > >- if (*ppos >= strlen(buf)) >+ if (pos != (unsigned)pos || pos >= strlen(buf)) > return 0; >- if (n > strlen(buf) - *ppos) >- n = strlen(buf) - *ppos; >+ if (n > strlen(buf) - pos) >+ n = strlen(buf) - pos; > if (n > count) > n = count; >- *ppos += n; >+ *ppos = pos + n; > return n; > } > /* ****************************************************************** */ >@@ -770,15 +773,16 @@ > static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf, > size_t count, loff_t *ppos) > { >- int n; >- n = sprintf(buf, "%lu\n", rtas_tone_volume); >+ int n = sprintf(buf, "%lu\n", rtas_tone_volume); >+ loff_t pos = *ppos; > >- if (*ppos >= strlen(buf)) >+ if (pos != (unsigned)pos || pos >= strlen(buf)) > return 0; >- if (n > strlen(buf) - *ppos) >- n = strlen(buf) - *ppos; >+ if (n > strlen(buf) - pos) >+ n = strlen(buf) - pos; > if (n > count) > n = count; >- *ppos += n; >+ *ppos = pos + n; >+ > return n; > } >diff -urN linux-2.4.21/arch/ppc64/kernel/lparcfg.c linux-2.4.21-fix/arch/ppc64/kernel/lparcfg.c >--- linux-2.4.21/arch/ppc64/kernel/lparcfg.c 2004-06-28 16:34:51.000000000 -0400 >+++ linux-2.4.21-fix/arch/ppc64/kernel/lparcfg.c 2004-06-28 17:01:05.000000000 -0400 >@@ -329,7 +329,7 @@ > ret = -EFAULT; > else { > ret = count; >- *ppos += count; >+ *ppos = p + count; > } > up(&lparcfg_sem); > return ret; >diff -urN linux-2.4.21/arch/ppc64/kernel/nvram.c linux-2.4.21-fix/arch/ppc64/kernel/nvram.c >--- linux-2.4.21/arch/ppc64/kernel/nvram.c 2004-06-28 16:34:51.000000000 -0400 >+++ linux-2.4.21-fix/arch/ppc64/kernel/nvram.c 2004-06-28 17:01:05.000000000 -0400 >@@ -75,10 +75,11 @@ > { > ssize_t len; > char *tmp_buffer; >+ loff_t pos = *ppos; > > if (verify_area(VERIFY_WRITE, buf, count)) > return -EFAULT; >- if (*ppos >= rtas_nvram_size) >+ if ((unsigned)pos != pos || pos >= rtas_nvram_size) > return 0; > if (count > rtas_nvram_size) > count = rtas_nvram_size; >@@ -89,7 +90,7 @@ > return -ENOMEM; > } > >- len = read_nvram(tmp_buffer, count, ppos); >+ len = read_nvram(tmp_buffer, count, &pos); > if (len <= 0) { > kfree(tmp_buffer); > return len; >@@ -101,6 +102,7 @@ > } > > kfree(tmp_buffer); >+ *ppos = pos; > return len; > > } >@@ -110,10 +112,11 @@ > { > ssize_t len; > char * tmp_buffer; >+ loff_t pos = *ppos; > > if (verify_area(VERIFY_READ, buf, count)) > return -EFAULT; >- if (*ppos >= rtas_nvram_size) >+ if (pos != (unsigned) pos || pos >= rtas_nvram_size) > return 0; > if (count > rtas_nvram_size) > count = rtas_nvram_size; >@@ -129,7 +132,8 @@ > return -EFAULT; > } > >- len = write_nvram(tmp_buffer, count, ppos); >+ len = write_nvram(tmp_buffer, count, &pos); >+ *ppos = pos; > > kfree(tmp_buffer); > return len; >diff -urN linux-2.4.21/arch/ppc64/kernel/proc_pmc.c linux-2.4.21-fix/arch/ppc64/kernel/proc_pmc.c >--- linux-2.4.21/arch/ppc64/kernel/proc_pmc.c 2004-06-28 16:35:01.000000000 -0400 >+++ linux-2.4.21-fix/arch/ppc64/kernel/proc_pmc.c 2004-06-28 17:01:05.000000000 -0400 >@@ -445,8 +445,9 @@ > } > pnt = (char *)(perfmon_base.profile_buffer) + p - sizeof(unsigned int); > copy_to_user(buf,(void *)pnt,count); >+ p += count; > read += count; >- *ppos += read; >+ *ppos = p; > return read; > } > >@@ -460,19 +461,17 @@ > size_t count, loff_t *ppos) > { > unsigned long p = *ppos; >- ssize_t read; > char * pnt; > > if (p >= (perfmon_base.trace_length)) return 0; > if (count > (perfmon_base.trace_length) - p) > count = (perfmon_base.trace_length) - p; >- read = 0; > > pnt = (char *)(perfmon_base.trace_buffer) + p; > copy_to_user(buf,(void *)pnt,count); >- read += count; >- *ppos += read; >- return read; >+ p += count; >+ *ppos = p; >+ return count; > } > > static ssize_t write_trace(struct file * file, const char * buf, >@@ -492,13 +491,11 @@ > if (p >= (perfmon_base.timeslice_length)) return 0; > if (count > (perfmon_base.timeslice_length) - p) > count = (perfmon_base.timeslice_length) - p; >- read = 0; > > pnt = (char *)(perfmon_base.timeslice_buffer) + p; > copy_to_user(buf,(void *)pnt,count); >- read += count; >- *ppos += read; >- return read; >+ *ppos = p + count; >+ return count; > } > > static ssize_t write_timeslice(struct file * file, const char * buf, >diff -urN linux-2.4.21/arch/ppc64/kernel/rtas_flash.c linux-2.4.21-fix/arch/ppc64/kernel/rtas_flash.c >--- linux-2.4.21/arch/ppc64/kernel/rtas_flash.c 2004-06-28 16:34:51.000000000 -0400 >+++ linux-2.4.21-fix/arch/ppc64/kernel/rtas_flash.c 2004-06-28 17:01:05.000000000 -0400 >@@ -225,6 +225,7 @@ > struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; > struct rtas_update_flash_t *uf; > char msg[RTAS_MSG_MAXLEN]; >+ loff_t pos = *ppos; > int msglen; > ssize_t ret; > >@@ -238,19 +239,19 @@ > msglen = sprintf(msg, "%d\n", uf->status); > } > >- if (*ppos >= msglen) { >+ if (pos != (unsigned)pos || pos >= msglen) { > ret = 0; > goto done; > } >- msglen -= *ppos; >+ msglen -= pos; > if (msglen > count) > msglen = count; > >- if (copy_to_user(buf, msg + (*ppos), msglen)) { >+ if (copy_to_user(buf, msg + pos, msglen)) { > ret = -EFAULT; > goto done; > } >- *ppos += msglen; >+ *ppos = pos + msglen; > ret = msglen; > done: > up(&rtas_flash_sem); >@@ -387,6 +388,7 @@ > char msg[RTAS_MSG_MAXLEN]; > int msglen; > ssize_t ret; >+ loff_t pos = *ppos; > > if (down_interruptible(&rtas_flash_sem)) > return -ERESTARTSYS; >@@ -397,20 +399,20 @@ > } > > msglen = sprintf(msg, "%d\n", args_buf->status); >- if (*ppos >= msglen) { >+ if (pos != (unsigned)pos || pos >= msglen) { > ret = 0; > goto done; > } > >- msglen -= *ppos; >+ msglen -= pos; > if (msglen > count) > msglen = count; > >- if (copy_to_user(buf, msg + (*ppos), msglen)) { >+ if (copy_to_user(buf, msg + pos, msglen)) { > ret = -EFAULT; > goto done; > } >- *ppos += msglen; >+ *ppos = pos + msglen; > ret = msglen; > > done: >@@ -553,6 +555,7 @@ > { > struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; > struct rtas_validate_flash_t *args_buf; >+ loff_t pos = *off; > ssize_t ret; > > if (down_interruptible(&rtas_flash_sem)) >@@ -570,25 +573,25 @@ > > /* We are only interested in the first 4K of the > * candidate image */ >- if ((*off >= VALIDATE_BUF_SIZE) || >+ if (pos != (unsigned)pos || pos >= VALIDATE_BUF_SIZE || > (args_buf->status == VALIDATE_AUTH)) { >- *off += count; >+ *off = pos + count; > ret = count; > goto done; > } > >- if (*off + count >= VALIDATE_BUF_SIZE) { >- count = VALIDATE_BUF_SIZE - *off; >+ if (count >= VALIDATE_BUF_SIZE - pos) { >+ count = VALIDATE_BUF_SIZE - pos; > args_buf->status = VALIDATE_READY; > } else { > args_buf->status = VALIDATE_INCOMPLETE; > } > >- if (copy_from_user(args_buf->buf + *off, buf, count)) { >+ if (copy_from_user(args_buf->buf + pos, buf, count)) { > ret = -EFAULT; > goto done; > } >- *off += count; >+ *off = pos + count; > ret = count; > > done: >diff -urN linux-2.4.21/arch/ppc64/kernel/rtas-proc.c linux-2.4.21-fix/arch/ppc64/kernel/rtas-proc.c >--- linux-2.4.21/arch/ppc64/kernel/rtas-proc.c 2004-06-28 16:34:51.000000000 -0400 >+++ linux-2.4.21-fix/arch/ppc64/kernel/rtas-proc.c 2004-06-28 17:01:05.000000000 -0400 >@@ -347,6 +347,7 @@ > size_t count, loff_t *ppos) > { > char timebuf[40]; >+ loff_t pos = *ppos; > int n; > > if (power_on_time == 0) >@@ -354,17 +355,16 @@ > else > n = snprintf(timebuf, 40, "%lu\n", power_on_time); > >- if (*ppos >= n) >+ if (pos != (unsigned)pos || pos >= n) > return 0; > n++; /* Include the null terminator */ >- if (*ppos) >- n -= *ppos; >+ n -= pos; > if (n > count) > n = count; >- if (copy_to_user (buf, timebuf + (*ppos), n)) { >+ if (copy_to_user (buf, timebuf + pos, n)) { > return -EFAULT; > } >- *ppos += n; >+ *ppos = pos + n; > return n; > } > >@@ -395,6 +395,7 @@ > { > int n; > char * tmpbuf; >+ loff_t pos = *ppos; > > tmpbuf = kmalloc (MAX_LINELENGTH, GFP_KERNEL); > if (!tmpbuf) { >@@ -404,21 +405,20 @@ > n = snprintf (tmpbuf, MAX_LINELENGTH, "%s\n", progress_led); > if (n > MAX_LINELENGTH) n = MAX_LINELENGTH; > >- if (*ppos >= n) { >+ if (pos != (unsigned)pos || pos >= n) { > kfree (tmpbuf); > return 0; > } > n++; /* Include the null terminator */ >- if (*ppos) >- n -= *ppos; >+ n -= pos; > if (n > count) > n = count; >- if (copy_to_user (buf, tmpbuf + (*ppos), n)) { >+ if (copy_to_user (buf, tmpbuf + pos, n)) { > kfree (tmpbuf); > return -EFAULT; > } > kfree (tmpbuf); >- *ppos += n; >+ *ppos = pos + n; > return n; > } > >@@ -466,6 +466,7 @@ > unsigned long tod[8]; > int n, error; > char timebuf[30]; >+ loff_t pos = *ppos; > > error = rtas_call(rtas_token("get-time-of-day"), 0, 8, tod); > >@@ -482,17 +483,16 @@ > mktime(year, mon, day, hour, min, sec)); > } > >- if (*ppos >= n) >+ if (pos != (unsigned)pos || pos >= n) > return 0; > n++; /* Include the null terminator */ >- if (*ppos) >- n -= *ppos; >+ n -= pos; > if (n > count) > n = count; >- if (copy_to_user (buf, timebuf + (*ppos), n)) { >+ if (copy_to_user (buf, timebuf + pos, n)) { > return -EFAULT; > } >- *ppos += n; >+ *ppos = pos + n; > return n; > } > >@@ -873,19 +873,19 @@ > { > int n; > char freqbuf[30]; >+ loff_t pos = *ppos; > > n = snprintf(freqbuf, 30, "%lu\n", rtas_tone_frequency); >- if (*ppos >= n) >+ if (pos != (unsigned)pos || pos >= n) > return 0; > n++; /* Include the null terminator */ >- if (*ppos) >- n -= *ppos; >+ n -= pos; > if (n > count) > n = count; >- if (copy_to_user (buf, freqbuf + (*ppos), n)) { >+ if (copy_to_user (buf, freqbuf + pos, n)) { > return -EFAULT; > } >- *ppos += n; >+ *ppos = pos + n; > return n; > } > /* ****************************************************************** */ >@@ -931,19 +931,19 @@ > { > int n; > char volbuf[10]; >+ loff_t pos = *ppos; > > n = snprintf(volbuf, 10, "%lu\n", rtas_tone_volume); >- if (*ppos >= n) >+ if (pos != (unsigned)pos || pos >= n) > return 0; > n++; /* Include the null terminator */ >- if (*ppos) >- n -= *ppos; >+ n -= pos; > if (n > count) > n = count; >- if (copy_to_user (buf, volbuf + (*ppos), n)) { >+ if (copy_to_user (buf, volbuf + pos, n)) { > return -EFAULT; > } >- *ppos += n; >+ *ppos = pos + n; > return n; > } > >@@ -1047,6 +1047,7 @@ > int i; > int n = 0, cnt; > int m = MAX_ERRINJCT_TOKENS * (ERRINJCT_TOKEN_LEN+1); >+ loff_t pos = *ppos; > > buffer = (char *)kmalloc(m, GFP_KERNEL); > if (!buffer) { >@@ -1064,21 +1065,20 @@ > n += cnt; > } > >- if (*ppos >= n) { >+ if (pos != (unsigned)pos || pos >= n) { > kfree(buffer); > return 0; > } > n++; /* Include the null terminator */ >- if (*ppos) >- n -= *ppos; >+ n -= pos; > if (n > count) > n = count; >- if (copy_to_user(buf, buffer + *ppos, n)) { >+ if (copy_to_user(buf, buffer + pos, n)) { > kfree (buffer); > return -EFAULT; > } > >- *ppos += n; >+ *ppos = pos + n; > > kfree(buffer); > return n; >@@ -1091,17 +1091,18 @@ > size_t count, loff_t *ppos) > { > char kbuf[RMO_READ_BUF_MAX]; >+ loff_t pos = *ppos; > int n; > > n = sprintf(kbuf, "%016lx %x\n", rtas_rmo_buf, RTAS_RMOBUF_MAX); > >- if (*ppos >= n) >+ if (pos != (unsigned)pos || pos >= n) > return 0; >- n -= *ppos; >+ n -= pos; > if (n > count) > n = count; >- if (copy_to_user(buf, kbuf + *ppos, n)) >+ if (copy_to_user(buf, kbuf + pos, n)) > return -EFAULT; >- *ppos += n; >+ *ppos = pos + n; > return n; > } >diff -urN linux-2.4.21/arch/s390/kernel/debug.c linux-2.4.21-fix/arch/s390/kernel/debug.c >--- linux-2.4.21/arch/s390/kernel/debug.c 2004-06-28 16:34:35.000000000 -0400 >+++ linux-2.4.21-fix/arch/s390/kernel/debug.c 2004-06-28 17:01:05.000000000 -0400 >@@ -470,7 +470,7 @@ > goto out; > } > out: >- p_info->offset = *offset + count; >+ p_info->offset += count; > p_info->act_entry_offset = size; > *offset = p_info->offset; > return count; >@@ -1068,7 +1068,7 @@ > input_buf[0]); > } > out: >- *offset += in_buf_size; >+ *offset = in_buf_size; > return rc; /* number of input characters */ > } > >@@ -1135,7 +1135,7 @@ > printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]); > > out: >- *offset += in_buf_size; >+ *offset = in_buf_size; > return rc; /* number of input characters */ > } > >diff -urN linux-2.4.21/arch/s390x/kernel/debug.c linux-2.4.21-fix/arch/s390x/kernel/debug.c >--- linux-2.4.21/arch/s390x/kernel/debug.c 2004-06-28 16:34:35.000000000 -0400 >+++ linux-2.4.21-fix/arch/s390x/kernel/debug.c 2004-06-28 17:01:05.000000000 -0400 >@@ -470,7 +470,7 @@ > goto out; > } > out: >- p_info->offset = *offset + count; >+ p_info->offset += count; > p_info->act_entry_offset = size; > *offset = p_info->offset; > return count; >@@ -1068,7 +1068,7 @@ > input_buf[0]); > } > out: >- *offset += in_buf_size; >+ *offset = in_buf_size; > return rc; /* number of input characters */ > } > >@@ -1135,7 +1135,7 @@ > printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]); > > out: >- *offset += in_buf_size; >+ *offset = in_buf_size; > return rc; /* number of input characters */ > } > >diff -urN linux-2.4.21/arch/x86_64/kernel/mtrr.c linux-2.4.21-fix/arch/x86_64/kernel/mtrr.c >--- linux-2.4.21/arch/x86_64/kernel/mtrr.c 2004-06-28 16:34:42.000000000 -0400 >+++ linux-2.4.21-fix/arch/x86_64/kernel/mtrr.c 2004-06-28 17:01:05.000000000 -0400 >@@ -957,16 +957,19 @@ > static ssize_t mtrr_read (struct file *file, char *buf, size_t len, > loff_t * ppos) > { >- if (*ppos >= ascii_buf_bytes) >+ loff_t n = *ppos; >+ unsigned pos = n; >+ >+ if (pos != n || pos >= ascii_buf_bytes) > return 0; > >- if (*ppos + len > ascii_buf_bytes) >- len = ascii_buf_bytes - *ppos; >+ if (len > ascii_buf_bytes - pos) >+ len = ascii_buf_bytes - pos; > >- if (copy_to_user (buf, ascii_buffer + *ppos, len)) >+ if (copy_to_user (buf, ascii_buffer + pos, len)) > return -EFAULT; > >- *ppos += len; >+ *ppos = pos + len; > return len; > } > >diff -urN linux-2.4.21/drivers/acpi/system.c linux-2.4.21-fix/drivers/acpi/system.c >--- linux-2.4.21/drivers/acpi/system.c 2004-06-28 16:35:12.000000000 -0400 >+++ linux-2.4.21-fix/drivers/acpi/system.c 2004-06-28 17:01:05.000000000 -0400 >@@ -520,6 +520,7 @@ > struct acpi_buffer dsdt = {ACPI_ALLOCATE_BUFFER, NULL}; > void *data = 0; > size_t size = 0; >+ loff_t pos = *ppos; > > ACPI_FUNCTION_TRACE("acpi_system_read_dsdt"); > >@@ -527,9 +528,12 @@ > if (ACPI_FAILURE(status)) > return_VALUE(-ENODEV); > >- if (*ppos < dsdt.length) { >- data = dsdt.pointer + file->f_pos; >- size = dsdt.length - file->f_pos; >+ if (pos < 0) >+ return -EINVAL; >+ >+ if (pos < dsdt.length) { >+ data = dsdt.pointer + pos; >+ size = dsdt.length - pos; > if (size > count) > size = count; > if (copy_to_user(buffer, data, size)) { >@@ -540,7 +544,9 @@ > > acpi_os_free(dsdt.pointer); > >- *ppos += size; >+ pos += size; >+ >+ *ppos = pos; > > return_VALUE(size); > } >@@ -563,6 +569,7 @@ > struct acpi_buffer fadt = {ACPI_ALLOCATE_BUFFER, NULL}; > void *data = 0; > size_t size = 0; >+ loff_t pos = *ppos; > > ACPI_FUNCTION_TRACE("acpi_system_read_fadt"); > >@@ -570,9 +577,12 @@ > if (ACPI_FAILURE(status)) > return_VALUE(-ENODEV); > >- if (*ppos < fadt.length) { >- data = fadt.pointer + file->f_pos; >- size = fadt.length - file->f_pos; >+ if (pos < 0) >+ return -EINVAL; >+ >+ if (pos < fadt.length) { >+ data = fadt.pointer + pos; >+ size = fadt.length - pos; > if (size > count) > size = count; > if (copy_to_user(buffer, data, size)) { >@@ -583,7 +593,8 @@ > > acpi_os_free(fadt.pointer); > >- *ppos += size; >+ pos += size; >+ *ppos = pos; > > return_VALUE(size); > } >diff -urN linux-2.4.21/drivers/block/acsi_slm.c linux-2.4.21-fix/drivers/block/acsi_slm.c >--- linux-2.4.21/drivers/block/acsi_slm.c 2002-11-28 18:53:12.000000000 -0500 >+++ linux-2.4.21-fix/drivers/block/acsi_slm.c 2004-06-28 17:01:05.000000000 -0400 >@@ -367,6 +367,7 @@ > > { > struct inode *node = file->f_dentry->d_inode; >+ loff_t pos = *ppos; > unsigned long page; > int length; > int end; >@@ -381,18 +382,18 @@ > count = length; > goto out; > } >- if (file->f_pos >= length) { >+ if (pos != (unsigned)pos || pos >= length) { > count = 0; > goto out; > } >- if (count + file->f_pos > length) >- count = length - file->f_pos; >- end = count + file->f_pos; >- if (copy_to_user(buf, (char *)page + file->f_pos, count)) { >+ if (count > length - pos) >+ count = length - pos; >+ end = count + pos; >+ if (copy_to_user(buf, (char *)page + pos, count)) { > count = -EFAULT; > goto out; > } >- file->f_pos = end; >+ *ppos = end; > out: free_page( page ); > return( count ); > } >diff -urN linux-2.4.21/drivers/block/rd.c linux-2.4.21-fix/drivers/block/rd.c >--- linux-2.4.21/drivers/block/rd.c 2004-06-28 16:35:34.000000000 -0400 >+++ linux-2.4.21-fix/drivers/block/rd.c 2004-06-28 17:01:05.000000000 -0400 >@@ -320,14 +320,19 @@ > static ssize_t initrd_read(struct file *file, char *buf, > size_t count, loff_t *ppos) > { >- int left; >+ loff_t n = *ppos; >+ unsigned pos = n; >+ unsigned left = initrd_end - initrd_start; > >- left = initrd_end - initrd_start - *ppos; >+ if (pos != n || pos >= left) >+ return 0; >+ >+ left -= pos; > if (count > left) count = left; > if (count == 0) return 0; >- if (copy_to_user(buf, (char *)initrd_start + *ppos, count)) >+ if (copy_to_user(buf, (char *)initrd_start + pos, count)) > return -EFAULT; >- *ppos += count; >+ *ppos = pos + count; > return count; > } > >diff -urN linux-2.4.21/drivers/char/i8k.c linux-2.4.21-fix/drivers/char/i8k.c >--- linux-2.4.21/drivers/char/i8k.c 2002-11-28 18:53:12.000000000 -0500 >+++ linux-2.4.21-fix/drivers/char/i8k.c 2004-06-28 17:01:05.000000000 -0400 >@@ -493,6 +493,7 @@ > > static ssize_t i8k_read(struct file *f, char *buffer, size_t len, loff_t *fpos) > { >+ loff_t pos = *fpos; > int n; > char info[128]; > >@@ -501,19 +502,19 @@ > return n; > } > >- if (*fpos >= n) { >+ if (pos != (unsigned)pos || pos >= n) { > return 0; > } > >- if ((*fpos + len) >= n) { >- len = n - *fpos; >+ if (len >= n - pos) { >+ len = n - pos; > } > > if (copy_to_user(buffer, info, len) != 0) { > return -EFAULT; > } > >- *fpos += len; >+ *fpos = pos + len; > return len; > } > >diff -urN linux-2.4.21/drivers/char/istallion.c linux-2.4.21-fix/drivers/char/istallion.c >--- linux-2.4.21/drivers/char/istallion.c 2004-06-28 16:34:35.000000000 -0400 >+++ linux-2.4.21-fix/drivers/char/istallion.c 2004-06-28 17:01:05.000000000 -0400 >@@ -4854,6 +4854,7 @@ > void *memptr; > stlibrd_t *brdp; > int brdnr, size, n; >+ loff_t pos = *offp; > > #if DEBUG > printk(KERN_DEBUG "stli_memread(fp=%x,buf=%x,count=%x,offp=%x)\n", >@@ -4868,25 +4869,26 @@ > return(-ENODEV); > if (brdp->state == 0) > return(-ENODEV); >- if (fp->f_pos >= brdp->memsize) >+ if (pos != (unsigned)pos || pos >= brdp->memsize) > return(0); > >- size = MIN(count, (brdp->memsize - fp->f_pos)); >+ size = MIN(count, (brdp->memsize - pos)); > > save_flags(flags); > cli(); > EBRDENABLE(brdp); > while (size > 0) { >- memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos); >- n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize))); >+ memptr = (void *) EBRDGETMEMPTR(brdp, pos); >+ n = MIN(size, (brdp->pagesize - (((unsigned long) pos) % brdp->pagesize))); > if (copy_to_user(buf, memptr, n)) { > count = -EFAULT; > goto out; > } >- fp->f_pos += n; >+ pos += n; > buf += n; > size -= n; > } >+ *offp = pos; > out: > EBRDDISABLE(brdp); > restore_flags(flags); >@@ -4909,6 +4911,7 @@ > stlibrd_t *brdp; > char *chbuf; > int brdnr, size, n; >+ loff_t pos = *offp; > > #if DEBUG > printk(KERN_DEBUG "stli_memwrite(fp=%x,buf=%x,count=%x,offp=%x)\n", >@@ -4923,26 +4926,27 @@ > return(-ENODEV); > if (brdp->state == 0) > return(-ENODEV); >- if (fp->f_pos >= brdp->memsize) >+ if (pos != (unsigned)pos || pos >= brdp->memsize) > return(0); > > chbuf = (char *) buf; >- size = MIN(count, (brdp->memsize - fp->f_pos)); >+ size = MIN(count, (brdp->memsize - pos)); > > save_flags(flags); > cli(); > EBRDENABLE(brdp); > while (size > 0) { >- memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos); >- n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize))); >+ memptr = (void *) EBRDGETMEMPTR(brdp, pos); >+ n = MIN(size, (brdp->pagesize - (((unsigned long) pos) % brdp->pagesize))); > if (copy_from_user(memptr, chbuf, n)) { > count = -EFAULT; > goto out; > } >- fp->f_pos += n; >+ pos += n; > chbuf += n; > size -= n; > } >+ *offp = pos; > out: > EBRDDISABLE(brdp); > restore_flags(flags); >diff -urN linux-2.4.21/drivers/char/mem.c linux-2.4.21-fix/drivers/char/mem.c >--- linux-2.4.21/drivers/char/mem.c 2004-06-28 16:35:26.000000000 -0400 >+++ linux-2.4.21-fix/drivers/char/mem.c 2004-06-28 17:01:05.000000000 -0400 >@@ -66,7 +66,7 @@ > if (copy_from_user(p, buf, count)) > return -EFAULT; > written += count; >- *ppos += written; >+ *ppos = realp + written; > return written; > } > >@@ -107,7 +107,7 @@ > if (copy_to_user(buf, __va(p), count)) > return -EFAULT; > read += count; >- *ppos += read; >+ *ppos = p + read; > return read; > } > >diff -urN linux-2.4.21/drivers/char/nvram.c linux-2.4.21-fix/drivers/char/nvram.c >--- linux-2.4.21/drivers/char/nvram.c 2003-06-13 10:51:33.000000000 -0400 >+++ linux-2.4.21-fix/drivers/char/nvram.c 2004-06-28 17:01:05.000000000 -0400 >@@ -252,9 +252,13 @@ > nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos) > { > unsigned char contents[NVRAM_BYTES]; >- unsigned i = *ppos; >+ loff_t n = *ppos; >+ unsigned i = n; > unsigned char *tmp; > >+ if (i != n || i >= NVRAM_BYTES) >+ return 0; >+ > spin_lock_irq(&rtc_lock); > > if (!__nvram_check_checksum()) >@@ -281,10 +285,14 @@ > nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos) > { > unsigned char contents[NVRAM_BYTES]; >- unsigned i = *ppos; >+ loff_t n = *ppos; >+ unsigned i = n; > unsigned char *tmp; > int len; > >+ if (i != n || i >= NVRAM_BYTES) >+ return 0; >+ > len = (NVRAM_BYTES - i) < count ? (NVRAM_BYTES - i) : count; > if (copy_from_user(contents, buf, len)) > return -EFAULT; >diff -urN linux-2.4.21/drivers/char/nwflash.c linux-2.4.21-fix/drivers/char/nwflash.c >--- linux-2.4.21/drivers/char/nwflash.c 2004-06-28 16:34:35.000000000 -0400 >+++ linux-2.4.21-fix/drivers/char/nwflash.c 2004-06-28 17:01:05.000000000 -0400 >@@ -133,7 +133,8 @@ > > static ssize_t flash_read(struct file *file, char *buf, size_t size, loff_t * ppos) > { >- unsigned long p = *ppos; >+ loff_t n = *ppos; >+ unsigned long p = n; > unsigned int count = size; > int ret = 0; > >@@ -144,7 +145,7 @@ > if (count) > ret = -ENXIO; > >- if (p < gbFlashSize) { >+ if (n == p && p < gbFlashSize) { > if (count > gbFlashSize - p) > count = gbFlashSize - p; > >@@ -155,7 +156,7 @@ > return -ERESTARTSYS; > > ret = count - copy_to_user(buf, (void *)(FLASH_BASE + p), count); >- *ppos += ret; >+ *ppos = p + ret; > up(&nwflash_sem); > if (ret == 0) > ret = -EFAULT; >@@ -165,7 +166,8 @@ > > static ssize_t flash_write(struct file *file, const char *buf, size_t size, loff_t * ppos) > { >- unsigned long p = *ppos; >+ loff_t n = *ppos; >+ unsigned long p = n; > unsigned int count = size; > int written; > int nBlock, temp, rc; >@@ -184,7 +186,7 @@ > /* > * check for out of range pos or count > */ >- if (p >= gbFlashSize) >+ if (p != n || p >= gbFlashSize) > return count ? -ENXIO : 0; > > if (count > gbFlashSize - p) >@@ -273,7 +275,7 @@ > p += rc; > buf += rc; > written += rc; >- *ppos += rc; >+ *ppos = p; > > if (flashdebug) > printk(KERN_DEBUG "flash_write: written 0x%X bytes OK.\n", written); >diff -urN linux-2.4.21/drivers/char/raw.c linux-2.4.21-fix/drivers/char/raw.c >--- linux-2.4.21/drivers/char/raw.c 2004-06-28 16:35:25.000000000 -0400 >+++ linux-2.4.21-fix/drivers/char/raw.c 2004-06-28 17:01:05.000000000 -0400 >@@ -309,6 +309,7 @@ > int minor; > kdev_t dev; > unsigned long limit; >+ loff_t off = *offp; > > int sector_size, sector_bits, sector_mask; > int max_sectors; >@@ -319,6 +320,9 @@ > > minor = MINOR(filp->f_dentry->d_inode->i_rdev); > >+ if (off < 0) >+ return -EINVAL; >+ > err = alloc_kiovec(1, &iobuf); > if (err) > return err; >@@ -338,12 +342,12 @@ > MAJOR(dev), MINOR(dev), limit); > > err = -EINVAL; >- if ((*offp & sector_mask) || (size & sector_mask)) >+ if ((off & sector_mask) || (size & sector_mask)) > goto out_free; > err = 0; > if (size) > err = -ENXIO; >- if ((*offp >> sector_bits) >= limit) >+ if ((off >> sector_bits) >= limit) > goto out_free; > > /* >@@ -353,7 +357,7 @@ > */ > > transferred = 0; >- blocknr = *offp >> sector_bits; >+ blocknr = off >> sector_bits; > while (size > 0) { > blocks = size >> sector_bits; > if (blocks > max_sectors) >@@ -390,7 +394,7 @@ > } > > if (transferred) { >- *offp += transferred; >+ *offp = off + transferred; > err = transferred; > } > >@@ -511,6 +515,10 @@ > int i, minor, err; > int sector_size, sector_bits, sector_mask, max_sectors; > ssize_t tot_len; >+ loff_t off = *offp; >+ >+ if (off < 0) >+ return -EINVAL; > > for (i = 0, tot_len = 0; i < iov_count; i++) { > ssize_t tmp = tot_len; >@@ -547,15 +555,15 @@ > MAJOR(dev), MINOR(dev), limit); > > err = -EINVAL; >- if ((*offp & sector_mask) || (tot_len & sector_mask)) >+ if ((off & sector_mask) || (tot_len & sector_mask)) > goto out; > err = 0; > if (tot_len) > err = -ENXIO; >- if ((*offp >> sector_bits) >= limit) >+ if ((off >> sector_bits) >= limit) > goto out; > >- blocknr = *offp >> sector_bits; >+ blocknr = off >> sector_bits; > blocks = tot_len >> sector_bits; > > if (!blocks) >@@ -582,7 +590,7 @@ > unmap_kiobuf(iobuf); > > if (err > 0) >- *offp += err; >+ *offp = off + err; > out: > free_kiovec(1, &iobuf); > return err; >diff -urN linux-2.4.21/drivers/char/vc_screen.c linux-2.4.21-fix/drivers/char/vc_screen.c >--- linux-2.4.21/drivers/char/vc_screen.c 2001-09-17 00:22:40.000000000 -0400 >+++ linux-2.4.21-fix/drivers/char/vc_screen.c 2004-06-28 17:01:05.000000000 -0400 >@@ -98,7 +98,8 @@ > { > struct inode *inode = file->f_dentry->d_inode; > unsigned int currcons = MINOR(inode->i_rdev); >- long pos = *ppos; >+ loff_t n = *ppos; >+ unsigned pos = n; > long viewed, attr, read; > int col, maxcol; > unsigned short *org = NULL; >@@ -124,11 +125,10 @@ > if (!vc_cons_allocated(currcons)) > goto unlock_out; > >- ret = -EINVAL; >- if (pos < 0) >- goto unlock_out; > read = 0; > ret = 0; >+ if (pos != n) >+ goto unlock_out; > while (count) { > char *con_buf0, *con_buf_start; > long this_round, size; >@@ -244,16 +244,15 @@ > acquire_console_sem(); > > if (ret) { >- read += (orig_count - ret); > ret = -EFAULT; >- break; >+ goto unlock_out; > } > buf += orig_count; > pos += orig_count; > read += orig_count; > count -= orig_count; > } >- *ppos += read; >+ *ppos = pos; > if (read) > ret = read; > unlock_out: >@@ -267,7 +266,8 @@ > { > struct inode *inode = file->f_dentry->d_inode; > unsigned int currcons = MINOR(inode->i_rdev); >- long pos = *ppos; >+ loff_t n = *ppos; >+ unsigned pos = n; > long viewed, attr, size, written; > char *con_buf0; > int col, maxcol; >@@ -297,7 +297,7 @@ > > size = vcs_size(inode); > ret = -EINVAL; >- if (pos < 0 || pos > size) >+ if (pos != n || pos > size) > goto unlock_out; > if (count > size - pos) > count = size - pos; >@@ -435,7 +435,7 @@ > if (org0) > update_region(currcons, (unsigned long)(org0), org-org0); > } >- *ppos += written; >+ *ppos = pos; > ret = written; > > unlock_out: >diff -urN linux-2.4.21/drivers/gsc/eisa_eeprom.c linux-2.4.21-fix/drivers/gsc/eisa_eeprom.c >--- linux-2.4.21/drivers/gsc/eisa_eeprom.c 2002-11-28 18:53:12.000000000 -0500 >+++ linux-2.4.21-fix/drivers/gsc/eisa_eeprom.c 2004-06-28 17:01:05.000000000 -0400 >@@ -33,21 +33,27 @@ > { > unsigned char *tmp; > ssize_t ret; >+ loff_t n = *ppos; >+ unsigned pos = n; > int i; > >- if (*ppos >= HPEE_MAX_LENGTH) >+ if (pos != n || pos >= HPEE_MAX_LENGTH) > return 0; > >- count = *ppos + count < HPEE_MAX_LENGTH ? count : HPEE_MAX_LENGTH - *ppos; >+ if (count > HPEE_MAX_LENGTH - pos) >+ count = HPEE_MAX_LENGTH - pos; >+ > tmp = kmalloc(count, GFP_KERNEL); > if (tmp) { > for (i = 0; i < count; i++) >- tmp[i] = gsc_readb(eeprom_addr+(*ppos)++); >+ tmp[i] = gsc_readb(eeprom_addr+pos++); > > if (copy_to_user (buf, tmp, count)) > ret = -EFAULT; >- else >+ else { > ret = count; >+ *ppos = pos; >+ } > kfree (tmp); > } else > ret = -ENOMEM; >diff -urN linux-2.4.21/drivers/hotplug/pci_hotplug_core.c linux-2.4.21-fix/drivers/hotplug/pci_hotplug_core.c >--- linux-2.4.21/drivers/hotplug/pci_hotplug_core.c 2002-11-28 18:53:13.000000000 -0500 >+++ linux-2.4.21-fix/drivers/hotplug/pci_hotplug_core.c 2004-06-28 17:01:06.000000000 -0400 >@@ -604,7 +604,7 @@ > retval = -EFAULT; > goto exit; > } >- *offset += len; >+ *offset = len; > retval = len; > > exit: >@@ -715,7 +715,7 @@ > retval = -EFAULT; > goto exit; > } >- *offset += len; >+ *offset = len; > retval = len; > > exit: >@@ -780,14 +780,15 @@ > int retval; > int len; > u8 value; >+ loff_t off = *offset; > >- dbg("count = %d, offset = %lld\n", count, *offset); >+ dbg("count = %d, offset = %lld\n", count, off); > >- if (*offset < 0) >+ if (off < 0) > return -EINVAL; > if (count <= 0) > return 0; >- if (*offset != 0) >+ if (off != 0) > return 0; > > if (slot == NULL) { >@@ -808,7 +809,7 @@ > retval = -EFAULT; > goto exit; > } >- *offset += len; >+ *offset = off + len; > retval = len; > > exit: >@@ -823,14 +824,15 @@ > int retval; > int len; > u8 value; >+ loff_t off = *offset; > >- dbg("count = %d, offset = %lld\n", count, *offset); >+ dbg("count = %d, offset = %lld\n", count, off); > >- if (*offset < 0) >+ if (off < 0) > return -EINVAL; > if (count <= 0) > return 0; >- if (*offset != 0) >+ if (off != 0) > return 0; > > if (slot == NULL) { >@@ -851,7 +853,7 @@ > retval = -EFAULT; > goto exit; > } >- *offset += len; >+ *offset = off + len; > retval = len; > > exit: >@@ -869,14 +871,15 @@ > int retval; > int len = 0; > enum pci_bus_speed value; >+ loff_t off = *offset; > >- dbg ("count = %d, offset = %lld\n", count, *offset); >+ dbg ("count = %d, offset = %lld\n", count, off); > >- if (*offset < 0) >+ if (off < 0) > return -EINVAL; > if (count <= 0) > return 0; >- if (*offset != 0) >+ if (off != 0) > return 0; > > if (slot == NULL) { >@@ -903,7 +906,7 @@ > retval = -EFAULT; > goto exit; > } >- *offset += len; >+ *offset = off + len; > retval = len; > > exit: >@@ -919,14 +922,15 @@ > int retval; > int len = 0; > enum pci_bus_speed value; >+ loff_t off = *offset; > >- dbg ("count = %d, offset = %lld\n", count, *offset); >+ dbg ("count = %d, offset = %lld\n", count, off); > >- if (*offset < 0) >+ if (off < 0) > return -EINVAL; > if (count <= 0) > return 0; >- if (*offset != 0) >+ if (off != 0) > return 0; > > if (slot == NULL) { >@@ -953,7 +957,7 @@ > retval = -EFAULT; > goto exit; > } >- *offset += len; >+ *offset = off + len; > retval = len; > > exit: >diff -urN linux-2.4.21/drivers/ieee1394/pcilynx.c linux-2.4.21-fix/drivers/ieee1394/pcilynx.c >--- linux-2.4.21/drivers/ieee1394/pcilynx.c 2003-06-13 10:51:34.000000000 -0400 >+++ linux-2.4.21-fix/drivers/ieee1394/pcilynx.c 2004-06-28 17:01:06.000000000 -0400 >@@ -1064,12 +1064,14 @@ > ssize_t retval; > void *membase; > >- if ((off + count) > PCILYNX_MAX_MEMORY+1) { >- count = PCILYNX_MAX_MEMORY+1 - off; >- } >- if (count == 0 || off > PCILYNX_MAX_MEMORY) { >+ if (!count) >+ return 0; >+ if (off < 0) >+ return -EINVAL; >+ if (off > PCILYNX_MAX_MEMORY) > return -ENOSPC; >- } >+ if (count > PCILYNX_MAX_MEMORY + 1 - off) >+ count = PCILYNX_MAX_MEMORY + 1 - off; > > switch (md->type) { > case rom: >@@ -1090,6 +1092,7 @@ > > if (count < mem_mindma) { > memcpy_fromio(md->lynx->mem_dma_buffer, membase+off, count); >+ off += count; > goto out; > } > >@@ -1120,6 +1123,7 @@ > if (bcount) { > memcpy_fromio(md->lynx->mem_dma_buffer + count - bcount, > membase+off, bcount); >+ off += bcount; > } > > out: >@@ -1127,7 +1131,7 @@ > up(&md->lynx->mem_dma_mutex); > > if (retval < 0) return retval; >- *offset += count; >+ *offset = off; > return count; > } > >@@ -1136,29 +1140,33 @@ > loff_t *offset) > { > struct memdata *md = (struct memdata *)file->private_data; >+ loff_t off = *offset; > >- if (((*offset) + count) > PCILYNX_MAX_MEMORY+1) { >- count = PCILYNX_MAX_MEMORY+1 - *offset; >- } >- if (count == 0 || *offset > PCILYNX_MAX_MEMORY) { >- return -ENOSPC; >- } >+ if (!count) >+ return 0; >+ if (off < PCILYNX_MAX_MEMORY) >+ return -EINVAL; >+ if (off > PCILYNX_MAX_MEMORY) >+ return -ENOSPC; >+ >+ if (count) > PCILYNX_MAX_MEMORY + 1 - off) >+ count = PCILYNX_MAX_MEMORY + 1 - off; > > /* FIXME: dereferencing pointers to PCI mem doesn't work everywhere */ > switch (md->type) { > case aux: >- copy_from_user(md->lynx->aux_port+(*offset), buffer, count); >+ copy_from_user(md->lynx->aux_port+off, buffer, count); > break; > case ram: >- copy_from_user(md->lynx->local_ram+(*offset), buffer, count); >+ copy_from_user(md->lynx->local_ram+off, buffer, count); > break; > case rom: > /* the ROM may be writeable */ >- copy_from_user(md->lynx->local_rom+(*offset), buffer, count); >+ copy_from_user(md->lynx->local_rom+off, buffer, count); > break; > } > >- file->f_pos += count; >+ *offset = off + count; > return count; > } > #endif /* CONFIG_IEEE1394_PCILYNX_PORTS */ >diff -urN linux-2.4.21/drivers/isdn/divert/divert_procfs.c linux-2.4.21-fix/drivers/isdn/divert/divert_procfs.c >--- linux-2.4.21/drivers/isdn/divert/divert_procfs.c 2001-12-21 12:41:54.000000000 -0500 >+++ linux-2.4.21-fix/drivers/isdn/divert/divert_procfs.c 2004-06-28 17:01:06.000000000 -0400 >@@ -80,6 +80,7 @@ > isdn_divert_read(struct file *file, char *buf, size_t count, loff_t * off) > { > struct divert_info *inf; >+ loff_t pos = *off; > int len; > > if (!*((struct divert_info **) file->private_data)) { >@@ -95,7 +96,7 @@ > if ((len = strlen(inf->info_start)) <= count) { > if (copy_to_user(buf, inf->info_start, len)) > return -EFAULT; >- file->f_pos += len; >+ *off = pos + len; > return (len); > } > return (0); >diff -urN linux-2.4.21/drivers/isdn/hysdn/hysdn_procconf.c linux-2.4.21-fix/drivers/isdn/hysdn/hysdn_procconf.c >--- linux-2.4.21/drivers/isdn/hysdn/hysdn_procconf.c 2001-12-21 12:41:54.000000000 -0500 >+++ linux-2.4.21-fix/drivers/isdn/hysdn/hysdn_procconf.c 2004-06-28 17:01:06.000000000 -0400 >@@ -212,29 +212,27 @@ > static ssize_t > hysdn_conf_read(struct file *file, char *buf, size_t count, loff_t * off) > { >+ loff_t pos = *off; > char *cp; > int i; > > if (off != &file->f_pos) /* fs error check */ > return -ESPIPE; > >- if (file->f_mode & FMODE_READ) { >- if (!(cp = file->private_data)) >- return (-EFAULT); /* should never happen */ >- i = strlen(cp); /* get total string length */ >- if (*off < i) { >- /* still bytes to transfer */ >- cp += *off; /* point to desired data offset */ >- i -= *off; /* remaining length */ >- if (i > count) >- i = count; /* limit length to transfer */ >- if (copy_to_user(buf, cp, i)) >- return (-EFAULT); /* copy error */ >- *off += i; /* adjust offset */ >- } else >- return (0); >+ if (!(cp = file->private_data)) >+ return (-EFAULT); /* should never happen */ >+ i = strlen(cp); /* get total string length */ >+ if (pos == (unsigned)pos && pos < i) { >+ /* still bytes to transfer */ >+ cp += pos; /* point to desired data offset */ >+ i -= pos; /* remaining length */ >+ if (i > count) >+ i = count; /* limit length to transfer */ >+ if (copy_to_user(buf, cp, i)) >+ return (-EFAULT); /* copy error */ >+ *off = pos + i; /* adjust offset */ > } else >- return (-EPERM); /* no permission to read */ >+ return (0); > > return (i); > } /* hysdn_conf_read */ >diff -urN linux-2.4.21/drivers/isdn/hysdn/hysdn_proclog.c linux-2.4.21-fix/drivers/isdn/hysdn/hysdn_proclog.c >--- linux-2.4.21/drivers/isdn/hysdn/hysdn_proclog.c 2001-12-21 12:41:54.000000000 -0500 >+++ linux-2.4.21-fix/drivers/isdn/hysdn/hysdn_proclog.c 2004-06-28 17:01:06.000000000 -0400 >@@ -210,6 +210,7 @@ > word ino; > struct procdata *pd = NULL; > hysdn_card *card; >+ loff_t pos = *off; > > if (!*((struct log_data **) file->private_data)) { > if (file->f_flags & O_NONBLOCK) >@@ -238,7 +239,7 @@ > if ((len = strlen(inf->log_start)) <= count) { > if (copy_to_user(buf, inf->log_start, len)) > return -EFAULT; >- file->f_pos += len; >+ *off = pos + len; > return (len); > } > return (0); >diff -urN linux-2.4.21/drivers/macintosh/ans-lcd.c linux-2.4.21-fix/drivers/macintosh/ans-lcd.c >--- linux-2.4.21/drivers/macintosh/ans-lcd.c 2002-02-25 14:37:58.000000000 -0500 >+++ linux-2.4.21-fix/drivers/macintosh/ans-lcd.c 2004-06-28 17:01:06.000000000 -0400 >@@ -61,13 +61,13 @@ > > if ( verify_area(VERIFY_READ, buf, count) ) > return -EFAULT; >- for ( i = *ppos; count > 0; ++i, ++p, --count ) >- { >+ while (count--) { > char c; >- __get_user(c, p); >+ if (__get_user(c, p++)) >+ return -EFAULT; > anslcd_write_byte_data( c ); > } >- *ppos = i; >+ *ppos += p - buf; > return p - buf; > } > >diff -urN linux-2.4.21/drivers/macintosh/nvram.c linux-2.4.21-fix/drivers/macintosh/nvram.c >--- linux-2.4.21/drivers/macintosh/nvram.c 2003-06-13 10:51:34.000000000 -0400 >+++ linux-2.4.21-fix/drivers/macintosh/nvram.c 2004-06-28 17:01:06.000000000 -0400 >@@ -37,14 +37,15 @@ > static ssize_t read_nvram(struct file *file, char *buf, > size_t count, loff_t *ppos) > { >- unsigned int i; >+ loff_t n = *ppos; >+ unsigned int i = n; > char *p = buf; > > if (verify_area(VERIFY_WRITE, buf, count)) > return -EFAULT; >- if (*ppos >= NVRAM_SIZE) >+ if (i != n || i >= NVRAM_SIZE) > return 0; >- for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) >+ for (; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) > if (__put_user(nvram_read_byte(i), p)) > return -EFAULT; > *ppos = i; >@@ -54,15 +55,16 @@ > static ssize_t write_nvram(struct file *file, const char *buf, > size_t count, loff_t *ppos) > { >- unsigned int i; >+ loff_t n = *ppos; >+ unsigned int i = n; > const char *p = buf; > char c; > > if (verify_area(VERIFY_READ, buf, count)) > return -EFAULT; >- if (*ppos >= NVRAM_SIZE) >+ if (i != n || i >= NVRAM_SIZE) > return 0; >- for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) { >+ for (; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) { > if (__get_user(c, p)) > return -EFAULT; > nvram_write_byte(c, i); >diff -urN linux-2.4.21/drivers/mtd/mtdchar.c linux-2.4.21-fix/drivers/mtd/mtdchar.c >--- linux-2.4.21/drivers/mtd/mtdchar.c 2003-06-13 10:51:34.000000000 -0400 >+++ linux-2.4.21-fix/drivers/mtd/mtdchar.c 2004-06-28 17:01:06.000000000 -0400 >@@ -125,11 +125,16 @@ > int ret=0; > int len; > char *kbuf; >+ loff_t n = *ppos; >+ unsigned long pos = n; > > DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n"); > >- if (*ppos + count > mtd->size) >- count = mtd->size - *ppos; >+ if (n != pos || pos > mtd->size) >+ return 0; >+ >+ if (count > mtd->size - pos) >+ count = mtd->size - pos; > > if (!count) > return 0; >@@ -146,9 +151,9 @@ > if (!kbuf) > return -ENOMEM; > >- ret = MTD_READ(mtd, *ppos, len, &retlen, kbuf); >+ ret = MTD_READ(mtd, pos, len, &retlen, kbuf); > if (!ret) { >- *ppos += retlen; >+ pos += retlen; > if (copy_to_user(buf, kbuf, retlen)) { > kfree(kbuf); > return -EFAULT; >@@ -166,6 +171,7 @@ > > kfree(kbuf); > } >+ *ppos = pos; > > return total_retlen; > } /* mtd_read */ >@@ -176,16 +182,18 @@ > char *kbuf; > size_t retlen; > size_t total_retlen=0; >+ loff_t n = *ppos; >+ unsigned long pos = n; > int ret=0; > int len; > > DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n"); > >- if (*ppos == mtd->size) >+ if (n != pos || pos >= mtd->size) > return -ENOSPC; > >- if (*ppos + count > mtd->size) >- count = mtd->size - *ppos; >+ if (count > mtd->size - pos) >+ count = mtd->size - pos; > > if (!count) > return 0; >@@ -207,9 +215,9 @@ > return -EFAULT; > } > >- ret = (*(mtd->write))(mtd, *ppos, len, &retlen, kbuf); >+ ret = (*(mtd->write))(mtd, pos, len, &retlen, kbuf); > if (!ret) { >- *ppos += retlen; >+ pos += retlen; > total_retlen += retlen; > count -= retlen; > buf += retlen; >@@ -221,6 +229,7 @@ > > kfree(kbuf); > } >+ *ppos = pos; > > return total_retlen; > } /* mtd_write */ >diff -urN linux-2.4.21/drivers/oprofile/oprofilefs.c linux-2.4.21-fix/drivers/oprofile/oprofilefs.c >--- linux-2.4.21/drivers/oprofile/oprofilefs.c 2004-06-28 16:34:55.000000000 -0400 >+++ linux-2.4.21-fix/drivers/oprofile/oprofilefs.c 2004-06-28 17:01:06.000000000 -0400 >@@ -55,20 +55,22 @@ > ssize_t oprofilefs_str_to_user(char const * str, char * buf, size_t count, loff_t * offset) > { > size_t len = strlen(str); >+ loff_t n = *offset; >+ unsigned pos = n; > > if (!count) > return 0; > >- if (*offset > len) >+ if (pos != n || pos > len) > return 0; > >- if (count > len - *offset) >- count = len - *offset; >+ if (count > len - pos) >+ count = len - pos; > >- if (copy_to_user(buf, str + *offset, count)) >+ if (copy_to_user(buf, str + pos, count)) > return -EFAULT; > >- *offset += count; >+ *offset = pos + count; > > return count; > } >@@ -80,22 +82,24 @@ > { > char tmpbuf[TMPBUFSIZE]; > size_t maxlen; >+ loff_t n = *offset; >+ unsigned pos = n; > > if (!count) > return 0; > > maxlen = snprintf(tmpbuf, TMPBUFSIZE, "%lu\n", *val); > >- if (*offset > maxlen) >+ if (pos !=n || pos > maxlen) > return 0; > >- if (count > maxlen - *offset) >- count = maxlen - *offset; >+ if (count > maxlen - pos) >+ count = maxlen - pos; > >- if (copy_to_user(buf, tmpbuf + *offset, count)) >+ if (copy_to_user(buf, tmpbuf + pos, count)) > return -EFAULT; > >- *offset += count; >+ *offset = pos + count; > > return count; > } >diff -urN linux-2.4.21/drivers/pci/proc.c linux-2.4.21-fix/drivers/pci/proc.c >--- linux-2.4.21/drivers/pci/proc.c 2002-11-28 18:53:14.000000000 -0500 >+++ linux-2.4.21-fix/drivers/pci/proc.c 2004-06-28 17:01:06.000000000 -0400 >@@ -47,7 +47,8 @@ > const struct inode *ino = file->f_dentry->d_inode; > const struct proc_dir_entry *dp = ino->u.generic_ip; > struct pci_dev *dev = dp->data; >- unsigned int pos = *ppos; >+ loff_t n = *ppos; >+ unsigned pos = n; > unsigned int cnt, size; > > /* >@@ -63,7 +64,7 @@ > else > size = 64; > >- if (pos >= size) >+ if (pos != n || pos >= size) > return 0; > if (nbytes >= size) > nbytes = size; >@@ -129,14 +130,13 @@ > const struct inode *ino = file->f_dentry->d_inode; > const struct proc_dir_entry *dp = ino->u.generic_ip; > struct pci_dev *dev = dp->data; >- int pos = *ppos; >+ loff_t n = *ppos; >+ unsigned pos = n; > int cnt; > >- if (pos >= PCI_CFG_SPACE_SIZE) >+ if (pos != n || pos >= PCI_CFG_SPACE_SIZE) > return 0; >- if (nbytes >= PCI_CFG_SPACE_SIZE) >- nbytes = PCI_CFG_SPACE_SIZE; >- if (pos + nbytes > PCI_CFG_SPACE_SIZE) >+ if (nbytes > PCI_CFG_SPACE_SIZE - pos) > nbytes = PCI_CFG_SPACE_SIZE - pos; > cnt = nbytes; > >diff -urN linux-2.4.21/drivers/pnp/isapnp_proc.c linux-2.4.21-fix/drivers/pnp/isapnp_proc.c >--- linux-2.4.21/drivers/pnp/isapnp_proc.c 2002-11-28 18:53:14.000000000 -0500 >+++ linux-2.4.21-fix/drivers/pnp/isapnp_proc.c 2004-06-28 17:01:06.000000000 -0400 >@@ -102,6 +102,7 @@ > size_t count, loff_t * offset) > { > isapnp_info_buffer_t *buf; >+ loff_t pos = *offset; > long size = 0, size1; > int mode; > >@@ -111,15 +112,15 @@ > buf = (isapnp_info_buffer_t *) file->private_data; > if (!buf) > return -EIO; >- if (file->f_pos >= buf->size) >+ if (pos != (unsigned)pos || pos >= buf->size) > return 0; > size = buf->size < count ? buf->size : count; >- size1 = buf->size - file->f_pos; >+ size1 = buf->size - pos; > if (size1 < size) > size = size1; >- if (copy_to_user(buffer, buf->buffer + file->f_pos, size)) >+ if (copy_to_user(buffer, buf->buffer + pos, size)) > return -EFAULT; >- file->f_pos += size; >+ *offset = pos + size; > return size; > } > >@@ -128,6 +129,7 @@ > { > isapnp_info_buffer_t *buf; > long size = 0, size1; >+ loff_t pos = *offset; > int mode; > > mode = file->f_flags & O_ACCMODE; >@@ -136,19 +138,19 @@ > buf = (isapnp_info_buffer_t *) file->private_data; > if (!buf) > return -EIO; >- if (file->f_pos < 0) >+ if (pos < 0) > return -EINVAL; >- if (file->f_pos >= buf->len) >+ if (pos >= buf->len) > return -ENOMEM; > size = buf->len < count ? buf->len : count; >- size1 = buf->len - file->f_pos; >+ size1 = buf->len - pos; > if (size1 < size) > size = size1; >- if (copy_from_user(buf->buffer + file->f_pos, buffer, size)) >+ if (copy_from_user(buf->buffer + pos, buffer, size)) > return -EFAULT; >- if (buf->size < file->f_pos + size) >- buf->size = file->f_pos + size; >- file->f_pos += size; >+ if (buf->size < pos + size) >+ buf->size = pos + size; >+ *offset = pos + size; > return size; > } > >@@ -240,14 +242,13 @@ > struct inode *ino = file->f_dentry->d_inode; > struct proc_dir_entry *dp = ino->u.generic_ip; > struct pci_dev *dev = dp->data; >- int pos = *ppos; >+ loff_t n = *ppos; >+ unsigned pos = n; > int cnt, size = 256; > >- if (pos >= size) >+ if (pos != n || pos >= size) > return 0; >- if (nbytes >= size) >- nbytes = size; >- if (pos + nbytes > size) >+ if (nbytes > size - pos) > nbytes = size - pos; > cnt = nbytes; > >diff -urN linux-2.4.21/drivers/s390/block/dasd.c linux-2.4.21-fix/drivers/s390/block/dasd.c >--- linux-2.4.21/drivers/s390/block/dasd.c 2004-06-28 16:34:49.000000000 -0400 >+++ linux-2.4.21-fix/drivers/s390/block/dasd.c 2004-06-28 17:01:06.000000000 -0400 >@@ -4670,15 +4670,17 @@ > loff_t * offset) > { > loff_t len; >+ loff_t n = *offset; >+ unsigned pos = n; > tempinfo_t *p_info = (tempinfo_t *) file->private_data; > >- if (*offset >= p_info->len) { >+ if (n != pos || pos >= p_info->len) { > return 0; /* EOF */ > } else { >- len = MIN (user_len, (p_info->len - *offset)); >- if (copy_to_user (user_buf, &(p_info->data[*offset]), len)) >+ len = MIN (user_len, (p_info->len - pos)); >+ if (copy_to_user (user_buf, &(p_info->data[pos]), len)) > return -EFAULT; >- (*offset) += len; >+ *offset = pos + len; > return len; /* number of bytes "read" */ > } > } >diff -urN linux-2.4.21/drivers/s390/char/tape_char.c linux-2.4.21-fix/drivers/s390/char/tape_char.c >--- linux-2.4.21/drivers/s390/char/tape_char.c 2004-06-28 16:34:36.000000000 -0400 >+++ linux-2.4.21-fix/drivers/s390/char/tape_char.c 2004-06-28 17:01:06.000000000 -0400 >@@ -159,6 +159,7 @@ > struct tape_device *device; > struct tape_request *request; > size_t block_size; >+ loff_t pos = *ppos; > int rc; > > DBF_EVENT(6, "TCHAR:read\n"); >@@ -208,11 +209,13 @@ > if (rc == 0) { > rc = block_size - device->devstat.rescnt; > DBF_EVENT(6, "TCHAR:rbytes: %x\n", rc); >- filp->f_pos += rc; >+ pos += rc; > /* Copy data from idal buffer to user space. */ > if (idal_buffer_to_user(device->char_data.idal_buf, > data, rc) != 0) > rc = -EFAULT; >+ else >+ *ppos = pos; > } > tape_put_request(request); > return rc; >@@ -224,6 +227,7 @@ > ssize_t > tapechar_write(struct file *filp, const char *data, size_t count, loff_t *ppos) > { >+ loff_t pos = *ppos; > struct tape_device *device; > struct tape_request *request; > size_t block_size; >@@ -275,7 +279,7 @@ > break; > DBF_EVENT(6, "TCHAR:wbytes: %lx\n", > block_size - device->devstat.rescnt); >- filp->f_pos += block_size - device->devstat.rescnt; >+ pos += block_size - device->devstat.rescnt; > written += block_size - device->devstat.rescnt; > if (device->devstat.rescnt != 0) > break; >@@ -301,8 +305,10 @@ > * Since process_eov positions the tape in front of the written > * tapemark it doesn't hurt to write two marks again. > */ >- if(!rc) >+ if(!rc) { > device->required_tapemarks = 2; >+ *ppos = pos; >+ } > > return rc ? rc : written; > } >diff -urN linux-2.4.21/drivers/s390/net/ctcmain.c linux-2.4.21-fix/drivers/s390/net/ctcmain.c >--- linux-2.4.21/drivers/s390/net/ctcmain.c 2004-06-28 16:34:50.000000000 -0400 >+++ linux-2.4.21-fix/drivers/s390/net/ctcmain.c 2004-06-28 17:01:06.000000000 -0400 >@@ -2899,6 +2899,7 @@ > file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL); > if (file->private_data == NULL) > return -ENOMEM; >+ *(char *)file->private_data = '\0'; > MOD_INC_USE_COUNT; > return 0; > } >@@ -2964,6 +2965,7 @@ > ctc_priv *privptr; > ssize_t ret = 0; > char *p = sbuf; >+ loff_t pos = *off; > int l; > > if (!(dev = find_netdev_by_ino(ino))) >@@ -2973,19 +2975,19 @@ > > privptr = (ctc_priv *)dev->priv; > >- if (file->f_pos == 0) >+ if (!*sbuf || pos == 0) > sprintf(sbuf, "%d\n", privptr->channel[READ]->max_bufsize); > > l = strlen(sbuf); > p = sbuf; >- if (file->f_pos < l) { >- p += file->f_pos; >+ if (pos == (unsigned)pos && pos < l) { >+ p += pos; > l = strlen(p); > ret = (count > l) ? l : count; > if (copy_to_user(buf, p, ret)) > return -EFAULT; >+ *off = pos + ret; > } >- file->f_pos += ret; > return ret; > } > >@@ -2996,6 +2998,7 @@ > file->private_data = kmalloc(STATS_BUFSIZE, GFP_KERNEL); > if (file->private_data == NULL) > return -ENOMEM; >+ *(char *)file->private_data = '\0'; > MOD_INC_USE_COUNT; > return 0; > } >@@ -3035,6 +3038,7 @@ > ctc_priv *privptr; > ssize_t ret = 0; > char *p = sbuf; >+ loff_t pos = *off; > int l; > > if (!(dev = find_netdev_by_ino(ino))) >@@ -3044,7 +3048,7 @@ > > privptr = (ctc_priv *)dev->priv; > >- if (file->f_pos == 0) { >+ if (!*sbuf || pos == 0) { > p += sprintf(p, "Device FSM state: %s\n", > fsm_getstate_str(privptr->fsm)); > p += sprintf(p, "RX channel FSM state: %s\n", >@@ -3066,14 +3070,14 @@ > } > l = strlen(sbuf); > p = sbuf; >- if (file->f_pos < l) { >- p += file->f_pos; >+ if (pos == (unsigned)pos && pos < l) { >+ p += pos; > l = strlen(p); > ret = (count > l) ? l : count; > if (copy_to_user(buf, p, ret)) > return -EFAULT; >+ *off = pos + ret; > } >- file->f_pos += ret; > return ret; > } > >diff -urN linux-2.4.21/drivers/s390/net/netiucv.c linux-2.4.21-fix/drivers/s390/net/netiucv.c >--- linux-2.4.21/drivers/s390/net/netiucv.c 2004-06-28 16:34:48.000000000 -0400 >+++ linux-2.4.21-fix/drivers/s390/net/netiucv.c 2004-06-28 17:01:06.000000000 -0400 >@@ -1366,6 +1366,7 @@ > file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL); > if (file->private_data == NULL) > return -ENOMEM; >+ *(char *)file->private_data = '\0'; > MOD_INC_USE_COUNT; > return 0; > } >@@ -1431,6 +1432,7 @@ > netiucv_priv *privptr; > ssize_t ret = 0; > char *p = sbuf; >+ loff_t pos = *ppos; > int l; > > if (!(dev = find_netdev_by_ino(ino))) >@@ -1440,19 +1442,20 @@ > > privptr = (netiucv_priv *)dev->priv; > >- if (file->f_pos == 0) >+ if (!*sbuf || pos == 0) > sprintf(sbuf, "%d\n", privptr->conn->max_buffsize); > > l = strlen(sbuf); > p = sbuf; >- if (file->f_pos < l) { >- p += file->f_pos; >+ if (pos == (unsigned)pos && pos < l) { >+ p += pos; > l = strlen(p); > ret = (count > l) ? l : count; > if (copy_to_user(buf, p, ret)) > return -EFAULT; > } >- file->f_pos += ret; >+ pos += ret; >+ *ppos = pos; > return ret; > } > >@@ -1462,6 +1465,7 @@ > file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL); > if (file->private_data == NULL) > return -ENOMEM; >+ *(char *)file->private_data = '\0'; > MOD_INC_USE_COUNT; > return 0; > } >@@ -1526,6 +1530,7 @@ > netiucv_priv *privptr; > ssize_t ret = 0; > char *p = sbuf; >+ loff_t pos = *ppos; > int l; > > if (!(dev = find_netdev_by_ino(ino))) >@@ -1536,20 +1541,20 @@ > privptr = (netiucv_priv *)dev->priv; > > >- if (file->f_pos == 0) >+ if (!*sbuf || pos == 0) > sprintf(sbuf, "%s\n", > netiucv_printname(privptr->conn->userid)); > > l = strlen(sbuf); > p = sbuf; >- if (file->f_pos < l) { >- p += file->f_pos; >+ if (pos == (unsigned)pos && pos < l) { >+ p += pos; > l = strlen(p); > ret = (count > l) ? l : count; > if (copy_to_user(buf, p, ret)) > return -EFAULT; >+ *ppos = pos + ret; > } >- file->f_pos += ret; > return ret; > } > >@@ -1561,6 +1566,7 @@ > file->private_data = kmalloc(STATS_BUFSIZE, GFP_KERNEL); > if (file->private_data == NULL) > return -ENOMEM; >+ *(char *)file->private_data = '\0'; > MOD_INC_USE_COUNT; > return 0; > } >@@ -1591,6 +1597,7 @@ > netiucv_stat_read(struct file *file, char *buf, size_t count, loff_t *off) > { > unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; >+ loff_t pos = *ppos; > char *sbuf = (char *)file->private_data; > net_device *dev; > netiucv_priv *privptr; >@@ -1605,7 +1612,7 @@ > > privptr = (netiucv_priv *)dev->priv; > >- if (file->f_pos == 0) { >+ if (!*sbuf || pos == 0) { > p += sprintf(p, "Device FSM state: %s\n", > fsm_getstate_str(privptr->fsm)); > p += sprintf(p, "Connection FSM state: %s\n", >@@ -1629,14 +1636,14 @@ > } > l = strlen(sbuf); > p = sbuf; >- if (file->f_pos < l) { >- p += file->f_pos; >+ if (pos == (unsigned)pos && pos < l) { >+ p += pos; > l = strlen(p); > ret = (count > l) ? l : count; > if (copy_to_user(buf, p, ret)) > return -EFAULT; >+ *ppos = pos + ret; > } >- file->f_pos += ret; > return ret; > } > >diff -urN linux-2.4.21/drivers/s390/net/qeth.c linux-2.4.21-fix/drivers/s390/net/qeth.c >--- linux-2.4.21/drivers/s390/net/qeth.c 2004-06-28 16:35:32.000000000 -0400 >+++ linux-2.4.21-fix/drivers/s390/net/qeth.c 2004-06-28 17:01:06.000000000 -0400 >@@ -9891,7 +9891,7 @@ > int pos=0,end_pos; > char dbf_text[15]; > >- if (*offset>0) return user_len; >+ if (*offset) return user_len; > buffer=vmalloc(__max(user_len+1,QETH_DBF_MISC_LEN)); > if (buffer == NULL) > return -ENOMEM; >@@ -10407,14 +10407,16 @@ > { > loff_t len; > tempinfo_t *p_info = (tempinfo_t *) file->private_data; >+ loff_t n = *offset; >+ unsigned long pos = n; > >- if (*offset >= p_info->len) { >+ if (pos != n || pos >= p_info->len) { > return 0; > } else { >- len = __min(user_len, (p_info->len - *offset)); >- if (copy_to_user (user_buf, &(p_info->data[*offset]), len)) >+ len = __min(user_len, (p_info->len - pos)); >+ if (copy_to_user (user_buf, &(p_info->data[pos]), len)) > return -EFAULT; >- (*offset) += len; >+ *offset = pos + len; > return len; > } > } >@@ -10449,7 +10451,7 @@ > qeth_card_t *card; > #define BUFFER_LEN (10+32+1+5+1+DEV_NAME_LEN+1) > >- if (*offset>0) return user_len; >+ if (*offset) return user_len; > buffer=vmalloc(__max(__max(user_len+1,BUFFER_LEN),QETH_DBF_MISC_LEN)); > > if (buffer == NULL) >@@ -10573,7 +10575,7 @@ > PRINT_ERR("unknown ipato information command\n"); > out: > vfree(buffer); >- *offset = *offset + user_len; >+ *offset = user_len; > #undef BUFFER_LEN > return user_len; > } >diff -urN linux-2.4.21/drivers/s390/s390io.c linux-2.4.21-fix/drivers/s390/s390io.c >--- linux-2.4.21/drivers/s390/s390io.c 2004-06-28 16:34:49.000000000 -0400 >+++ linux-2.4.21-fix/drivers/s390/s390io.c 2004-06-28 17:01:06.000000000 -0400 >@@ -8545,14 +8545,16 @@ > { > loff_t len; > tempinfo_t *p_info = (tempinfo_t *) file->private_data; >+ loff_t n = *offset; >+ unsigned long pos = n; > >- if (*offset >= p_info->len) { >+ if (pos != n || pos >= p_info->len) { > return 0; > } else { >- len = MIN (user_len, (p_info->len - *offset)); >- if (copy_to_user (user_buf, &(p_info->data[*offset]), len)) >+ len = MIN (user_len, (p_info->len - pos)); >+ if (copy_to_user (user_buf, &(p_info->data[pos]), len)) > return -EFAULT; >- (*offset) += len; >+ *offset = pos + len; > return len; > } > } >@@ -9340,14 +9342,16 @@ > { > loff_t len; > tempinfo_t *p_info = (tempinfo_t *) file->private_data; >+ loff_t n = *offset; >+ unsigned long pos = n; > >- if ( *offset>=p_info->len) { >+ if ( n != pos || pos >= p_info->len) { > return 0; > } else { >- len = MIN(user_len, (p_info->len - *offset)); >- if (copy_to_user( user_buf, &(p_info->data[*offset]), len)) >+ len = MIN(user_len, (p_info->len - pos)); >+ if (copy_to_user( user_buf, &(p_info->data[pos]), len)) > return -EFAULT; >- (* offset) += len; >+ *offset = pos + len; > return len; > } > } >diff -urN linux-2.4.21/drivers/s390/scsi/zfcp.c linux-2.4.21-fix/drivers/s390/scsi/zfcp.c >--- linux-2.4.21/drivers/s390/scsi/zfcp.c 2004-06-28 16:35:33.000000000 -0400 >+++ linux-2.4.21-fix/drivers/s390/scsi/zfcp.c 2004-06-28 17:01:06.000000000 -0400 >@@ -5809,6 +5809,7 @@ > > loff_t len; > procbuf_t *pbuf = (procbuf_t *) file->private_data; >+ loff_t pos = *offset; > > ZFCP_LOG_TRACE( > "enter (file=0x%lx user_buf=0x%lx " >@@ -5816,20 +5817,20 @@ > (unsigned long)file, > (unsigned long)user_buf, > user_len, >- (unsigned long)*offset); >+ (unsigned long)pos); > >- if ( *offset>=pbuf->len) { >+ if (pos != (unsigned long)pos || pos >= pbuf->len) { > return 0; > } else { >- len = min(user_len, (unsigned long)(pbuf->len - *offset)); >- if (copy_to_user( user_buf, &(pbuf->buf[*offset]), len)) >+ len = min(user_len, (unsigned long)(pbuf->len - pos)); >+ if (copy_to_user( user_buf, &(pbuf->buf[pos]), len)) > return -EFAULT; >- (* offset) += len; >+ *offset = pos + len; > return len; > } > > ZFCP_LOG_TRACE("Size-offset is %ld, user_len is %ld\n ", >- ((unsigned long)(pbuf->len - *offset)), >+ ((unsigned long)(pbuf->len - pos)), > user_len); > > ZFCP_LOG_TRACE("exit (%Li)\n", len); >@@ -6247,6 +6248,7 @@ > zfcp_adapter_t *adapter=NULL; > zfcp_port_t *port=NULL; > zfcp_unit_t *unit=NULL; >+ loff_t pos = *offset; > > /* Is used when we don't have a 0 offset, which cannot happen > * during the first call >@@ -6259,16 +6261,16 @@ > (unsigned long)file, > (unsigned long)user_buf, > user_len, >- *offset); >+ pos); > > /* Do not overwrite proc-buffer */ > user_len = min(user_len, ZFCP_MAX_PROC_SIZE); > size=0; >- if((*offset)==0) { >+ if(pos==0) { > current_unit=0; > line_offset=0; > } else { >- current_unit = (*offset); >+ current_unit = pos; > line_offset = do_div(current_unit, item_size); > ZFCP_LOG_TRACE("item_size %ld, current_unit %Ld, line_offset %Ld\n", > item_size, >@@ -6322,7 +6324,7 @@ > } > > out: >- (*offset) += user_len; >+ *offset = pos + user_len; > > ZFCP_LOG_TRACE("exit (%li)\n", user_len); > >@@ -7051,6 +7053,7 @@ > > loff_t len; > procbuf_t *pbuf = (procbuf_t *) file->private_data; >+ loff_t pos = *offset; > > ZFCP_LOG_TRACE( > "enter (file=0x%lx user_buf=0x%lx " >@@ -7058,15 +7061,15 @@ > (unsigned long)file, > (unsigned long)user_buf, > user_len, >- (unsigned long)*offset); >+ (unsigned long)pos); > >- if ( *offset>=pbuf->len) { >+ if ( pos != (unsigned long)pos || pos >= pbuf->len) { > return 0; > } else { >- len = min(user_len, (unsigned long)(pbuf->len - *offset)); >- if (copy_to_user( user_buf, &(pbuf->buf[*offset]), len)) >+ len = min(user_len, (unsigned long)(pbuf->len - pos)); >+ if (copy_to_user( user_buf, &(pbuf->buf[pos]), len)) > return -EFAULT; >- (* offset) += len; >+ *offset = pos + len; > return len; > } > >@@ -7205,6 +7208,7 @@ > > loff_t len; > procbuf_t *pbuf = (procbuf_t *) file->private_data; >+ loff_t pos = *offset; > > ZFCP_LOG_TRACE( > "enter (file=0x%lx user_buf=0x%lx " >@@ -7212,15 +7216,15 @@ > (unsigned long)file, > (unsigned long)user_buf, > user_len, >- (unsigned long)*offset); >+ (unsigned long)pos); > >- if ( *offset>=pbuf->len) { >+ if (pos != (unsigned long)pos || pos >= pbuf->len) { > return 0; > } else { >- len = min(user_len, (unsigned long)(pbuf->len - *offset)); >- if (copy_to_user( user_buf, &(pbuf->buf[*offset]), len)) >+ len = min(user_len, (unsigned long)(pbuf->len - pos)); >+ if (copy_to_user( user_buf, &(pbuf->buf[pos]), len)) > return -EFAULT; >- (* offset) += len; >+ *offset = pos + len; > return len; > } > >@@ -7607,6 +7611,7 @@ > > loff_t len; > procbuf_t *pbuf = (procbuf_t *) file->private_data; >+ loff_t pos = *offset; > > ZFCP_LOG_TRACE( > "enter (file=0x%lx user_buf=0x%lx " >@@ -7614,20 +7619,20 @@ > (unsigned long)file, > (unsigned long)user_buf, > user_len, >- (unsigned long)*offset); >+ (unsigned long)pos); > >- if ( *offset>=pbuf->len) { >+ if (pos != (unsigned long)pos || pos >= pbuf->len) { > return 0; > } else { >- len = min(user_len, (unsigned long)(pbuf->len - *offset)); >- if (copy_to_user( user_buf, &(pbuf->buf[*offset]), len)) >+ len = min(user_len, (unsigned long)(pbuf->len - pos)); >+ if (copy_to_user( user_buf, &(pbuf->buf[pos]), len)) > return -EFAULT; >- (* offset) += len; >+ *offset = pos + len; > return len; > } > > ZFCP_LOG_TRACE("Size-offset is %ld, user_len is %ld\n ", >- ((unsigned long)(pbuf->len - *offset)), >+ ((unsigned long)(pbuf->len - pos)), > user_len); > > ZFCP_LOG_TRACE("exit (%Li)\n", len); >diff -urN linux-2.4.21/drivers/sbus/char/flash.c linux-2.4.21-fix/drivers/sbus/char/flash.c >--- linux-2.4.21/drivers/sbus/char/flash.c 2004-06-28 16:35:01.000000000 -0400 >+++ linux-2.4.21-fix/drivers/sbus/char/flash.c 2004-06-28 17:01:06.000000000 -0400 >@@ -105,9 +105,12 @@ > flash_read(struct file * file, char * buf, > size_t count, loff_t *ppos) > { >- unsigned long p = file->f_pos; >+ unsigned long p = *ppos; > int i; > >+ if (p > flash.read_size) >+ return 0; >+ > if (count > flash.read_size - p) > count = flash.read_size - p; > >@@ -118,7 +121,7 @@ > buf++; > } > >- file->f_pos += count; >+ *ppos = p + count; > return count; > } > >diff -urN linux-2.4.21/drivers/scsi/osst.c linux-2.4.21-fix/drivers/scsi/osst.c >--- linux-2.4.21/drivers/scsi/osst.c 2001-12-21 12:41:55.000000000 -0500 >+++ linux-2.4.21-fix/drivers/scsi/osst.c 2004-06-28 17:01:06.000000000 -0400 >@@ -3082,6 +3082,7 @@ > ST_mode * STm; > ST_partstat * STps; > int dev = TAPE_NR(inode->i_rdev); >+ loff_t pos = *ppos; > > STp = os_scsi_tapes[dev]; > >@@ -3299,7 +3300,7 @@ > if (i == (-ENOSPC)) { > transfer = STp->buffer->writing; /* FIXME -- check this logic */ > if (transfer <= do_count) { >- filp->f_pos += do_count - transfer; >+ pos += do_count - transfer; > count -= do_count - transfer; > if (STps->drv_block >= 0) { > STps->drv_block += (do_count - transfer) / STp->block_size; >@@ -3337,7 +3338,7 @@ > goto out; > } > >- filp->f_pos += do_count; >+ pos += do_count; > b_point += do_count; > count -= do_count; > if (STps->drv_block >= 0) { >@@ -3359,7 +3360,7 @@ > if (STps->drv_block >= 0) { > STps->drv_block += blks; > } >- filp->f_pos += count; >+ pos += count; > count = 0; > } > >@@ -3389,6 +3390,7 @@ > retval = total; > > out: >+ *ppos = pos; > if (SRpnt != NULL) scsi_release_request(SRpnt); > > up(&STp->lock); >@@ -3409,6 +3411,7 @@ > ST_partstat * STps; > Scsi_Request *SRpnt = NULL; > int dev = TAPE_NR(inode->i_rdev); >+ loff_t pos = *ppos; > > STp = os_scsi_tapes[dev]; > >@@ -3534,7 +3537,7 @@ > } > STp->logical_blk_num += transfer / STp->block_size; > STps->drv_block += transfer / STp->block_size; >- filp->f_pos += transfer; >+ pos += transfer; > buf += transfer; > total += transfer; > } >@@ -3573,6 +3576,7 @@ > retval = total; > > out: >+ *ppos = pos; > if (SRpnt != NULL) scsi_release_request(SRpnt); > > up(&STp->lock); >diff -urN linux-2.4.21/drivers/scsi/st.c linux-2.4.21-fix/drivers/scsi/st.c >--- linux-2.4.21/drivers/scsi/st.c 2004-06-28 16:35:18.000000000 -0400 >+++ linux-2.4.21-fix/drivers/scsi/st.c 2004-06-28 17:01:06.000000000 -0400 >@@ -1202,6 +1202,8 @@ > ST_mode *STm; > ST_partstat *STps; > int dev = TAPE_NR(inode->i_rdev); >+ loff_t pos = *ppos; >+ loff_t pos = *ppos; > > read_lock(&st_dev_arr_lock); > STp = scsi_tapes[dev]; >@@ -1433,7 +1435,7 @@ > residual *= STp->block_size; > if (residual <= do_count) { > /* Within the data in this write() */ >- filp->f_pos += do_count - residual; >+ pos += do_count - residual; > count -= do_count - residual; > if (STps->drv_block >= 0) { > if (STp->block_size == 0 && >@@ -1489,7 +1491,7 @@ > retval = total - count; > goto out; > } >- filp->f_pos += do_count; >+ pos += do_count; > b_point += do_count; > count -= do_count; > if (STps->drv_block >= 0) { >@@ -1508,7 +1510,7 @@ > retval = i; > goto out; > } >- filp->f_pos += count; >+ pos += count; > count = 0; > } > >@@ -1543,6 +1545,7 @@ > retval = total - count; > > out: >+ *ppos = pos; > if (SRpnt != NULL) > scsi_release_request(SRpnt); > up(&STp->lock); >@@ -1743,6 +1746,7 @@ > ST_mode *STm; > ST_partstat *STps; > int dev = TAPE_NR(inode->i_rdev); >+ loff_t pos = *ppos; > > read_lock(&st_dev_arr_lock); > STp = scsi_tapes[dev]; >@@ -1887,7 +1891,7 @@ > retval = i; > goto out; > } >- filp->f_pos += transfer; >+ pos += transfer; > buf += transfer; > total += transfer; > } >@@ -1917,6 +1921,7 @@ > retval = total; > > out: >+ *ppos = pos; > if (SRpnt != NULL) { > scsi_release_request(SRpnt); > SRpnt = NULL; >diff -urN linux-2.4.21/drivers/usb/brlvger.c linux-2.4.21-fix/drivers/usb/brlvger.c >--- linux-2.4.21/drivers/usb/brlvger.c 2002-11-28 18:53:14.000000000 -0500 >+++ linux-2.4.21-fix/drivers/usb/brlvger.c 2004-06-28 17:01:06.000000000 -0400 >@@ -596,6 +596,9 @@ > > off = *pos; > >+ if (off < 0) >+ return -EINVAL; >+ > if(off > priv->plength) > return -ESPIPE;; > >diff -urN linux-2.4.21/drivers/usb/devio.c linux-2.4.21-fix/drivers/usb/devio.c >--- linux-2.4.21/drivers/usb/devio.c 2004-06-28 16:35:11.000000000 -0400 >+++ linux-2.4.21-fix/drivers/usb/devio.c 2004-06-28 17:01:06.000000000 -0400 >@@ -80,7 +80,7 @@ > struct dev_state *ps = (struct dev_state *)file->private_data; > ssize_t ret = 0; > unsigned len; >- loff_t pos; >+ loff_t pos, last; > int i; > > pos = *ppos; >@@ -102,37 +102,38 @@ > goto err; > } > >- *ppos += len; >+ pos += len; > buf += len; > nbytes -= len; > ret += len; > } > >- pos = sizeof(struct usb_device_descriptor); >+ last = sizeof(struct usb_device_descriptor); > for (i = 0; nbytes && i < ps->dev->descriptor.bNumConfigurations; i++) { > struct usb_config_descriptor *config = > (struct usb_config_descriptor *)ps->dev->rawdescriptors[i]; > unsigned int length = le16_to_cpu(config->wTotalLength); > >- if (*ppos < pos + length) { >- len = length - (*ppos - pos); >+ if (pos < last + length) { >+ len = length - (pos - last); > if (len > nbytes) > len = nbytes; > > if (copy_to_user(buf, >- ps->dev->rawdescriptors[i] + (*ppos - pos), len)) { >+ ps->dev->rawdescriptors[i] + (pos - last), len)) { > ret = -EFAULT; > goto err; > } > >- *ppos += len; >+ pos += len; > buf += len; > nbytes -= len; > ret += len; > } > >- pos += length; >+ last += length; > } >+ *ppos = pos; > > err: > up_read(&ps->devsem); >diff -urN linux-2.4.21/drivers/usb/drivers.c linux-2.4.21-fix/drivers/usb/drivers.c >--- linux-2.4.21/drivers/usb/drivers.c 2000-04-26 18:22:55.000000000 -0400 >+++ linux-2.4.21-fix/drivers/usb/drivers.c 2004-06-28 17:01:06.000000000 -0400 >@@ -52,9 +52,10 @@ > struct list_head *tmp = usb_driver_list.next; > char *page, *start, *end; > ssize_t ret = 0; >- unsigned int pos, len; >+ loff_t n = *ppos; >+ unsigned int pos = n, len; > >- if (*ppos < 0) >+ if (pos != n) > return -EINVAL; > if (nbytes <= 0) > return 0; >@@ -64,7 +65,6 @@ > return -ENOMEM; > start = page; > end = page + (PAGE_SIZE - 100); >- pos = *ppos; > for (; tmp != &usb_driver_list; tmp = tmp->next) { > struct usb_driver *driver = list_entry(tmp, struct usb_driver, driver_list); > int minor = driver->fops ? driver->minor : -1; >@@ -88,7 +88,7 @@ > if (copy_to_user(buf, page + pos, len)) > ret = -EFAULT; > else >- *ppos += len; >+ *ppos = pos + len; > } > free_page((unsigned long)page); > return ret; >diff -urN linux-2.4.21/drivers/usb/host/uhci-debug.h linux-2.4.21-fix/drivers/usb/host/uhci-debug.h >--- linux-2.4.21/drivers/usb/host/uhci-debug.h 2003-06-13 10:51:36.000000000 -0400 >+++ linux-2.4.21-fix/drivers/usb/host/uhci-debug.h 2004-06-28 17:01:06.000000000 -0400 >@@ -530,16 +530,14 @@ > loff_t *ppos) > { > struct uhci_proc *up = file->private_data; >- unsigned int pos; >+ loff_t n = *ppos; >+ unsigned int pos = n; > unsigned int size; > >- pos = *ppos; > size = up->size; >- if (pos >= size) >+ if (pos != n || pos >= size) > return 0; >- if (nbytes >= size) >- nbytes = size; >- if (pos + nbytes > size) >+ if (nbytes > size - pos) > nbytes = size - pos; > > if (!access_ok(VERIFY_WRITE, buf, nbytes)) >@@ -547,7 +545,7 @@ > > copy_to_user(buf, up->data + pos, nbytes); > >- *ppos += nbytes; >+ ppos = pos + nbytes; > > return nbytes; > } >diff -urN linux-2.4.21/drivers/video/fbmem.c linux-2.4.21-fix/drivers/video/fbmem.c >--- linux-2.4.21/drivers/video/fbmem.c 2004-06-28 16:35:01.000000000 -0400 >+++ linux-2.4.21-fix/drivers/video/fbmem.c 2004-06-28 17:01:06.000000000 -0400 >@@ -403,9 +403,7 @@ > fb->fb_get_fix(&fix,PROC_CONSOLE(info), info); > if (p >= fix.smem_len) > return 0; >- if (count >= fix.smem_len) >- count = fix.smem_len; >- if (count + p > fix.smem_len) >+ if (count > fix.smem_len - p) > count = fix.smem_len - p; > if (count) { > char *base_addr; >@@ -414,7 +412,7 @@ > count -= copy_to_user(buf, base_addr+p, count); > if (!count) > return -EFAULT; >- *ppos += count; >+ *ppos = p + count; > } > return count; > } >@@ -436,10 +434,8 @@ > fb->fb_get_fix(&fix, PROC_CONSOLE(info), info); > if (p > fix.smem_len) > return -ENOSPC; >- if (count >= fix.smem_len) >- count = fix.smem_len; > err = 0; >- if (count + p > fix.smem_len) { >+ if (count > fix.smem_len - p) { > count = fix.smem_len - p; > err = -ENOSPC; > } >@@ -448,7 +444,7 @@ > > base_addr = info->disp->screen_base; > count -= copy_from_user(base_addr+p, buf, count); >- *ppos += count; >+ *ppos = p + count; > err = -EFAULT; > } > if (count) >diff -urN linux-2.4.21/drivers/zorro/proc.c linux-2.4.21-fix/drivers/zorro/proc.c >--- linux-2.4.21/drivers/zorro/proc.c 2002-11-28 18:53:15.000000000 -0500 >+++ linux-2.4.21-fix/drivers/zorro/proc.c 2004-06-28 17:01:06.000000000 -0400 >@@ -50,11 +50,9 @@ > struct ConfigDev cd; > loff_t pos = *ppos; > >- if (pos >= sizeof(struct ConfigDev)) >+ if (pos < 0 || pos >= sizeof(struct ConfigDev)) > return 0; >- if (nbytes >= sizeof(struct ConfigDev)) >- nbytes = sizeof(struct ConfigDev); >- if (pos + nbytes > sizeof(struct ConfigDev)) >+ if (nbytes > sizeof(struct ConfigDev) - pos) > nbytes = sizeof(struct ConfigDev) - pos; > > /* Construct a ConfigDev */ >@@ -67,7 +65,7 @@ > > if (copy_to_user(buf, &cd, nbytes)) > return -EFAULT; >- *ppos += nbytes; >+ *ppos = pos + nbytes; > > return nbytes; > } >diff -urN linux-2.4.21/fs/devfs/base.c linux-2.4.21-fix/fs/devfs/base.c >--- linux-2.4.21/fs/devfs/base.c 2002-11-28 18:53:15.000000000 -0500 >+++ linux-2.4.21-fix/fs/devfs/base.c 2004-06-28 17:01:06.000000000 -0400 >@@ -3312,7 +3312,7 @@ > { > int done = FALSE; > int ival; >- loff_t pos, devname_offset, tlen, rpos; >+ loff_t pos, devname_offset, tlen, rpos, old_pos; > devfs_handle_t de; > struct devfsd_buf_entry *entry; > struct fs_info *fs_info = file->f_dentry->d_inode->i_sb->u.generic_sbp; >@@ -3363,8 +3363,8 @@ > info->namelen = DEVFS_PATHLEN - pos - 1; > if (info->mode == 0) info->mode = de->mode; > devname_offset = info->devname - (char *) info; >- rpos = *ppos; >- if (rpos < devname_offset) >+ old_pos = rpos = *ppos; >+ if (rpos >= 0 && rpos < devname_offset) > { > /* Copy parts of the header */ > tlen = devname_offset - rpos; >@@ -3390,7 +3390,7 @@ > } > rpos += tlen; > } >- tlen = rpos - *ppos; >+ tlen = rpos - old_pos; > if (done) > { > devfs_handle_t parent; >@@ -3504,16 +3504,17 @@ > loff_t *ppos) > { > ssize_t num; >+ loff_t n = *ppos; > char txt[80]; > > num = sprintf (txt, "Number of entries: %u number of bytes: %u\n", > stat_num_entries, stat_num_bytes) + 1; > /* Can't seek (pread) on this device */ > if (ppos != &file->f_pos) return -ESPIPE; >- if (*ppos >= num) return 0; >- if (*ppos + len > num) len = num - *ppos; >- if ( copy_to_user (buf, txt + *ppos, len) ) return -EFAULT; >- *ppos += len; >+ if (n != (unsigned)n || n >= num) return 0; >+ if (len > num - n) len = num - n; >+ if ( copy_to_user (buf, txt + n, len) ) return -EFAULT; >+ *ppos = n + len; > return len; > } /* End Function stat_read */ > #endif >diff -urN linux-2.4.21/fs/hfs/file.c linux-2.4.21-fix/fs/hfs/file.c >--- linux-2.4.21/fs/hfs/file.c 2002-02-25 14:38:08.000000000 -0500 >+++ linux-2.4.21-fix/fs/hfs/file.c 2004-06-28 17:01:06.000000000 -0400 >@@ -150,7 +150,7 @@ > return -EINVAL; > } > pos = *ppos; >- if (pos >= HFS_FORK_MAX) { >+ if (pos < 0 || pos >= HFS_FORK_MAX) { > return 0; > } > size = inode->i_size; >@@ -167,7 +167,7 @@ > } > if ((read = hfs_do_read(inode, HFS_I(inode)->fork, pos, > buf, left, filp->f_reada != 0)) > 0) { >- *ppos += read; >+ *ppos = pos + read; > filp->f_reada = 1; > } > >@@ -197,7 +197,7 @@ > > pos = (filp->f_flags & O_APPEND) ? inode->i_size : *ppos; > >- if (pos >= HFS_FORK_MAX) { >+ if (pos < 0 || pos >= HFS_FORK_MAX) { > return 0; > } > if (count > HFS_FORK_MAX) { >@@ -207,8 +207,8 @@ > pos += written; > > *ppos = pos; >- if (*ppos > inode->i_size) { >- inode->i_size = *ppos; >+ if (pos > inode->i_size) { >+ inode->i_size = pos; > mark_inode_dirty(inode); > } > >diff -urN linux-2.4.21/fs/hfs/file_cap.c linux-2.4.21-fix/fs/hfs/file_cap.c >--- linux-2.4.21/fs/hfs/file_cap.c 2001-09-10 10:31:25.000000000 -0400 >+++ linux-2.4.21-fix/fs/hfs/file_cap.c 2004-06-28 17:01:06.000000000 -0400 >@@ -191,7 +191,7 @@ > hfs_rwarg_t count, loff_t *ppos) > { > struct inode *inode = filp->f_dentry->d_inode; >- hfs_u32 pos; >+ hfs_u32 pos, end; > > if (!S_ISREG(inode->i_mode)) { > hfs_warn("hfs_file_write: mode = %07o\n", inode->i_mode); >@@ -207,14 +207,14 @@ > return 0; > } > >- *ppos += count; >- if (*ppos > HFS_FORK_MAX) { >- *ppos = HFS_FORK_MAX; >+ end = pos + count; >+ if (end > HFS_FORK_MAX) { >+ end = HFS_FORK_MAX; > count = HFS_FORK_MAX - pos; > } > >- if (*ppos > inode->i_size) >- inode->i_size = *ppos; >+ if (end > inode->i_size) >+ inode->i_size = end; > > /* Only deal with the part we store in memory */ > if (pos < sizeof(struct hfs_cap_info)) { >@@ -272,6 +272,7 @@ > } > } > >+ *ppos = end; > inode->i_mtime = inode->i_ctime = CURRENT_TIME; > mark_inode_dirty(inode); > return count; >diff -urN linux-2.4.21/fs/hfs/file_hdr.c linux-2.4.21-fix/fs/hfs/file_hdr.c >--- linux-2.4.21/fs/hfs/file_hdr.c 2001-08-12 13:56:56.000000000 -0400 >+++ linux-2.4.21-fix/fs/hfs/file_hdr.c 2004-06-28 17:01:06.000000000 -0400 >@@ -384,7 +384,7 @@ > struct hfs_cat_entry *entry = HFS_I(inode)->entry; > const struct hfs_hdr_layout *layout; > off_t start, length, offset; >- off_t pos = *ppos; >+ loff_t pos = *ppos; > int left, lcv, read = 0; > > if (!S_ISREG(inode->i_mode)) { >@@ -399,7 +399,7 @@ > } > > /* Adjust count to fit within the bounds of the file */ >- if ((pos >= inode->i_size) || (count <= 0)) { >+ if (pos != (unsigned)pos || pos >= inode->i_size || count <= 0) { > return 0; > } else if (count > inode->i_size - pos) { > count = inode->i_size - pos; >@@ -646,7 +646,7 @@ > hfs_warn("hfs_hdr_write: mode = %07o\n", inode->i_mode); > return -EINVAL; > } >- if (count <= 0) { >+ if (count <= 0 || pos != (unsigned)pos) { > return 0; > } > >diff -urN linux-2.4.21/fs/openpromfs/inode.c linux-2.4.21-fix/fs/openpromfs/inode.c >--- linux-2.4.21/fs/openpromfs/inode.c 2001-12-21 12:42:03.000000000 -0500 >+++ linux-2.4.21-fix/fs/openpromfs/inode.c 2004-06-28 17:01:06.000000000 -0400 >@@ -69,17 +69,18 @@ > size_t count, loff_t *ppos) > { > struct inode *inode = file->f_dentry->d_inode; >+ loff_t pos = *ppos; > char buffer[10]; > > if (count < 0 || !inode->u.generic_ip) > return -EINVAL; > sprintf (buffer, "%8.8x\n", (u32)(long)(inode->u.generic_ip)); >- if (file->f_pos >= 9) >+ if (pos != (unsigned)pos || pos >= 9) > return 0; >- if (count > 9 - file->f_pos) >- count = 9 - file->f_pos; >- copy_to_user(buf, buffer + file->f_pos, count); >- file->f_pos += count; >+ if (count > 9 - pos) >+ count = 9 - pos; >+ copy_to_user(buf, buffer + pos, count); >+ *ppos = pos + count; > return count; > } > >@@ -87,6 +88,7 @@ > size_t count, loff_t *ppos) > { > struct inode *inode = filp->f_dentry->d_inode; >+ loff_t pos = *ppos; > int i, j, k; > u32 node; > char *p, *s; >@@ -94,7 +96,7 @@ > openprom_property *op; > char buffer[64]; > >- if (filp->f_pos >= 0xffffff) >+ if (pos < 0 || pos >= 0xffffff) > return -EINVAL; > if (!filp->private_data) { > node = nodes[(u16)((long)inode->u.generic_ip)].node; >@@ -180,7 +182,7 @@ > } else { > i = (op->len << 1) + 1; > } >- k = filp->f_pos; >+ k = pos; > if (k >= i) return 0; > if (count > i - k) count = i - k; > if (op->flag & OPP_STRING) { >@@ -196,16 +198,16 @@ > j = count; > > if (j >= 0) { >- copy_to_user(buf + k - filp->f_pos, >+ copy_to_user(buf + k - pos, > op->value + k - 1, j); > count -= j; > k += j; > } > > if (count) >- __put_user('\'', &buf [k++ - filp->f_pos]); >+ __put_user('\'', &buf [k++ - pos]); > if (count > 1) >- __put_user('\n', &buf [k++ - filp->f_pos]); >+ __put_user('\n', &buf [k++ - pos]); > > } else if (op->flag & OPP_STRINGLIST) { > char *tmp; >@@ -273,47 +275,48 @@ > > if ((k < i - 1) && (k & 1)) { > sprintf (buffer, "%02x", *(op->value + (k >> 1))); >- __put_user(buffer[1], &buf[k++ - filp->f_pos]); >+ __put_user(buffer[1], &buf[k++ - pos]); > count--; > } > > for (; (count > 1) && (k < i - 1); k += 2) { > sprintf (buffer, "%02x", *(op->value + (k >> 1))); >- copy_to_user (buf + k - filp->f_pos, buffer, 2); >+ copy_to_user (buf + k - pos, buffer, 2); > count -= 2; > } > > if (count && (k < i - 1)) { > sprintf (buffer, "%02x", *(op->value + (k >> 1))); >- __put_user(buffer[0], &buf[k++ - filp->f_pos]); >+ __put_user(buffer[0], &buf[k++ - pos]); > count--; > } > > if (count) >- __put_user('\n', &buf [k++ - filp->f_pos]); >+ __put_user('\n', &buf [k++ - pos]); > } >- count = k - filp->f_pos; >- filp->f_pos = k; >+ count = k - pos; >+ *ppos = k; > return count; > } > > static ssize_t property_write(struct file *filp, const char *buf, > size_t count, loff_t *ppos) > { >+ loff_t pos = *ppos; > int i, j, k; > char *p; > u32 *q; > void *b; > openprom_property *op; > >- if (filp->f_pos >= 0xffffff) >+ if (pos < 0 || pos >= 0xffffff) > return -EINVAL; > if (!filp->private_data) { > i = property_read (filp, NULL, 0, 0); > if (i) > return i; > } >- k = filp->f_pos; >+ k = pos; > op = (openprom_property *)filp->private_data; > if (!(op->flag & OPP_STRING)) { > u32 *first, *last; >@@ -433,7 +436,8 @@ > op->len = i; > } else > op->len = i; >- filp->f_pos += count; >+ pos += count; >+ *ppos = pos; > } > write_try_string: > if (!(op->flag & OPP_BINARY)) { >@@ -450,7 +454,8 @@ > op->flag |= OPP_QUOTED; > buf++; > count--; >- filp->f_pos++; >+ pos++; >+ *ppos = pos; > if (!count) { > op->flag |= OPP_STRING; > return 1; >@@ -459,9 +464,9 @@ > op->flag |= OPP_NOTQUOTED; > } > op->flag |= OPP_STRING; >- if (op->alloclen <= count + filp->f_pos) { >+ if (op->alloclen <= count + pos) { > b = kmalloc (sizeof (openprom_property) >- + 2 * (count + filp->f_pos), GFP_KERNEL); >+ + 2 * (count + pos), GFP_KERNEL); > if (!b) > return -ENOMEM; > memcpy (b, filp->private_data, >@@ -469,14 +474,14 @@ > + strlen (op->name) + op->alloclen); > memset (((char *)b) + sizeof (openprom_property) > + strlen (op->name) + op->alloclen, >- 0, 2*(count - filp->f_pos) - op->alloclen); >+ 0, 2*(count - pos) - op->alloclen); > op = (openprom_property *)b; >- op->alloclen = 2*(count + filp->f_pos); >+ op->alloclen = 2*(count + pos); > b = filp->private_data; > filp->private_data = (void *)op; > kfree (b); > } >- p = op->value + filp->f_pos - ((op->flag & OPP_QUOTED) ? 1 : 0); >+ p = op->value + pos - ((op->flag & OPP_QUOTED) ? 1 : 0); > copy_from_user (p, buf, count); > op->flag |= OPP_DIRTY; > for (i = 0; i < count; i++, p++) >@@ -486,17 +491,19 @@ > } > if (i < count) { > op->len = p - op->value; >- filp->f_pos += i + 1; >+ pos += i + 1; >+ *ppos = pos; > if ((p > op->value) && (op->flag & OPP_QUOTED) > && (*(p - 1) == '\'')) > op->len--; > } else { > if (p - op->value > op->len) > op->len = p - op->value; >- filp->f_pos += count; >+ pos += count; >+ *ppos = pos; > } > } >- return filp->f_pos - k; >+ return pos - k; > } > > int property_release (struct inode *inode, struct file *filp) >diff -urN linux-2.4.21/fs/proc/array.c linux-2.4.21-fix/fs/proc/array.c >--- linux-2.4.21/fs/proc/array.c 2004-06-28 16:35:24.000000000 -0400 >+++ linux-2.4.21-fix/fs/proc/array.c 2004-06-28 17:01:06.000000000 -0400 >@@ -653,15 +653,17 @@ > struct vm_area_struct * map; > char *tmp, *kbuf; > long retval; >- int off, lineno, loff; >+ int lineno, loff; >+ unsigned off; >+ loff_t pos = *ppos; > > /* reject calls with out of range parameters immediately */ > retval = 0; >- if (*ppos > LONG_MAX) >+ off = pos; >+ if (off != pos) > goto out; > if (count == 0) > goto out; >- off = (long)*ppos; > /* > * We might sleep getting the page, so get it first. > */ >diff -urN linux-2.4.21/fs/proc/base.c linux-2.4.21-fix/fs/proc/base.c >--- linux-2.4.21/fs/proc/base.c 2004-06-28 16:35:35.000000000 -0400 >+++ linux-2.4.21-fix/fs/proc/base.c 2004-06-28 17:01:06.000000000 -0400 >@@ -340,6 +340,7 @@ > ssize_t length; > ssize_t end; > struct task_struct *task = inode->u.proc_i.task; >+ loff_t pos = *ppos; > > if (count > PROC_BLOCK_SIZE) > count = PROC_BLOCK_SIZE; >@@ -353,14 +354,14 @@ > return length; > } > /* Static 4kB (or whatever) block capacity */ >- if (*ppos >= length) { >+ if (pos < 0 || pos >= length) { > free_page(page); > return 0; > } >- if (count + *ppos > length) >- count = length - *ppos; >- end = count + *ppos; >- copy_to_user(buf, (char *) page + *ppos, count); >+ if (count > length - pos) >+ count = length - pos; >+ end = count + pos; >+ copy_to_user(buf, (char *) page + pos, count); > *ppos = end; > free_page(page); > return count; >diff -urN linux-2.4.21/fs/proc/generic.c linux-2.4.21-fix/fs/proc/generic.c >--- linux-2.4.21/fs/proc/generic.c 2004-06-28 16:35:23.000000000 -0400 >+++ linux-2.4.21-fix/fs/proc/generic.c 2004-06-28 17:01:06.000000000 -0400 >@@ -56,6 +56,7 @@ > ssize_t n, count; > char *start; > struct proc_dir_entry * dp; >+ loff_t pos = *ppos; > > dp = (struct proc_dir_entry *) inode->u.generic_ip; > if (!(page = (char*) __get_free_page(GFP_KERNEL))) >@@ -64,6 +65,8 @@ > while ((nbytes > 0) && !eof) > { > count = MIN(PROC_BLOCK_SIZE, nbytes); >+ if ((unsigned)pos > INT_MAX) >+ break; > > start = NULL; > if (dp->get_info) { >@@ -71,11 +74,11 @@ > * Handle backwards compatibility with the old net > * routines. > */ >- n = dp->get_info(page, &start, *ppos, count); >+ n = dp->get_info(page, &start, pos, count); > if (n < count) > eof = 1; > } else if (dp->read_proc) { >- n = dp->read_proc(page, &start, *ppos, >+ n = dp->read_proc(page, &start, pos, > count, &eof, dp->data); > } else > break; >@@ -84,8 +87,8 @@ > /* > * For proc files that are less than 4k > */ >- start = page + *ppos; >- n -= *ppos; >+ start = page + pos; >+ n -= pos; > if (n <= 0) > break; > if (n > count) >@@ -111,7 +114,8 @@ > break; > } > >- *ppos += start < page ? (long)start : n; /* Move down the file */ >+ pos = start < page ? (long)start : n; /* Move down the file */ >+ *ppos = pos; > nbytes -= n; > buf += n; > retval += n; >diff -urN linux-2.4.21/fs/proc/kcore.c linux-2.4.21-fix/fs/proc/kcore.c >--- linux-2.4.21/fs/proc/kcore.c 2002-08-02 20:39:45.000000000 -0400 >+++ linux-2.4.21-fix/fs/proc/kcore.c 2004-06-28 17:01:06.000000000 -0400 >@@ -93,8 +93,9 @@ > if (copy_to_user(buf, (void *) (PAGE_OFFSET+p-PAGE_SIZE), count)) > return -EFAULT; > read += count; >+ p += count; > } >- *ppos += read; >+ *ppos = p; > return read; > } > #else /* CONFIG_KCORE_AOUT */ >diff -urN linux-2.4.21/fs/proc/proc_misc.c linux-2.4.21-fix/fs/proc/proc_misc.c >--- linux-2.4.21/fs/proc/proc_misc.c 2004-06-28 16:35:24.000000000 -0400 >+++ linux-2.4.21-fix/fs/proc/proc_misc.c 2004-06-28 17:01:06.000000000 -0400 >@@ -539,12 +539,13 @@ > static ssize_t read_profile(struct file *file, char *buf, > size_t count, loff_t *ppos) > { >- unsigned long p = *ppos; >+ loff_t n = *ppos; >+ unsigned p = n; > ssize_t read; > char * pnt; > unsigned int sample_step = 1 << prof_shift; > >- if (p >= (prof_len+1)*sizeof(unsigned int)) >+ if (p != n || p >= (prof_len+1)*sizeof(unsigned int)) > return 0; > if (count > (prof_len+1)*sizeof(unsigned int) - p) > count = (prof_len+1)*sizeof(unsigned int) - p; >@@ -558,7 +559,7 @@ > if (copy_to_user(buf,(void *)pnt,count)) > return -EFAULT; > read += count; >- *ppos += read; >+ *ppos = n + read; > return read; > } > >diff -urN linux-2.4.21/fs/udf/file.c linux-2.4.21-fix/fs/udf/file.c >--- linux-2.4.21/fs/udf/file.c 2002-08-02 20:39:45.000000000 -0400 >+++ linux-2.4.21-fix/fs/udf/file.c 2004-06-28 17:05:32.000000000 -0400 >@@ -155,7 +155,8 @@ > { > ssize_t retval; > struct inode *inode = file->f_dentry->d_inode; >- int err, pos; >+ int err; >+ loff_t pos; > > if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) > { >@@ -164,8 +165,11 @@ > else > pos = *ppos; > >- if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) + >- pos + count)) >+ if (pos < 0 || pos + count < pos) >+ return 0; >+ >+ if (inode->i_sb->s_blocksize - udf_file_entry_alloc_offset(inode) < >+ pos + count) > { > udf_expand_file_adinicb(inode, pos + count, &err); > if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) >diff -urN linux-2.4.21/mm/shmem.c linux-2.4.21-fix/mm/shmem.c >--- linux-2.4.21/mm/shmem.c 2004-06-28 16:35:01.000000000 -0400 >+++ linux-2.4.21-fix/mm/shmem.c 2004-06-28 17:01:06.000000000 -0400 >@@ -1101,10 +1101,14 @@ > struct inode *inode = filp->f_dentry->d_inode; > struct address_space *mapping = inode->i_mapping; > unsigned long index, offset; >+ loff_t pos = *ppos; > int nr = 1; > >- index = *ppos >> PAGE_CACHE_SHIFT; >- offset = *ppos & ~PAGE_CACHE_MASK; >+ if (unlikel(pos < 0)) >+ return; >+ >+ index = pos >> PAGE_CACHE_SHIFT; >+ offset = pos & ~PAGE_CACHE_MASK; > > while (nr && desc->count) { > struct page *page; >diff -urN linux-2.4.21/net/8021q/vlanproc.c linux-2.4.21-fix/net/8021q/vlanproc.c >--- linux-2.4.21/net/8021q/vlanproc.c 2003-06-13 10:51:39.000000000 -0400 >+++ linux-2.4.21-fix/net/8021q/vlanproc.c 2004-06-28 17:01:07.000000000 -0400 >@@ -232,7 +232,9 @@ > struct inode *inode = file->f_dentry->d_inode; > struct proc_dir_entry *dent; > char *page; >- int pos, offs, len; >+ int pos, len; >+ loff_t n = *ppos; >+ unsigned offs = pos; > > if (count <= 0) > return 0; >@@ -249,15 +251,14 @@ > return -ENOBUFS; > > pos = dent->get_info(page, dent->data, 0, 0); >- offs = file->f_pos; >- if (offs < pos) { >+ if (offs = n && offs < pos) { > len = min_t(int, pos - offs, count); > if (copy_to_user(buf, (page + offs), len)) { > kfree(page); > return -EFAULT; > } > >- file->f_pos += len; >+ *ppos = offs + len; > } else { > len = 0; > } >diff -urN linux-2.4.21/net/atm/br2684.c linux-2.4.21-fix/net/atm/br2684.c >--- linux-2.4.21/net/atm/br2684.c 2003-06-13 10:51:39.000000000 -0400 >+++ linux-2.4.21-fix/net/atm/br2684.c 2004-06-28 17:01:07.000000000 -0400 >@@ -729,6 +729,7 @@ > unsigned long page; > int len = 0, x, left; > page = get_free_page(GFP_KERNEL); >+ loff_t n = *pos; > if (!page) > return -ENOMEM; > left = PAGE_SIZE - 256; >@@ -736,7 +737,7 @@ > left = count; > read_lock(&devs_lock); > for (;;) { >- x = br2684_proc_engine(*pos, &((char *) page)[len]); >+ x = br2684_proc_engine(n, &((char *) page)[len]); > if (x == 0) > break; > if (x > left) >@@ -751,11 +752,12 @@ > } > len += x; > left -= x; >- (*pos)++; >+ n++; > if (left < 256) > break; > } > read_unlock(&devs_lock); >+ *pos = n; > if (len > 0 && copy_to_user(buf, (char *) page, len)) > len = -EFAULT; > free_page(page); >diff -urN linux-2.4.21/net/atm/mpoa_proc.c linux-2.4.21-fix/net/atm/mpoa_proc.c >--- linux-2.4.21/net/atm/mpoa_proc.c 2001-07-04 14:50:38.000000000 -0400 >+++ linux-2.4.21-fix/net/atm/mpoa_proc.c 2004-06-28 17:01:07.000000000 -0400 >@@ -109,6 +109,7 @@ > eg_cache_entry *eg_entry; > struct timeval now; > unsigned char ip_string[16]; >+ loff_t n = *pos; > if(count == 0) > return 0; > page = get_free_page(GFP_KERNEL); >@@ -150,14 +151,14 @@ > mpc = mpc->next; > } > >- if (*pos >= length) length = 0; >+ if (n != (unsigned)n || n >= length) length = 0; > else { >- if ((count + *pos) > length) count = length - *pos; >+ if (count > length - n) count = length - n; > if (copy_to_user(buff, (char *)page , count)) { > free_page(page); > return -EFAULT; > } >- *pos += count; >+ *pos = n + count; > } > > free_page(page); >diff -urN linux-2.4.21/net/wanrouter/wanproc.c linux-2.4.21-fix/net/wanrouter/wanproc.c >--- linux-2.4.21/net/wanrouter/wanproc.c 2004-06-28 16:35:34.000000000 -0400 >+++ linux-2.4.21-fix/net/wanrouter/wanproc.c 2004-06-28 17:01:07.000000000 -0400 >@@ -243,7 +243,9 @@ > struct inode *inode = file->f_dentry->d_inode; > struct proc_dir_entry* dent; > char* page; >- int pos, offs, len; >+ int pos, len; >+ loff_t n = *ppos; >+ unsigned offs = n; > > if (count <= 0) > return 0; >@@ -257,14 +259,13 @@ > return -ENOBUFS; > > pos = dent->get_info(page, dent->data, 0, 0); >- offs = file->f_pos; >- if (offs < pos) { >+ if (offs == n && offs < pos) { > len = min_t(unsigned int, pos - offs, count); > if (copy_to_user(buf, (page + offs), len)) { > kfree(page); > return -EFAULT; > } >- file->f_pos += len; >+ *ppos = offs + len; > } > else > len = 0; >_______________________________________________ >Vendor Security mailing list >Vendor Security@lst.de >https://www.lst.de/cgi-bin/mailman/listinfo/vendor-sec
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
|
Diff
Attachments on
bug 56074
:
21716
|
21755
|
21757
| 21767