lkml.org 
[lkml]   [2004]   [Aug]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    SubjectRe: [RFC, PATCH] sys_revoke(), just a try. (was: Re: dynamic /dev security hole?)
    Date
    -----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/
    \
     
     \ /
      Last update: 2005-03-22 14:05    [W:2.269 / U:0.892 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site