SECURITY HOLE in namei.c ??

root (saturn@studbox.uni-stuttgart.de)
Sun, 01 Sep 1996 20:58:33 -0100


This is a multi-part message in MIME format.

--------------7362B5E5317ED34E5051154B
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hello,

I may be wrong or have passed this theme, but how is it possible for a
user to delete Files and Dirs, for them he has no write permissions!!

Have I got the wrong linux/fs/namei.c???!!!! HOPE YES!

I corrected this with my applied Attachment.

Additionally (THE reason why I looked in namei.c) I added
EISDIR as return value for do_unlink!

Hmmm ... so long,

Harald

-- 
--------------------------------------------------------
Harald Hoyer  Software Beratung, Erstellung und Vertrieb

EMAIL: saturn@studbox.uni-stuttgart.de WWW : http://wwwcip.rus.uni-stuttgart.de/~etk10226/

--------------7362B5E5317ED34E5051154B Content-Type: text/plain; charset=us-ascii; name="SECURE.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="SECURE.patch"

--- namei.c.old Sun Sep 1 18:37:50 1996 +++ namei.c Sun Sep 1 20:36:17 1996 @@ -610,7 +610,7 @@ { const char * basename; int namelen, error; - struct inode * dir; + struct inode * dir, *dir2; error = dir_namei(name, &namelen, &basename, NULL, &dir); if (error) @@ -638,7 +638,22 @@ iput(dir); return -EPERM; } - if (dir->i_sb && dir->i_sb->dq_op) + + dir->i_count++; + error = lookup(dir, basename, namelen, &dir2); + if (error) { + iput(dir); + return error; + } + + if ((error = permission(dir2,MAY_WRITE)) != 0) { + iput(dir2); + iput(dir); + return error; + } + iput(dir2); + + if (dir->i_sb && dir->i_sb->dq_op) dir->i_sb->dq_op->initialize(dir, -1); return dir->i_op->rmdir(dir,basename,namelen); } @@ -661,14 +676,20 @@ { const char * basename; int namelen, error; - struct inode * dir; + struct inode * dir, *file; error = dir_namei(name, &namelen, &basename, NULL, &dir); if (error) return error; if (!namelen) { + /* thanks to Paul Pluzhnikov for noticing this was missing.. */ + if ((error = permission(dir,MAY_WRITE | MAY_EXEC)) != 0) { + iput(dir); + return error; + } + iput(dir); - return -EPERM; + return -EISDIR; } if (IS_RDONLY(dir)) { iput(dir); @@ -689,7 +710,29 @@ iput(dir); return -EPERM; } - if (dir->i_sb && dir->i_sb->dq_op) + + dir->i_count++; + error = lookup(dir, basename, namelen, &file); + if (error) { + iput(dir); + return error; + } + + if(S_ISDIR(file->i_mode)) { + iput(file); + iput(dir); + return -EISDIR; + } + + if ((error = permission(file,MAY_WRITE)) != 0) { + iput(file); + iput(dir); + return error; + } + + iput(file); + + if (dir->i_sb && dir->i_sb->dq_op) dir->i_sb->dq_op->initialize(dir, -1); return dir->i_op->unlink(dir,basename,namelen); }

--------------7362B5E5317ED34E5051154B--