patch-2.1.10 linux/fs/exec.c
Next file: linux/fs/ext2/balloc.c
Previous file: linux/fs/buffer.c
Back to the patch index
Back to the overall index
- Lines: 125
- Date:
Fri Nov 15 15:19:29 1996
- Orig file:
v2.1.9/linux/fs/exec.c
- Orig date:
Tue Oct 29 19:58:20 1996
diff -u --recursive --new-file v2.1.9/linux/fs/exec.c linux/fs/exec.c
@@ -178,27 +178,23 @@
/*
* count() counts the number of arguments/envelopes
- *
- * We also do some limited EFAULT checking: this isn't complete, but
- * it does cover most cases. I'll have to do this correctly some day..
*/
static int count(char ** argv)
{
- int error, i = 0;
- char ** tmp, *p;
+ int i = 0;
- if ((tmp = argv) != NULL) {
- error = verify_area(VERIFY_READ, tmp, sizeof(char *));
- if (error)
- return error;
+ if (argv != NULL) {
for (;;) {
- get_user(p,tmp++);
+ char * p;
+ int error;
+
+ error = get_user(p,argv);
+ if (error)
+ return error;
if (!p)
break;
+ argv++;
i++;
- error = verify_area(VERIFY_READ, p, 1);
- if (error)
- return error;
}
}
return i;
@@ -224,60 +220,51 @@
unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
unsigned long p, int from_kmem)
{
- char *tmp, *tmp1, *pag = NULL;
- int len, offset = 0;
- unsigned long old_fs, new_fs;
+ char *str;
+ unsigned long old_fs;
if (!p)
return 0; /* bullet-proofing */
- new_fs = get_ds();
old_fs = get_fs();
if (from_kmem==2)
- set_fs(new_fs);
+ set_fs(KERNEL_DS);
while (argc-- > 0) {
+ int len;
+ unsigned long pos;
+
if (from_kmem == 1)
- set_fs(new_fs);
- get_user(tmp, argv+argc);
- if (!tmp)
+ set_fs(KERNEL_DS);
+ get_user(str, argv+argc);
+ if (!str)
panic("VFS: argc is wrong");
- tmp1 = tmp;
if (from_kmem == 1)
set_fs(old_fs);
- for (;;) {
- char c;
- get_user(c,tmp++);
- if (!c)
- break;
- }
- len = tmp - tmp1;
+ len = strlen_user(str); /* includes the '\0' */
if (p < len) { /* this shouldn't happen - 128kB */
set_fs(old_fs);
return 0;
}
+ p -= len;
+ pos = p;
while (len) {
- --p; --tmp; --len;
- if (--offset < 0) {
- offset = p % PAGE_SIZE;
+ char *pag;
+ int offset, bytes_to_copy;
+
+ offset = pos % PAGE_SIZE;
+ if (!(pag = (char *) page[pos/PAGE_SIZE]) &&
+ !(pag = (char *) page[pos/PAGE_SIZE] =
+ (unsigned long *) get_free_page(GFP_USER))) {
if (from_kmem==2)
set_fs(old_fs);
- if (!(pag = (char *) page[p/PAGE_SIZE]) &&
- !(pag = (char *) page[p/PAGE_SIZE] =
- (unsigned long *) get_free_page(GFP_USER)))
- return 0;
- if (from_kmem==2)
- set_fs(new_fs);
-
- }
- if (len == 0 || offset == 0)
- get_user(*(pag + offset), tmp);
- else {
- int bytes_to_copy = (len > offset) ? offset : len;
- tmp -= bytes_to_copy;
- p -= bytes_to_copy;
- offset -= bytes_to_copy;
- len -= bytes_to_copy;
- copy_from_user(pag + offset, tmp, bytes_to_copy + 1);
+ return 0;
}
+ bytes_to_copy = PAGE_SIZE - offset;
+ if (bytes_to_copy > len)
+ bytes_to_copy = len;
+ copy_from_user(pag + offset, str, bytes_to_copy);
+ pos += bytes_to_copy;
+ str += bytes_to_copy;
+ len -= bytes_to_copy;
}
}
if (from_kmem==2)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov