[PATCH][RFC] Allow setproctitle to work again
Brian Gerst
bgerst en quark.vpplus.com
Mie Ene 26 14:00:02 CST 2000
Here is the patch I promised a few days ago. It Works For Me(tm),
although there are some applications (Netscape in particular) that
mangle their argv array and cause garbage to be output. Summary of the
patch:
- mm->{arg,env}_{start,end} now point to the argv[] and envp[] arrays
instead of the string space on the user stack. I have only tested
binfmt_elf.
- access_process_vm has been modified to perform strncpy instead of
memcpy when requested.
- Some crufty code that touched the environment variable space of insmod
was removed from the floppy driver. I see no reason for this code to be
there, and I didn't really want to fix it to work with the new scheme.
While this patch restores the ability to set the process title by
strcpy(argv[0], title), it also allows for argv[0]=title to work, which
is much safer and less prone to trashing the stack and environment
space.
--
Brian Gerst
------------ próxima parte ------------
diff -urN linux-2.3.41p3/arch/alpha/kernel/ptrace.c linux-proctitle/arch/alpha/kernel/ptrace.c
--- linux-2.3.41p3/arch/alpha/kernel/ptrace.c Mon Dec 6 22:23:26 1999
+++ linux-proctitle/arch/alpha/kernel/ptrace.c Wed Jan 26 01:25:51 2000
@@ -132,14 +132,14 @@
static inline int
read_int(struct task_struct *task, unsigned long addr, int * data)
{
- int copied = access_process_vm(task, addr, data, sizeof(int), 0);
+ int copied = access_process_vm(task, addr, data, sizeof(int), APVM_READ);
return (copied == sizeof(int)) ? 0 : -EIO;
}
static inline int
write_int(struct task_struct *task, unsigned long addr, int data)
{
- int copied = access_process_vm(task, addr, &data, sizeof(int), 1);
+ int copied = access_process_vm(task, addr, &data, sizeof(int), APVM_WRITE);
return (copied == sizeof(int)) ? 0 : -EIO;
}
@@ -292,7 +292,7 @@
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: {
unsigned long tmp;
- int copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+ int copied = access_process_vm(child, addr, &tmp, sizeof(tmp), APVM_READ);
ret = -EIO;
if (copied != sizeof(tmp))
goto out;
@@ -313,7 +313,7 @@
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: {
unsigned long tmp = data;
- int copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 1);
+ int copied = access_process_vm(child, addr, &tmp, sizeof(tmp), APVM_WRITE);
ret = (copied == sizeof(tmp)) ? 0 : -EIO;
goto out;
}
diff -urN linux-2.3.41p3/arch/arm/kernel/ptrace.c linux-proctitle/arch/arm/kernel/ptrace.c
--- linux-2.3.41p3/arch/arm/kernel/ptrace.c Wed Oct 20 19:29:08 1999
+++ linux-proctitle/arch/arm/kernel/ptrace.c Wed Jan 26 01:25:51 2000
@@ -64,7 +64,7 @@
{
int copied;
- copied = access_process_vm(child, addr, res, sizeof(*res), 0);
+ copied = access_process_vm(child, addr, res, sizeof(*res), APVM_READ);
return copied != sizeof(*res) ? -EIO : 0;
}
@@ -74,7 +74,7 @@
{
int copied;
- copied = access_process_vm(child, addr, &val, sizeof(val), 1);
+ copied = access_process_vm(child, addr, &val, sizeof(val), APVM_WRITE);
return copied != sizeof(val) ? -EIO : 0;
}
diff -urN linux-2.3.41p3/arch/i386/kernel/ptrace.c linux-proctitle/arch/i386/kernel/ptrace.c
--- linux-2.3.41p3/arch/i386/kernel/ptrace.c Sun Jan 23 12:49:43 2000
+++ linux-proctitle/arch/i386/kernel/ptrace.c Wed Jan 26 01:26:31 2000
@@ -203,7 +203,7 @@
unsigned long tmp;
int copied;
- copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+ copied = access_process_vm(child, addr, &tmp, sizeof(tmp), APVM_READ);
ret = -EIO;
if (copied != sizeof(tmp))
break;
@@ -237,7 +237,7 @@
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
ret = 0;
- if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+ if (access_process_vm(child, addr, &data, sizeof(data), APVM_WRITE) == sizeof(data))
break;
ret = -EIO;
break;
diff -urN linux-2.3.41p3/arch/mips/kernel/irixelf.c linux-proctitle/arch/mips/kernel/irixelf.c
--- linux-2.3.41p3/arch/mips/kernel/irixelf.c Sun Jul 25 16:45:25 1999
+++ linux-proctitle/arch/mips/kernel/irixelf.c Wed Jan 26 01:25:51 2000
@@ -206,25 +206,25 @@
}
#undef NEW_AUX_ENT
+ current->mm->env_end = (unsigned long) sp;
sp -= envc+1;
envp = (elf_caddr_t *) sp;
+ current->mm->arg_end = current->mm->env_start = (unsigned long) sp;
sp -= argc+1;
argv = (elf_caddr_t *) sp;
+ current->mm->arg_start = (unsigned long) sp;
__put_user((elf_addr_t)argc,--sp);
- current->mm->arg_start = (unsigned long) p;
while (argc-->0) {
__put_user((elf_caddr_t)(unsigned long)p,argv++);
p += strlen_user(p);
}
__put_user(NULL, argv);
- current->mm->arg_end = current->mm->env_start = (unsigned long) p;
while (envc-->0) {
__put_user((elf_caddr_t)(unsigned long)p,envp++);
p += strlen_user(p);
}
__put_user(NULL, envp);
- current->mm->env_end = (unsigned long) p;
return sp;
}
diff -urN linux-2.3.41p3/arch/mips/kernel/ptrace.c linux-proctitle/arch/mips/kernel/ptrace.c
--- linux-2.3.41p3/arch/mips/kernel/ptrace.c Mon Jul 5 22:44:57 1999
+++ linux-proctitle/arch/mips/kernel/ptrace.c Wed Jan 26 01:25:51 2000
@@ -112,7 +112,7 @@
unsigned long tmp;
int copied;
- copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+ copied = access_process_vm(child, addr, &tmp, sizeof(tmp), APVM_READ);
res = -EIO;
if (copied != sizeof(tmp))
goto out;
@@ -184,7 +184,7 @@
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
res = 0;
- if (access_process_vm(child, addr, &data, sizeof(data), 1)
+ if (access_process_vm(child, addr, &data, sizeof(data), APVM_WRITE)
== sizeof(data))
goto out;
res = -EIO;
diff -urN linux-2.3.41p3/arch/ppc/kernel/ptrace.c linux-proctitle/arch/ppc/kernel/ptrace.c
--- linux-2.3.41p3/arch/ppc/kernel/ptrace.c Tue Aug 31 14:36:43 1999
+++ linux-proctitle/arch/ppc/kernel/ptrace.c Wed Jan 26 01:25:51 2000
@@ -358,7 +358,7 @@
unsigned long tmp;
int copied;
- copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+ copied = access_process_vm(child, addr, &tmp, sizeof(tmp), APVM_READ);
ret = -EIO;
if (copied != sizeof(tmp))
goto out;
@@ -399,7 +399,7 @@
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
ret = 0;
- if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+ if (access_process_vm(child, addr, &data, sizeof(data), APVM_WRITE) == sizeof(data))
goto out;
ret = -EIO;
goto out;
diff -urN linux-2.3.41p3/arch/sh/kernel/ptrace.c linux-proctitle/arch/sh/kernel/ptrace.c
--- linux-2.3.41p3/arch/sh/kernel/ptrace.c Wed Sep 1 18:34:01 1999
+++ linux-proctitle/arch/sh/kernel/ptrace.c Wed Jan 26 01:25:51 2000
@@ -208,7 +208,7 @@
unsigned long tmp;
int copied;
- copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+ copied = access_process_vm(child, addr, &tmp, sizeof(tmp), APVM_READ);
ret = -EIO;
if (copied != sizeof(tmp))
goto out;
@@ -244,7 +244,7 @@
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
ret = 0;
- if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+ if (access_process_vm(child, addr, &data, sizeof(data), APVM_WRITE) == sizeof(data))
goto out;
ret = -EIO;
goto out;
diff -urN linux-2.3.41p3/arch/sparc/kernel/ptrace.c linux-proctitle/arch/sparc/kernel/ptrace.c
--- linux-2.3.41p3/arch/sparc/kernel/ptrace.c Tue Aug 31 14:23:29 1999
+++ linux-proctitle/arch/sparc/kernel/ptrace.c Wed Jan 26 01:25:51 2000
@@ -371,7 +371,7 @@
unsigned long tmp;
if (access_process_vm(child, addr,
- &tmp, sizeof(tmp), 0) == sizeof(tmp))
+ &tmp, sizeof(tmp), APVM_READ) == sizeof(tmp))
pt_os_succ_return(regs, tmp, (long *)data);
else
pt_error_return(regs, EIO);
@@ -389,7 +389,7 @@
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: {
if (access_process_vm(child, addr,
- &data, sizeof(data), 1) == sizeof(data))
+ &data, sizeof(data), APVM_WRITE) == sizeof(data))
pt_succ_return(regs, 0);
else
pt_error_return(regs, EIO);
diff -urN linux-2.3.41p3/arch/sparc64/kernel/binfmt_aout32.c linux-proctitle/arch/sparc64/kernel/binfmt_aout32.c
--- linux-2.3.41p3/arch/sparc64/kernel/binfmt_aout32.c Thu Aug 26 15:42:32 1999
+++ linux-proctitle/arch/sparc64/kernel/binfmt_aout32.c Wed Jan 26 01:25:51 2000
@@ -175,12 +175,15 @@
if ((envc+argc+3)&1)
--sp;
+ current->mm->env_end = (unsigned long) sp;
sp -= envc+1;
envp = (u32 *) sp;
+ current->mm->arg_end = current->mm->env_start = (unsigned long) sp;
sp -= argc+1;
argv = (u32 *) sp;
+ current->mm->arg_start = (unsigned long) sp;
+
put_user(argc,--sp);
- current->mm->arg_start = (unsigned long) p;
while (argc-->0) {
char c;
put_user(((u32)A(p)),argv++);
@@ -189,7 +192,6 @@
} while (c);
}
put_user(NULL,argv);
- current->mm->arg_end = current->mm->env_start = (unsigned long) p;
while (envc-->0) {
char c;
put_user(((u32)A(p)),envp++);
@@ -198,7 +200,6 @@
} while (c);
}
put_user(NULL,envp);
- current->mm->env_end = (unsigned long) p;
return sp;
}
diff -urN linux-2.3.41p3/arch/sparc64/kernel/ptrace.c linux-proctitle/arch/sparc64/kernel/ptrace.c
--- linux-2.3.41p3/arch/sparc64/kernel/ptrace.c Tue Aug 3 01:07:16 1999
+++ linux-proctitle/arch/sparc64/kernel/ptrace.c Wed Jan 26 01:25:51 2000
@@ -244,13 +244,13 @@
res = -EIO;
if (current->thread.flags & SPARC_FLAG_32BIT) {
copied = access_process_vm(child, addr,
- &tmp32, sizeof(tmp32), 0);
+ &tmp32, sizeof(tmp32), APVM_READ);
tmp64 = (unsigned long) tmp32;
if (copied == sizeof(tmp32))
res = 0;
} else {
copied = access_process_vm(child, addr,
- &tmp64, sizeof(tmp64), 0);
+ &tmp64, sizeof(tmp64), APVM_READ);
if (copied == sizeof(tmp64))
res = 0;
}
@@ -270,13 +270,13 @@
if (current->thread.flags & SPARC_FLAG_32BIT) {
tmp32 = data;
copied = access_process_vm(child, addr,
- &tmp32, sizeof(tmp32), 1);
+ &tmp32, sizeof(tmp32), APVM_WRITE);
if (copied == sizeof(tmp32))
res = 0;
} else {
tmp64 = data;
copied = access_process_vm(child, addr,
- &tmp64, sizeof(tmp64), 1);
+ &tmp64, sizeof(tmp64), APVM_WRITE);
if (copied == sizeof(tmp64))
res = 0;
}
diff -urN linux-2.3.41p3/drivers/block/floppy.c linux-proctitle/drivers/block/floppy.c
--- linux-2.3.41p3/drivers/block/floppy.c Sun Jan 23 12:49:47 2000
+++ linux-proctitle/drivers/block/floppy.c Wed Jan 26 01:33:13 2000
@@ -4330,60 +4330,13 @@
}
}
-static void __init mod_setup(char *pattern, int (*setup)(char *))
-{
- unsigned long i;
- char c;
- int j;
- int match;
- char buffer[100];
- int length = strlen(pattern)+1;
-
- match=0;
- j=1;
-
- for (i=current->mm->env_start; i< current->mm->env_end; i ++){
- get_user(c, (char *)i);
- if (match){
- if (j==99)
- c='\0';
- buffer[j] = c;
- if (!c || c == ' ' || c == '\t'){
- if (j){
- buffer[j] = '\0';
- setup(buffer);
- }
- j=0;
- } else
- j++;
- if (!c)
- break;
- continue;
- }
- if ((!j && !c) || (j && c == pattern[j-1]))
- j++;
- else
- j=0;
- if (j==length){
- match=1;
- j=0;
- }
- }
-}
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
int init_module(void)
{
printk(KERN_INFO "inserting floppy driver for " UTS_RELEASE "\n");
if(floppy)
parse_floppy_cfg_string(floppy);
- else
- mod_setup("floppy=", floppy_setup);
-
+
return floppy_init();
}
@@ -4403,10 +4356,6 @@
MODULE_PARM(FLOPPY_DMA,"i");
MODULE_AUTHOR("Alain L. Knaff");
MODULE_SUPPORTED_DEVICE("fd");
-
-#ifdef __cplusplus
-}
-#endif
#else
diff -urN linux-2.3.41p3/fs/binfmt_aout.c linux-proctitle/fs/binfmt_aout.c
--- linux-2.3.41p3/fs/binfmt_aout.c Wed Nov 24 11:36:09 1999
+++ linux-proctitle/fs/binfmt_aout.c Wed Jan 26 01:25:51 2000
@@ -225,16 +225,18 @@
put_user(bprm->exec, --sp);
put_user(0x3e9, --sp);
#endif
+ current->mm->env_end = (unsigned long) sp;
sp -= envc+1;
envp = (char **) sp;
+ current->mm->env_start = current->mm->arg_end = (unsigned long) sp;
sp -= argc+1;
argv = (char **) sp;
+ current->mm->arg_start = (unsigned long) sp;
#if defined(__i386__) || defined(__mc68000__)
put_user((unsigned long) envp,--sp);
put_user((unsigned long) argv,--sp);
#endif
put_user(argc,--sp);
- current->mm->arg_start = (unsigned long) p;
while (argc-->0) {
char c;
put_user(p,argv++);
@@ -243,7 +245,6 @@
} while (c);
}
put_user(NULL,argv);
- current->mm->arg_end = current->mm->env_start = (unsigned long) p;
while (envc-->0) {
char c;
put_user(p,envp++);
@@ -252,7 +253,6 @@
} while (c);
}
put_user(NULL,envp);
- current->mm->env_end = (unsigned long) p;
return sp;
}
diff -urN linux-2.3.41p3/fs/binfmt_elf.c linux-proctitle/fs/binfmt_elf.c
--- linux-2.3.41p3/fs/binfmt_elf.c Wed Jan 12 18:53:02 2000
+++ linux-proctitle/fs/binfmt_elf.c Wed Jan 26 01:25:51 2000
@@ -173,29 +173,29 @@
}
#undef NEW_AUX_ENT
+ current->mm->env_end = (unsigned long) sp;
sp -= envc+1;
envp = (elf_caddr_t *) sp;
+ current->mm->env_start = current->mm->arg_end = (unsigned long) sp;
sp -= argc+1;
argv = (elf_caddr_t *) sp;
+ current->mm->arg_start = (unsigned long) sp;
if (!ibcs) {
__put_user((elf_addr_t)(unsigned long) envp,--sp);
__put_user((elf_addr_t)(unsigned long) argv,--sp);
}
__put_user((elf_addr_t)argc,--sp);
- current->mm->arg_start = (unsigned long) p;
while (argc-->0) {
__put_user((elf_caddr_t)(unsigned long)p,argv++);
p += strlen_user(p);
}
__put_user(NULL, argv);
- current->mm->arg_end = current->mm->env_start = (unsigned long) p;
while (envc-->0) {
__put_user((elf_caddr_t)(unsigned long)p,envp++);
p += strlen_user(p);
}
__put_user(NULL, envp);
- current->mm->env_end = (unsigned long) p;
return sp;
}
diff -urN linux-2.3.41p3/fs/proc/base.c linux-proctitle/fs/proc/base.c
--- linux-2.3.41p3/fs/proc/base.c Wed Jan 12 18:52:44 2000
+++ linux-proctitle/fs/proc/base.c Wed Jan 26 02:01:58 2000
@@ -100,15 +100,40 @@
/* task is locked and can't drop mm, so we are safe */
+static int get_array(struct task_struct *task, unsigned long start,
+ unsigned long end, char *buffer)
+{
+ unsigned long str;
+ int res;
+ int buflen = 0;
+
+ while (start < end) {
+ res = access_process_vm(task, start, &str, sizeof(str), APVM_READ);
+ if (res != sizeof(str) || !str)
+ break;
+
+ res = access_process_vm(task, str, buffer, PAGE_SIZE - buflen,
+ APVM_READ | APVM_STRNCPY);
+ if (!res || buffer[res - 1])
+ break;
+
+ buffer += res;
+ buflen += res;
+
+ start += sizeof(str);
+ }
+
+ return buflen;
+}
+
+/* task is locked and can't drop mm, so we are safe */
+
static int proc_pid_environ(struct task_struct *task, char * buffer)
{
struct mm_struct *mm = task->mm;
int res = 0;
if (mm) {
- int len = mm->env_end - mm->env_start;
- if (len > PAGE_SIZE)
- len = PAGE_SIZE;
- res = access_process_vm(task, mm->env_start, buffer, len, 0);
+ res = get_array(task, mm->env_start, mm->env_end, buffer);
}
return res;
}
@@ -120,10 +145,7 @@
struct mm_struct *mm = task->mm;
int res = 0;
if (mm) {
- int len = mm->arg_end - mm->arg_start;
- if (len > PAGE_SIZE)
- len = PAGE_SIZE;
- res = access_process_vm(task, mm->arg_start, buffer, len, 0);
+ res = get_array(task, mm->arg_start, mm->arg_end, buffer);
}
return res;
}
@@ -288,7 +310,7 @@
int this_len, retval;
this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
- retval = access_process_vm(task, src, page, this_len, 0);
+ retval = access_process_vm(task, src, page, this_len, APVM_READ);
if (!retval) {
if (!copied)
copied = -EIO;
@@ -331,7 +353,7 @@
copied = -EFAULT;
break;
}
- retval = access_process_vm(task, dst, page, this_len, 1);
+ retval = access_process_vm(task, dst, page, this_len, APVM_WRITE);
if (!retval) {
if (!copied)
copied = -EIO;
diff -urN linux-2.3.41p3/include/linux/mm.h linux-proctitle/include/linux/mm.h
--- linux-2.3.41p3/include/linux/mm.h Sun Jan 23 12:50:00 2000
+++ linux-proctitle/include/linux/mm.h Wed Jan 26 01:52:31 2000
@@ -390,6 +390,11 @@
extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char *dst, int len);
extern int ptrace_writedata(struct task_struct *tsk, char * src, unsigned long dst, int len);
+/* Flags for access_process_vm() */
+#define APVM_READ 0
+#define APVM_WRITE 1
+#define APVM_STRNCPY 2
+
extern int pgt_cache_water[2];
extern int check_pgt_cache(void);
diff -urN linux-2.3.41p3/kernel/ptrace.c linux-proctitle/kernel/ptrace.c
--- linux-2.3.41p3/kernel/ptrace.c Mon Nov 22 23:48:55 1999
+++ linux-proctitle/kernel/ptrace.c Wed Jan 26 01:56:54 2000
@@ -18,13 +18,14 @@
/*
* Access another process' address space, one page at a time.
*/
-static int access_one_page(struct task_struct * tsk, struct vm_area_struct * vma, unsigned long addr, void *buf, int len, int write)
+static int access_one_page(struct task_struct * tsk, struct vm_area_struct * vma,
+ unsigned long addr, void *buf, int len, int flags)
{
pgd_t * pgdir;
pmd_t * pgmiddle;
pte_t * pgtable;
unsigned long mapnr;
- unsigned long maddr;
+ char * maddr;
struct page *page;
repeat:
@@ -42,29 +43,32 @@
if (!pte_present(*pgtable))
goto fault_in_page;
mapnr = pte_pagenr(*pgtable);
- if (write && (!pte_write(*pgtable) || !pte_dirty(*pgtable)))
+ if ((flags & APVM_WRITE) && (!pte_write(*pgtable) || !pte_dirty(*pgtable)))
goto fault_in_page;
if (mapnr >= max_mapnr)
return 0;
page = mem_map + mapnr;
flush_cache_page(vma, addr);
- if (write) {
- maddr = kmap(page);
- memcpy((char *)maddr + (addr & ~PAGE_MASK), buf, len);
- flush_page_to_ram(page);
- kunmap(page);
+ maddr = (char *) kmap(page) + (addr & ~PAGE_MASK);
+ if (flags & APVM_WRITE) {
+ if (flags & APVM_STRNCPY)
+ len = strnlen(buf, len) + 1;
+ memcpy(maddr, buf, len);
} else {
- maddr = kmap(page);
- memcpy(buf, (char *)maddr + (addr & ~PAGE_MASK), len);
- flush_page_to_ram(page);
- kunmap(page);
+ if (flags & APVM_STRNCPY)
+ len = strnlen(maddr, len) + 1;
+ memcpy(buf, maddr, len);
}
+
+ flush_page_to_ram(page);
+ kunmap(page);
+
return len;
fault_in_page:
/* -1: out of memory. 0 - unmapped page */
- if (handle_mm_fault(tsk, vma, addr, write) > 0)
+ if (handle_mm_fault(tsk, vma, addr, (flags & APVM_WRITE)) > 0)
goto repeat;
return 0;
@@ -77,7 +81,7 @@
return 0;
}
-int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
+int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int flags)
{
int copied;
struct vm_area_struct * vma;
@@ -96,7 +100,7 @@
if (this_len > len)
this_len = len;
- retval = access_one_page(tsk, vma, addr, buf, this_len, write);
+ retval = access_one_page(tsk, vma, addr, buf, this_len, flags);
copied += retval;
if (retval != this_len)
break;
@@ -108,6 +112,10 @@
addr += retval;
buf += retval;
+ /* Catch case where null is last byte on page */
+ if ((flags & APVM_STRNCPY) && !*((char*)buf-1))
+ break;
+
if (addr < vma->vm_end)
continue;
if (!vma->vm_next)
@@ -130,7 +138,7 @@
int this_len, retval;
this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
- retval = access_process_vm(tsk, src, buf, this_len, 0);
+ retval = access_process_vm(tsk, src, buf, this_len, APVM_READ);
if (!retval) {
if (copied)
break;
@@ -157,7 +165,7 @@
this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
if (copy_from_user(buf, src, this_len))
return -EFAULT;
- retval = access_process_vm(tsk, dst, buf, this_len, 1);
+ retval = access_process_vm(tsk, dst, buf, this_len, APVM_WRITE);
if (!retval) {
if (copied)
break;
Más información sobre la lista de distribución Ayuda