[PATCH] Fix to exec syscall

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

In function sys_execve() in file fs/exec.c, if after opening an
executable file an error was found, closed the file and returned an error
code, but the corresponding inode structure was not released. Now,
the inode is released on errors.

In file fs/buffer.c, function find_buffer() now looks for the
requested block in the direction most likely to find it faster.

Moved prototype for function get_unused_fd() from include/arch/system.h
to the more reasonable place in include/linuxmt/fs.h.

Code size was reduced by 16 bytes.

Greetings,

Juan
diff -Nur elks.orig/arch/i86/drivers/char/pty.c elks/arch/i86/drivers/char/pty.c
--- elks.orig/arch/i86/drivers/char/pty.c	2014-12-08 07:24:41.000000000 -0600
+++ elks/arch/i86/drivers/char/pty.c	2015-01-22 16:46:51.000000000 -0600
@@ -91,7 +91,7 @@
 {
     register struct tty *tty = determine_tty(inode->i_rdev);
     register char *pi;
-    int j, l;
+    int l;
     unsigned char ch;
 
     debug("PTY: read ");
@@ -102,8 +102,7 @@
     l = (file->f_flags & O_NONBLOCK) ? 0 : 1;
     pi = 0;
     while (((int)pi) < len) {
-	j = chq_getch(&tty->outq, &ch, l);
-	if (j == -1)
+	if(chq_getch(&tty->outq, &ch, l) == -1)
 	    if (l) {
 		debug("failed: INTR\n");
 		return -EINTR;
diff -Nur elks.orig/fs/buffer.c elks/fs/buffer.c
--- elks.orig/fs/buffer.c	2014-12-08 07:24:41.000000000 -0600
+++ elks/fs/buffer.c	2015-01-21 15:33:14.000000000 -0600
@@ -74,9 +74,8 @@
 	/*
 	 *      Unhook
 	 */
-	if ((bhn = bh->b_next_lru))
-	    bhn->b_prev_lru = bh->b_prev_lru;
-	if (bh->b_prev_lru)
+	bhn = bh->b_next_lru;
+	if((bhn->b_prev_lru = bh->b_prev_lru))
 	    bh->b_prev_lru->b_next_lru = bhn;
 	/*
 	 *      Alter head
@@ -167,11 +166,12 @@
 
 static struct buffer_head *find_buffer(kdev_t dev, block_t block)
 {
-    register struct buffer_head *bh;
+    register struct buffer_head *bh = bh_llru;
 
-    for (bh = bh_chain; bh != NULL; bh = bh->b_next)
+    do {
 	if (bh->b_blocknr == block && bh->b_dev == dev)
 	    break;
+    } while((bh = bh->b_prev_lru) != NULL);
     return bh;
 }
 
diff -Nur elks.orig/fs/exec.c elks/fs/exec.c
--- elks.orig/fs/exec.c	2014-12-08 07:24:41.000000000 -0600
+++ elks/fs/exec.c	2015-01-21 18:26:30.000000000 -0600
@@ -60,7 +60,7 @@
     __registers *tregs;
     unsigned int suidfile, sgidfile;
     int retval;
-    __u16 ds = current->t_regs.ds;
+    __u16 ds;
     seg_t cseg, dseg, stack_top = 0;
     uid_t effuid;
     gid_t effgid;
@@ -88,7 +88,7 @@
     filp = get_empty_filp(O_RDONLY);
     if(!filp) {
 	debug("\nNo filps\n");
-	goto error_exec1;
+	goto error_exec2;
     }
     filp->f_inode = inode;
 
@@ -101,7 +101,7 @@
     if ((!filp->f_op)
 	|| ((filp->f_op->open) && (filp->f_op->open(inode, filp)))
 	|| (!filp->f_op->read))
-	goto error_exec2;
+	goto normal_out;
 
     debug1("EXEC: Inode dev = 0x%x opened OK.\n", inode->i_dev);
 
@@ -109,7 +109,7 @@
      *      Read the header.
      */
     tregs = &current->t_regs;
-    tregs->ds = get_ds();
+    ds = tregs->ds;
 
     /*
      *      can I trust the following fields?
@@ -122,9 +122,10 @@
 	effuid = pinode->i_uid;
 	effgid = pinode->i_gid;
 
+	tregs->ds = get_ds();
 	result = filp->f_op->read(pinode, filp, &mh, sizeof(mh));
+	/*tregs->ds = ds;*/
     }
-    tregs->ds = ds;
 
     /*
      *      Sanity check it.
@@ -133,28 +134,28 @@
     if (result != sizeof(mh) ||
 	(mh.type != MINIX_SPLITID) || mh.chmem < 1024 || mh.tseg == 0) {
 	debug1("EXEC: bad header, result %u\n", result);
-	goto error_exec2;
+	goto error_exec3;
     }
 
 #ifdef CONFIG_EXEC_ELKS
     if ((unsigned int) mh.hlen == 0x30) {
 	/* BIG HEADER */
-	tregs->ds = get_ds();
+	/*tregs->ds = get_ds();*/
 	result = filp->f_op->read(inode, filp, &msuph, sizeof(msuph));
-	tregs->ds = ds;
+	/*tregs->ds = ds;*/
 	if (result != sizeof(msuph)) {
 	    debug1("EXEC: Bad secondary header, result %u\n", result);
-	    goto error_exec2;
+	    goto error_exec3;
 	}
 	stack_top = msuph.msh_dbase;
 	if(stack_top & 0xf){
-	     goto error_exec2;
+	     goto error_exec3;
 	}
 	debug1("EXEC: New type executable stack = %x\n", stack_top);
     }
 #else
     if((unsigned int) mh.hlen != 0x20){
-        goto error_exec2;
+        goto error_exec3;
     }
 #endif
 
@@ -180,16 +181,16 @@
     if (!cseg) {
         cseg = mm_alloc((segext_t) ((mh.tseg + 15) >> 4));
         if (!cseg) {
-            goto error_exec2;
+            goto error_exec3;
         }
         tregs->ds = cseg;
         result = filp->f_op->read(inode, filp, 0, mh.tseg);
-        tregs->ds = ds;
+        /*tregs->ds = ds;*/
         if (result != mh.tseg) {
             debug2("EXEC(tseg read): bad result %u, expected %u\n",
 	       result, mh.tseg);
 	    retval = -ENOEXEC;
-	    goto error_exec3;
+	    goto error_exec4;
         }
     }
     else {
@@ -207,14 +208,14 @@
     }
     len = (len + 15) & ~15L;
     if (len > (lsize_t) 0x10000L) {
-	goto error_exec3;
+	goto error_exec4;
     }
 
     debug1("EXEC: Allocating %ld bytes for data segment\n", len);
 
     dseg = mm_alloc((segext_t) (len >> 4));
     if (!dseg) {
-	goto error_exec3;
+	goto error_exec4;
     }
 
     debug2("EXEC: Malloc succeeded - cs=%x ds=%x\n", cseg, dseg);
@@ -226,7 +227,7 @@
     if (result != mh.dseg) {
 	debug2("EXEC(dseg read): bad result %d, expected %d\n",
 	       result, mh.dseg);
-	goto error_exec4;
+	goto error_exec5;
     }
 
     /*
@@ -338,18 +339,22 @@
     retval = 0;
     goto normal_out;
 
-  error_exec4:
+  error_exec5:
     mm_free(dseg);
 
-  error_exec3:
+  error_exec4:
     mm_free(cseg);
 
+  error_exec3:
+    tregs->ds = ds;
   normal_out:
-  error_exec2:
     if(filp->f_op->release)
 	filp->f_op->release(inode, filp);
     filp->f_count--;
 
+  error_exec2:
+    if(retval)
+	iput(inode);
   error_exec1:
     debug1("EXEC: Returning %d\n", retval);
     return retval;
diff -Nur elks.orig/fs/inode.c elks/fs/inode.c
--- elks.orig/fs/inode.c	2014-12-08 07:24:41.000000000 -0600
+++ elks/fs/inode.c	2015-01-21 17:05:29.000000000 -0600
@@ -441,7 +441,6 @@
 	    iput(inode);
 	    return NULL;
 	}
-	(inode->i_count)++;	/* sum of readers/writers */
 	inode->i_pipe = 1;
 	PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
 	PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
diff -Nur elks.orig/fs/pipe.c elks/fs/pipe.c
--- elks.orig/fs/pipe.c	2014-12-08 07:24:41.000000000 -0600
+++ elks/fs/pipe.c	2015-01-21 17:28:26.000000000 -0600
@@ -307,10 +307,10 @@
     struct inode *inode;
     register struct file *f1;
     register struct file *f2;
-    int error;
+    int error = -ENOMEM;
     int i;
 
-    inode = get_pipe_inode();
+    inode = get_pipe_inode();	/* Create inode */
     if (!inode)
 	goto no_inodes;
 
@@ -330,6 +330,7 @@
     fd[0] = error;
     i = error;
 
+    (inode->i_count)++;		/* Increase inode usage count */
     /* write file */
     error = -ENFILE;
     f2 = get_empty_filp(O_WRONLY);
@@ -352,12 +353,12 @@
 
   close_f1_i:
     current->files.fd[i] = NULL;
+    inode->i_count--;
 
   close_f1:
     f1->f_count--;
 
   no_files:
-    inode->i_count--;
     iput(inode);
 
   no_inodes:
diff -Nur elks.orig/include/arch/system.h elks/include/arch/system.h
--- elks.orig/include/arch/system.h	2014-12-08 07:24:41.000000000 -0600
+++ elks/include/arch/system.h	2015-01-21 16:43:04.000000000 -0600
@@ -9,6 +9,5 @@
 extern void setup_arch(seg_t *,seg_t *);
 
 extern int in_group_p(gid_t);
-extern int get_unused_fd(void);
 
 #endif
diff -Nur elks.orig/include/linuxmt/fs.h elks/include/linuxmt/fs.h
--- elks.orig/include/linuxmt/fs.h	2014-12-08 07:24:41.000000000 -0600
+++ elks/include/linuxmt/fs.h	2015-01-21 16:42:52.000000000 -0600
@@ -509,6 +509,7 @@
 
 extern struct buffer_head *bread(dev_t,block_t);
 
+extern int get_unused_fd(void);
 extern char *get_pipe_mem(void);
 extern void free_pipe_mem(char *buf);
 

[Index of Archives]     [Kernel]     [Linux ia64]     [DCCP]     [Linux for ARM]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux