From: Stanislav Ievlev <inger@altlinux.ru>
Subject: BUG! sys_rename()
Date: Wed, 30 May 2001 19:36:49 +0400
Next Article (by Author): Re: BUG! sys_rename() Stanislav Ievlev
Previous Article (by Author): Re: 2 RSBAC Problems Stanislav Ievlev
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 Author): Re: BUG! sys_rename() Stanislav Ievlev
Previous Article (by Author): Re: 2 RSBAC Problems Stanislav Ievlev
Next in Thread: Re: BUG! sys_rename() Arkady A Drovosekov
Articles sorted by: [Date]
[Author]
[Subject]