lkml.org 
[lkml]   [2000]   [Jul]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectInvalid checking of directory in *permission()

Hello,

I've found bug in *permission() functions that checks CAP_DAC_READ_SEARCH
capability to access a directory. Those functions uses local variable
named 'mode' which initialized on startup to inode->i_mode but later in
the code its value may be shifted by 3 or 6 bits. Then it is used to check
if current inode is a directory with S_ISDIR(mode) macro. This is invalid
and should be S_ISDIR(inode->i_node).

If process has CAP_DAC_OVERRIDE cleared and CAP_DAC_READ_SEARCH raised
it may cause security problems.

Problem exists in kernels up to 2.2.17pre10 (and probably 2.4.0).

I attached patch against 2.2.16 kernel but I haven't tested it.

Greets,
-wp

PS: Please include me in CC as I'm not subscribed to the list.

+--------------------------------------------------------------------+
| Wojciech Purczynski wp@elzabsoft.pl http://www.elzabsoft.pl/~wp |
| GSM: +48604432981 Linux Administrator SMS: wp-sms@elzabsoft.pl |
+------ Public GnuPG Key: http://www.elzabsoft.pl/~wp/gpg.asc ------+
diff -u -r linux/fs/ext2/acl.c linux-perm/fs/ext2/acl.c
--- linux/fs/ext2/acl.c Wed May 6 19:56:08 1998
+++ linux-perm/fs/ext2/acl.c Wed Jul 12 22:03:27 2000
@@ -54,7 +54,7 @@
if (((mode & mask & S_IRWXO) == mask) || capable(CAP_DAC_OVERRIDE))
return 0;
if ((mask == S_IROTH) ||
- (S_ISDIR(mode) && !(mask & ~(S_IROTH | S_IXOTH))))
+ (S_ISDIR(inode->i_mode) && !(mask & ~(S_IROTH | S_IXOTH))))
if (capable(CAP_DAC_READ_SEARCH))
return 0;
return -EACCES;
diff -u -r linux/fs/namei.c linux-perm/fs/namei.c
--- linux/fs/namei.c Tue Jan 4 19:12:23 2000
+++ linux-perm/fs/namei.c Wed Jul 12 22:02:41 2000
@@ -155,7 +155,7 @@
return 0;
/* read and search access */
if ((mask == S_IROTH) ||
- (S_ISDIR(mode) && !(mask & ~(S_IROTH | S_IXOTH))))
+ (S_ISDIR(inode->i_mode) && !(mask & ~(S_IROTH | S_IXOTH))))
if (capable(CAP_DAC_READ_SEARCH))
return 0;
return -EACCES;
diff -u -r linux/fs/proc/inode.c linux-perm/fs/proc/inode.c
--- linux/fs/proc/inode.c Sat May 9 03:10:30 1998
+++ linux-perm/fs/proc/inode.c Wed Jul 12 22:03:36 2000
@@ -149,7 +149,7 @@
return 0;
/* read and search access */
if ((mask == S_IROTH) ||
- (S_ISDIR(mode) && !(mask & ~(S_IROTH | S_IXOTH))))
+ (S_ISDIR(inode->i_mode) && !(mask & ~(S_IROTH | S_IXOTH))))
if (capable(CAP_DAC_READ_SEARCH))
return 0;
return -EACCES;
diff -u -r linux/fs/ufs/acl.c linux-perm/fs/ufs/acl.c
--- linux/fs/ufs/acl.c Mon Jan 4 20:51:29 1999
+++ linux-perm/fs/ufs/acl.c Wed Jul 12 22:03:01 2000
@@ -61,7 +61,7 @@
if (((mode & mask & S_IRWXO) == mask) || capable(CAP_DAC_OVERRIDE))
return 0;
if ((mask == S_IROTH) ||
- (S_ISDIR(mode) && !(mask & ~(S_IROTH | S_IXOTH))))
+ (S_ISDIR(inode->i_mode) && !(mask & ~(S_IROTH | S_IXOTH))))
if (capable(CAP_DAC_READ_SEARCH))
return 0;
return -EACCES;
\
 
 \ /
  Last update: 2005-03-22 13:57    [W:0.048 / U:2.920 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site