lkml.org 
[lkml]   [1996]   [Sep]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
SubjectSECURITY HOLE in namei.c ??
Date
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/
--- 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);
}
\
 
 \ /
  Last update: 2005-03-22 13:37    [W:0.177 / U:0.216 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site