Messages in this thread Patch in this message | | | From | Michael Buesch <> | Subject | Re: [RFC, PATCH] sys_revoke(), just a try. (was: Re: dynamic /dev security hole?) | Date | Thu, 12 Aug 2004 18:49:17 +0200 |
| |
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Nobody interrested in this syscall?
I can't code this on my own, because I don't have the experience. Need help for this IMHO needed syscall.
And yes, I forgot to attach the patch inline, so you can comment on it. So here it is. :)
===== arch/i386/kernel/entry.S 1.77 vs edited ===== - --- 1.77/arch/i386/kernel/entry.S 2004-05-22 23:56:24 +02:00 +++ edited/arch/i386/kernel/entry.S 2004-08-10 20:11:29 +02:00 @@ -886,5 +886,6 @@ .long sys_mq_notify .long sys_mq_getsetattr .long sys_ni_syscall /* reserved for kexec */ + .long sys_revoke syscall_table_size=(.-sys_call_table) ===== fs/open.c 1.68 vs edited ===== - --- 1.68/fs/open.c 2004-08-08 03:54:13 +02:00 +++ edited/fs/open.c 2004-08-11 18:58:26 +02:00 @@ -1043,6 +1043,134 @@ EXPORT_SYMBOL(sys_close); +static int revoke_ret_ebadf(void) +{ + return -EBADF; +} + +static ssize_t revoke_read(struct file *filp, + char *buf, + size_t count, + loff_t *ppos) +{ + return 0; +} + +static int revoke_release(struct inode *inode, struct file *filp) +{ + fops_put(filp->f_op); + filp->f_op = NULL; + return 0; +} + +static ssize_t revoke_readv(struct file *filp, + const struct iovec *iov, + unsigned long count, + loff_t *ppos) +{ + return 0; +} + +static struct file_operations revoke_fops = { + .owner = THIS_MODULE, + .llseek = (void *)revoke_ret_ebadf, + .read = revoke_read, + .write = (void *)revoke_ret_ebadf, + .readdir = (void *)revoke_ret_ebadf, + .poll = (void *)revoke_ret_ebadf, + .ioctl = (void *)revoke_ret_ebadf, + .mmap = (void *)revoke_ret_ebadf, + .open = (void *)revoke_ret_ebadf, + .flush = (void *)revoke_ret_ebadf, + .release = revoke_release, + .fsync = (void *)revoke_ret_ebadf, + .fasync = (void *)revoke_ret_ebadf, + .lock = (void *)revoke_ret_ebadf, + .readv = revoke_readv, + .writev = (void *)revoke_ret_ebadf, +}; + +static int filp_revoke(struct file *filp, struct inode *inode) +{ + struct file_operations *fops = filp->f_op; + int ret = 0; + + down(&inode->i_sem); + if (!fops || !file_count(filp)) + goto out_truncate; + + filp->f_op = &revoke_fops; + + if (fops->flush) + fops->flush(filp); + if (fops->release) + ret = fops->release(inode, filp); + fops_put(fops); + +out_truncate: + vmtruncate(inode, (loff_t)0); + up(&inode->i_sem); + return ret; +} + +asmlinkage int sys_revoke(const char *path) +{ + struct nameidata nd; + struct super_block *sb; + struct list_head *p; + struct file *filp; + int ret = 0; +printk("called sys_revoke()\n"); + + if (user_path_walk(path, &nd)) { +printk("user_path_walk() failed\n"); + ret = -ENOENT; + goto out; + } + if (!nd.dentry->d_inode) { +printk("no inode\n"); + ret = -ENOENT; + goto out_release; + } + /* Allow only on Character or Block Devices. */ + if (!S_ISCHR(nd.dentry->d_inode->i_mode) && + !S_ISBLK(nd.dentry->d_inode->i_mode)) { +printk("no CHK/BLK\n"); + ret = -EINVAL; + goto out_release; + } + if ((current->fsuid != nd.dentry->d_inode->i_uid) || + !capable(CAP_FOWNER)) { +printk("perm\n"); + ret = -EPERM; + goto out_release; + } + + sb = nd.dentry->d_inode->i_sb; + file_list_lock(); + for (p = sb->s_files.next; p != &sb->s_files; p = p->next) { + filp = list_entry(p, struct file, f_list); + + if (!filp || !filp->f_dentry) + continue; + if (nd.dentry != filp->f_dentry) + continue; + if (filp->f_op == &revoke_fops) + continue; + if (!filp->f_dentry->d_inode) + continue; + + ret = filp_revoke(filp, filp->f_dentry->d_inode); + } + file_list_unlock(); +printk("done"); + +out_release: + path_release(&nd); +out: + return ret; +} + /* * This routine simulates a hangup on the tty, to arrange that users * are given clean terminals at login time. ===== include/asm-i386/unistd.h 1.39 vs edited ===== - --- 1.39/include/asm-i386/unistd.h 2004-08-02 10:00:44 +02:00 +++ edited/include/asm-i386/unistd.h 2004-08-10 20:14:44 +02:00 @@ -289,8 +289,9 @@ #define __NR_mq_notify (__NR_mq_open+4) #define __NR_mq_getsetattr (__NR_mq_open+5) #define __NR_sys_kexec_load 283 +#define __NR_revoke 284 - -#define NR_syscalls 284 +#define NR_syscalls 285 /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
Quoting Michael Buesch <mbuesch@freenet.de>: > Quoting Albert Cahalan <albert@users.sf.net>: > > Now all we need is revoke() and we're all set. > > Ordering: chown, chmod, revoke, unlink > > So, I searched the archives and found two previous attempts to create > a revoke syscall. They were long long ago. > I picked up some of its code and did a patch for latest 2.6 bk. > I'm currently running a kernel with the patch applied and did some > basic tests on it. Testing source is attached, too. > > I am a beginner in Kernel programming. I read some books and online > tutorials, but did not write much code. > So I'm sure, the code is full of bugs. I think there are nasty > race conditions. > Would be cool if someone could review it for races and report > them, please. I've not yet the experience to find them. > > Thank you. Have fun. >
- -- Regards Michael Buesch [ http://www.tuxsoft.de.vu ]
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) iD8DBQFBG5+NFGK1OIvVOP4RAoTgAKClBCUcLqJYk8o7aukgpkCzGEjVswCfZJVm 6ZsZw85Cps9LihNCX/3RnTI= =LjLk -----END PGP SIGNATURE----- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |