Al, this is the current (and new) open_exec():

struct file *open_exec(const char *name)
{
        struct dentry *dentry;
        struct file *file;

        lock_kernel();
        dentry = lookup_dentry(name, NULL, LOOKUP_FOLLOW);
        file = (struct file*) dentry;
        if (!IS_ERR(dentry)) {
                file = ERR_PTR(-EACCES);
                if (dentry->d_inode && S_ISREG(dentry->d_inode->i_mode)) {
                        int err = permission(dentry->d_inode, MAY_EXEC);
                        file = ERR_PTR(err);
                        if (!err) {
                                file = dentry_open(dentry, O_RDONLY);
out:
                                unlock_kernel();
                                return file;
                        }
                }
                dput(dentry);
        }
        goto out;
}

The exit conditions from it are rather odd.  It ends with a "goto out" to
the middle of the code, just so it can return an arg and unlock the kernel.
Also, it has a few too many nested if's.  Ion and I rewrote it more cleanly
and clearly.  Here's a small patch.

Erez.



*** linux-2.3-vanilla/fs/exec.c Fri Mar 24 12:34:59 2000
--- linux-2.3.bad/fs/exec.c     Fri Mar 24 22:13:59 2000
***************
*** 319,343 ****
  {
        struct dentry *dentry;
        struct file *file;
  
        lock_kernel();
        dentry = lookup_dentry(name, NULL, LOOKUP_FOLLOW);
!       file = (struct file*) dentry;
!       if (!IS_ERR(dentry)) {
                file = ERR_PTR(-EACCES);
!               if (dentry->d_inode && S_ISREG(dentry->d_inode->i_mode)) {
!                       int err = permission(dentry->d_inode, MAY_EXEC);
!                       file = ERR_PTR(err);
!                       if (!err) {
!                               file = dentry_open(dentry, O_RDONLY);
! out:
!                               unlock_kernel();
!                               return file;
!                       }
!               }
!               dput(dentry);
        }
        goto out;
  }
  
  int kernel_read(struct file *file, unsigned long offset,
--- 319,351 ----
  {
        struct dentry *dentry;
        struct file *file;
+       int err;
  
        lock_kernel();
        dentry = lookup_dentry(name, NULL, LOOKUP_FOLLOW);
!       if (IS_ERR(dentry)) {
!               file = (struct file*) dentry;
!               goto out;
!       }
!       if (!dentry->d_inode || !S_ISREG(dentry->d_inode->i_mode)) {
                file = ERR_PTR(-EACCES);
!               goto out_dput;
!       }
! 
!       err = permission(dentry->d_inode, MAY_EXEC);
!       if (err) {
!               file = ERR_PTR(err);
!               goto out_dput;
        }
+ 
+       file = dentry_open(dentry, O_RDONLY);
        goto out;
+ 
+  out_dput:
+       dput(dentry);
+  out:
+       unlock_kernel();
+       return file;
  }
  
  int kernel_read(struct file *file, unsigned long offset,

Reply via email to