From: Stanislav Ievlev <inger@altlinux.ru>
Subject: BUG! sys_rename()
Date: Wed, 30 May 2001 19:36:49 +0400
Next Article (by Date): Re: BUG! sys_rename() Arkady A Drovosekov
Previous Article (by Date): patch-2.4.5-v1.1.1.gz uploaded to /pre dir Amon Ott
Next in Thread: Re: BUG! sys_rename() Arkady A Drovosekov
Articles sorted by: [Date]
[Author]
[Subject]
This is a multi-part message in MIME format.
--------------000808090700020401050407
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
Hello All!
There is a serious bug:
In sys_rename() syscall RSBAC check only parent dir for R_WRITE, but we
need to check new file (if it exists) for R_DELETE.
-------------------
Simple exploit:
/tmp/old - file protected by FF (or ACL) as "read_only"
1. create /tmp/test
2. rename /tmp/test into /tmp/old will be GRANTED!!!
3(!). new /tmp/old unprotected now
--------------------
So we can:
1. copy /tmp/old into /tmp/test
2. rename /tmp/test into /tmp/old
As a result we have unprotected file /tmp/old
I've created an example patch to solve this problem. See attach.
--------------000808090700020401050407
Content-Type: text/plain;
name="exploit.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="exploit.diff"
--- namei.c.orig Wed May 30 17:39:58 2001
+++ namei.c Wed May 30 19:02:22 2001
@@ -2488,6 +2488,11 @@
enum rsbac_target_t rsbac_target;
union rsbac_target_id_t rsbac_target_id;
union rsbac_attribute_value_t rsbac_attribute_value;
+
+ enum rsbac_target_t rsbac_target_new;
+ union rsbac_target_id_t rsbac_target_id_new;
+ union rsbac_attribute_value_t rsbac_attribute_value_new;
+
#endif
if (path_init(oldname, LOOKUP_PARENT, &oldnd))
@@ -2533,6 +2538,11 @@
goto exit4;
}
+ new_dentry = lookup_hash(&newnd.last, new_dir);
+ error = PTR_ERR(new_dentry);
+ if (IS_ERR(new_dentry))
+ goto exit4;
+
/* RSBAC */
#ifdef CONFIG_RSBAC
if (rsbac_debug_aef)
@@ -2562,7 +2572,7 @@
if (rsbac_debug_aef)
printk(KERN_DEBUG
"do_rename() [sys_rename()]: calling ADF for WRITE on new_dir\n");
- rsbac_target_id.dir.device = new_dir->d_inode->i_dev;
+/* rsbac_target_id.dir.device = new_dir->d_inode->i_dev;
rsbac_target_id.dir.inode = new_dir->d_inode->i_ino;
rsbac_target_id.dir.dentry_p = new_dir;
rsbac_attribute_value.dummy = 0;
@@ -2575,19 +2585,40 @@
{
error = -EPERM;
goto exit4;
+ }*/
+ if(new_dentry->d_inode){
+ rsbac_target_new = T_FILE;
+ if (S_ISDIR(new_dentry->d_inode->i_mode))
+ rsbac_target_new = T_DIR;
+ else if (S_ISFIFO (new_dentry->d_inode->i_mode))
+ rsbac_target_new = T_FIFO;
+ else if (S_ISLNK (new_dentry->d_inode->i_mode))
+ rsbac_target_new = T_SYMLINK;
+
+ rsbac_target_id_new.file.device = new_dentry->d_inode->i_dev;
+ rsbac_target_id_new.file.inode = new_dentry->d_inode->i_ino;
+ rsbac_target_id_new.file.dentry_p = new_dentry;
+ rsbac_attribute_value_new.dummy = 0;
+ if (!rsbac_adf_request(R_DELETE,
+ current->pid,
+ rsbac_target_new,
+ rsbac_target_id_new,
+ A_none,
+ rsbac_attribute_value_new))
+ {
+ error = -EPERM;
+ goto exit_spec;
}
+ }
#endif /* CONFIG_RSBAC */
- new_dentry = lookup_hash(&newnd.last, new_dir);
- error = PTR_ERR(new_dentry);
- if (IS_ERR(new_dentry))
- goto exit4;
lock_kernel();
error = vfs_rename(old_dir->d_inode, old_dentry,
new_dir->d_inode, new_dentry);
unlock_kernel();
-
+
+exit_spec:
dput(new_dentry);
exit4:
dput(old_dentry);
--------------000808090700020401050407--
-
To unsubscribe from the rsbac list, send a mail to
majordomo@rsbac.org with
unsubscribe rsbac
as single line in the body.
Next Article (by Date): Re: BUG! sys_rename() Arkady A Drovosekov
Previous Article (by Date): patch-2.4.5-v1.1.1.gz uploaded to /pre dir Amon Ott
Next in Thread: Re: BUG! sys_rename() Arkady A Drovosekov
Articles sorted by: [Date]
[Author]
[Subject]