diff -urN linux-2.2.5/MAINTAINERS linux-fcaps/MAINTAINERS --- linux-2.2.5/MAINTAINERS Mon Mar 22 11:18:17 1999 +++ linux-fcaps/MAINTAINERS Wed Apr 14 22:59:29 1999 @@ -170,6 +170,13 @@ W: http://www.dandelion.com/Linux/ S: Maintained +CAPABILITIES +P: Andrew G. Morgan +M: morgan@transmeta.com +L: linux-privs@mit.edu +W: http://www.kernel.org/pub/linux/libs/linux-privs +S: Maintained + CONFIGURE, MENUCONFIG, XCONFIG P: Michael Elizabeth Chastain M: mec@shout.net diff -urN linux-2.2.5/arch/i386/kernel/mca.c linux-fcaps/arch/i386/kernel/mca.c --- linux-2.2.5/arch/i386/kernel/mca.c Sat Oct 17 15:33:45 1998 +++ linux-fcaps/arch/i386/kernel/mca.c Tue Apr 13 23:25:21 1999 @@ -138,7 +138,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; #endif diff -urN linux-2.2.5/arch/i386/kernel/mtrr.c linux-fcaps/arch/i386/kernel/mtrr.c --- linux-2.2.5/arch/i386/kernel/mtrr.c Sun Dec 27 22:45:13 1998 +++ linux-fcaps/arch/i386/kernel/mtrr.c Tue Apr 13 23:25:32 1999 @@ -1095,7 +1095,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static struct proc_dir_entry proc_root_mtrr = { diff -urN linux-2.2.5/arch/ppc/kernel/ppc_htab.c linux-fcaps/arch/ppc/kernel/ppc_htab.c --- linux-2.2.5/arch/ppc/kernel/ppc_htab.c Mon Dec 21 08:37:20 1998 +++ linux-fcaps/arch/ppc/kernel/ppc_htab.c Tue Apr 13 23:25:59 1999 @@ -78,7 +78,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* these will go into processor.h when I'm done debugging -- Cort */ diff -urN linux-2.2.5/drivers/ap1000/ringbuf.c linux-fcaps/drivers/ap1000/ringbuf.c --- linux-2.2.5/drivers/ap1000/ringbuf.c Wed Mar 10 16:51:35 1999 +++ linux-fcaps/drivers/ap1000/ringbuf.c Tue Apr 13 23:24:54 1999 @@ -322,5 +322,9 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/drivers/char/ftape/lowlevel/ftape-proc.c linux-fcaps/drivers/char/ftape/lowlevel/ftape-proc.c --- linux-2.2.5/drivers/char/ftape/lowlevel/ftape-proc.c Mon Aug 24 13:02:44 1998 +++ linux-fcaps/drivers/char/ftape/lowlevel/ftape-proc.c Tue Apr 13 23:26:10 1999 @@ -117,6 +117,10 @@ NULL, /* bmap */ NULL, /* truncate */ NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* diff -urN linux-2.2.5/drivers/pci/proc.c linux-fcaps/drivers/pci/proc.c --- linux-2.2.5/drivers/pci/proc.c Mon Aug 24 13:14:10 1998 +++ linux-fcaps/drivers/pci/proc.c Tue Apr 13 23:24:42 1999 @@ -226,7 +226,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; int diff -urN linux-2.2.5/drivers/zorro/proc.c linux-fcaps/drivers/zorro/proc.c --- linux-2.2.5/drivers/zorro/proc.c Mon Aug 24 13:14:10 1998 +++ linux-fcaps/drivers/zorro/proc.c Tue Apr 13 23:26:10 1999 @@ -93,7 +93,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; int diff -urN linux-2.2.5/fs/Makefile linux-fcaps/fs/Makefile --- linux-2.2.5/fs/Makefile Mon Aug 31 13:01:35 1998 +++ linux-fcaps/fs/Makefile Sat Apr 17 16:52:13 1999 @@ -13,7 +13,7 @@ O_OBJS = open.o read_write.o devices.o file_table.o buffer.o \ super.o block_dev.o stat.o exec.o pipe.o namei.o fcntl.o \ ioctl.o readdir.o select.o fifo.o locks.o filesystems.o \ - dcache.o inode.o attr.o bad_inode.o $(BINFMTS) + dcache.o inode.o attr.o bad_inode.o capability.o $(BINFMTS) MOD_LIST_NAME := FS_MODULES ALL_SUB_DIRS = coda minix ext2 fat msdos vfat proc isofs nfs umsdos ntfs \ diff -urN linux-2.2.5/fs/adfs/dir.c linux-fcaps/fs/adfs/dir.c --- linux-2.2.5/fs/adfs/dir.c Mon Aug 24 13:02:44 1998 +++ linux-fcaps/fs/adfs/dir.c Tue Apr 13 23:18:59 1999 @@ -56,7 +56,10 @@ NULL, /* bmap */ NULL, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; unsigned int adfs_val (unsigned char *p, int len) diff -urN linux-2.2.5/fs/adfs/file.c linux-fcaps/fs/adfs/file.c --- linux-2.2.5/fs/adfs/file.c Mon Aug 24 13:02:44 1998 +++ linux-fcaps/fs/adfs/file.c Tue Apr 13 23:19:13 1999 @@ -66,5 +66,8 @@ adfs_bmap, /* bmap */ NULL, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/affs/dir.c linux-fcaps/fs/affs/dir.c --- linux-2.2.5/fs/affs/dir.c Mon Aug 24 13:02:44 1998 +++ linux-fcaps/fs/affs/dir.c Tue Apr 13 23:26:18 1999 @@ -64,7 +64,8 @@ NULL, /* permissions */ NULL, /* smap */ NULL, /* updatepage */ - NULL /* revalidate */ + NULL, /* revalidate */ + NULL, /* capability */ }; static ssize_t diff -urN linux-2.2.5/fs/affs/file.c linux-fcaps/fs/affs/file.c --- linux-2.2.5/fs/affs/file.c Mon Aug 24 13:02:44 1998 +++ linux-fcaps/fs/affs/file.c Tue Apr 13 23:26:17 1999 @@ -81,7 +81,8 @@ NULL, /* permission */ NULL, /* smap */ NULL, /* updatepage */ - NULL /* revalidate */ + NULL, /* revalidate */ + NULL, /* capability */ }; static struct file_operations affs_file_operations_ofs = { @@ -122,7 +123,8 @@ NULL, /* permission */ NULL, /* smap */ NULL, /* updatepage */ - NULL /* revalidate */ + NULL, /* revalidate */ + NULL, /* capability */ }; #define AFFS_ISINDEX(x) ((x < 129) || \ diff -urN linux-2.2.5/fs/affs/symlink.c linux-fcaps/fs/affs/symlink.c --- linux-2.2.5/fs/affs/symlink.c Sat Sep 19 13:39:45 1998 +++ linux-fcaps/fs/affs/symlink.c Tue Apr 13 23:26:17 1999 @@ -40,7 +40,10 @@ NULL, /* bmap */ NULL, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static int diff -urN linux-2.2.5/fs/autofs/dir.c linux-fcaps/fs/autofs/dir.c --- linux-2.2.5/fs/autofs/dir.c Tue Oct 27 14:13:53 1998 +++ linux-fcaps/fs/autofs/dir.c Tue Apr 13 23:26:15 1999 @@ -82,6 +82,7 @@ NULL, /* permission */ NULL, /* smap */ NULL, /* updatepage */ - NULL /* revalidate */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/autofs/root.c linux-fcaps/fs/autofs/root.c --- linux-2.2.5/fs/autofs/root.c Wed Mar 10 15:07:56 1999 +++ linux-fcaps/fs/autofs/root.c Tue Apr 13 23:26:15 1999 @@ -61,7 +61,8 @@ NULL, /* permission */ NULL, /* smap */ NULL, /* updatepage */ - NULL /* revalidate */ + NULL, /* revalidate */ + NULL, /* capability */ }; static int autofs_root_readdir(struct file *filp, void *dirent, filldir_t filldir) diff -urN linux-2.2.5/fs/autofs/symlink.c linux-fcaps/fs/autofs/symlink.c --- linux-2.2.5/fs/autofs/symlink.c Tue Oct 27 14:13:53 1998 +++ linux-fcaps/fs/autofs/symlink.c Tue Apr 13 23:11:56 1999 @@ -56,5 +56,6 @@ NULL, /* permission */ NULL, /* smap */ NULL, /* updatepage */ - NULL /* revalidate */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/bad_inode.c linux-fcaps/fs/bad_inode.c --- linux-2.2.5/fs/bad_inode.c Mon Sep 21 14:37:20 1998 +++ linux-fcaps/fs/bad_inode.c Tue Apr 13 23:13:24 1999 @@ -67,7 +67,8 @@ EIO_ERROR, /* permission */ EIO_ERROR, /* smap */ EIO_ERROR, /* update_page */ - EIO_ERROR /* revalidate */ + EIO_ERROR, /* revalidate */ + EIO_ERROR, /* capability */ }; diff -urN linux-2.2.5/fs/capability.c linux-fcaps/fs/capability.c --- linux-2.2.5/fs/capability.c Wed Dec 31 16:00:00 1969 +++ linux-fcaps/fs/capability.c Thu Apr 22 22:55:23 1999 @@ -0,0 +1,88 @@ +/* + * fs/capability.c - vfs capability support + * + * Copyright (c) 1999 Andrew G. Morgan + */ + +#include + +/* this is a function hook for a module to set via the first call to + fs_capability_fn_register */ + +static int (*fs_capability_fn)(struct dentry *dentry, int operation, + kernel_cap_t *effective, + kernel_cap_t *inheritable, + kernel_cap_t *permitted) = NULL; + +/* + * This function may be called once to load and lock support for + * a filesystem capability method that overrides all other methods + * of setting/getting a file's (dentry's) capabilities. + */ + +int fs_capability_fn_register(int (*fs_cap_fn)(struct dentry *dentry, + int operation, + kernel_cap_t *effective, + kernel_cap_t *inheritable, + kernel_cap_t *permitted)) +{ +#define __FS_CAPABILITY_FN_REGISTER_DEBUG 1 +#ifdef __FS_CAPABILITY_FN_REGISTER_DEBUG + printk("fs_capability_fn_register(%p)\n", fs_cap_fn); + if (fs_cap_fn == NULL) { + printk(KERN_NOTICE "unlock-n-unload fs_capability_fn\n"); + fs_capability_fn = fs_cap_fn; + return 1; + } else +#endif /* __FS_CAPABILITY_FN_REGISTER_DEBUG */ + if (fs_capability_fn) { + printk(KERN_WARNING "ignoring attempt to reset fs_capability_fn\n"); + return 0; /* FAILED */ + } + + printk(KERN_NOTICE "load-n-lock fs_capability_fn (%p)\n", + fs_capability_fn); + fs_capability_fn = fs_cap_fn; + + return 1; /* OK */ +} + +/* XXX - really need to make some sense of the return values of this + function */ + +int vfs_cap_dentry(struct dentry *dentry, int operation, + kernel_cap_t *effective, + kernel_cap_t *inheritable, + kernel_cap_t *permitted) +{ + if (operation == _CAP_FS_GET) { /* start from a secure base */ + cap_clear(*effective); + cap_clear(*inheritable); + cap_clear(*permitted); + } + + if (IS_ERR(dentry)) { + return -ENOENT; + } + + if (fs_capability_fn != NULL) { + return fs_capability_fn(dentry, operation, + effective, inheritable, permitted); + } + + /* if the filesystem can handle it, use its custom function */ + if ((dentry->d_inode != NULL) + && (dentry->d_inode->i_op != NULL) + && (dentry->d_inode->i_op->capability != NULL)) { + return dentry->d_inode->i_op->capability(dentry->d_inode, operation, + effective, + inheritable, + permitted); + } + + if (operation != _CAP_FS_GET) { + return -ENOSYS; + } + + return 0; +} diff -urN linux-2.2.5/fs/coda/dir.c linux-fcaps/fs/coda/dir.c --- linux-2.2.5/fs/coda/dir.c Mon Jan 25 10:28:35 1999 +++ linux-fcaps/fs/coda/dir.c Tue Apr 13 23:26:14 1999 @@ -84,7 +84,8 @@ coda_permission, /* permission */ NULL, /* smap */ NULL, /* update page */ - coda_revalidate_inode /* revalidate */ + coda_revalidate_inode, /* revalidate */ + NULL, /* capability */ }; struct file_operations coda_dir_operations = { diff -urN linux-2.2.5/fs/coda/file.c linux-fcaps/fs/coda/file.c --- linux-2.2.5/fs/coda/file.c Mon Aug 31 15:46:10 1998 +++ linux-fcaps/fs/coda/file.c Tue Apr 13 23:26:13 1999 @@ -54,7 +54,8 @@ coda_permission, /* permission */ NULL, /* smap */ NULL, /* update page */ - coda_revalidate_inode /* revalidate */ + coda_revalidate_inode, /* revalidate */ + NULL, /* capability */ }; struct file_operations coda_file_operations = { diff -urN linux-2.2.5/fs/coda/pioctl.c linux-fcaps/fs/coda/pioctl.c --- linux-2.2.5/fs/coda/pioctl.c Mon Aug 31 15:46:10 1998 +++ linux-fcaps/fs/coda/pioctl.c Tue Apr 13 23:14:41 1999 @@ -53,7 +53,8 @@ coda_ioctl_permission, /* permission */ NULL, /* smap */ NULL, /* update page */ - NULL /* revalidate */ + NULL, /* revalidate */ + NULL, /* capability */ }; struct file_operations coda_ioctl_operations = { diff -urN linux-2.2.5/fs/coda/symlink.c linux-fcaps/fs/coda/symlink.c --- linux-2.2.5/fs/coda/symlink.c Fri Dec 18 12:45:00 1998 +++ linux-fcaps/fs/coda/symlink.c Tue Apr 13 23:26:13 1999 @@ -49,7 +49,8 @@ NULL, /* permission */ NULL, /* smap */ NULL, /* update page */ - NULL /* revalidate */ + NULL, /* revalidate */ + NULL, /* capability */ }; static int coda_readlink(struct dentry *de, char *buffer, int length) diff -urN linux-2.2.5/fs/devices.c linux-fcaps/fs/devices.c --- linux-2.2.5/fs/devices.c Wed Dec 23 11:39:49 1998 +++ linux-fcaps/fs/devices.c Tue Apr 13 23:26:28 1999 @@ -281,7 +281,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* @@ -334,7 +338,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* diff -urN linux-2.2.5/fs/devpts/root.c linux-fcaps/fs/devpts/root.c --- linux-2.2.5/fs/devpts/root.c Wed Sep 30 10:46:53 1998 +++ linux-fcaps/fs/devpts/root.c Tue Apr 13 23:20:54 1999 @@ -58,7 +58,8 @@ NULL, /* permission */ NULL, /* smap */ NULL, /* updatepage */ - NULL /* revalidate */ + NULL, /* revalidate */ + NULL, /* capability */ }; static struct dentry_operations devpts_dentry_operations = { diff -urN linux-2.2.5/fs/exec.c linux-fcaps/fs/exec.c --- linux-2.2.5/fs/exec.c Mon Jan 18 13:47:38 1999 +++ linux-fcaps/fs/exec.c Sat Apr 17 21:35:46 1999 @@ -601,41 +601,46 @@ id_change = 1; } - /* We don't have VFS support for capabilities yet */ - cap_clear(bprm->cap_inheritable); - cap_clear(bprm->cap_permitted); - cap_clear(bprm->cap_effective); + + /* For gets, this is guaranteed to succeed... */ + + (void) vfs_cap_dentry(bprm->dentry, _CAP_FS_GET, + &bprm->cap_effective, + &bprm->cap_inheritable, + &bprm->cap_permitted); + + /* if we're in the old "superuser knows best" scheme fake things */ /* To support inheritance of root-permissions and suid-root - * executables under compatibility mode, we raise the - * effective and inherited bitmasks of the executable file - * (translation: we set the executable "capability dumb" and - * set the allowed set to maximum). We don't set any forced - * bits. - * - * If only the real uid is 0, we only raise the inheritable - * bitmask of the executable file (translation: we set the - * allowed set to maximum and the application to "capability - * smart"). - */ + * executables under compatibility mode, we raise the + * effective and inherited bitmasks of the executable file + * (translation: we set the executable "capability dumb" and + * set the allowed set to maximum). We don't set any forced + * bits. + * + * If only the real uid is 0, we only raise the inheritable + * bitmask of the executable file (translation: we set the + * allowed set to maximum and the application to "capability + * smart"). + */ if (!issecure(SECURE_NOROOT)) { - if (bprm->e_uid == 0 || current->uid == 0) - cap_set_full(bprm->cap_inheritable); - if (bprm->e_uid == 0) - cap_set_full(bprm->cap_effective); + if (bprm->e_uid == 0 || current->uid == 0) + cap_set_full(bprm->cap_inheritable); + if (bprm->e_uid == 0) + cap_set_full(bprm->cap_effective); } - /* Only if pP' is _not_ a subset of pP, do we consider there - * has been a capability related "change of capability". In - * such cases, we need to check that the elevation of - * privilege does not go against other system constraints. - * The new Permitted set is defined below -- see (***). */ + /* Only if pP' is _not_ a subset of pP, do we consider there + * has been a capability related "change of capability". In + * such cases, we need to check that the elevation of + * privilege does not go against other system constraints. + * The new Permitted set is defined below -- see (***). */ { kernel_cap_t working = - cap_combine(bprm->cap_permitted, - cap_intersect(bprm->cap_inheritable, - current->cap_inheritable)); + cap_combine(bprm->cap_permitted, + cap_intersect(bprm->cap_inheritable, + current->cap_inheritable)); if (!cap_issubset(working, current->cap_permitted)) { cap_raised = 1; } diff -urN linux-2.2.5/fs/ext2/dir.c linux-fcaps/fs/ext2/dir.c --- linux-2.2.5/fs/ext2/dir.c Wed Nov 11 11:49:59 1998 +++ linux-fcaps/fs/ext2/dir.c Tue Apr 13 23:26:26 1999 @@ -72,7 +72,10 @@ NULL, /* bmap */ NULL, /* truncate */ ext2_permission, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; int ext2_check_dir_entry (const char * function, struct inode * dir, diff -urN linux-2.2.5/fs/ext2/file.c linux-fcaps/fs/ext2/file.c --- linux-2.2.5/fs/ext2/file.c Mon Dec 21 15:22:54 1998 +++ linux-fcaps/fs/ext2/file.c Tue Apr 13 23:26:26 1999 @@ -100,7 +100,10 @@ ext2_bmap, /* bmap */ ext2_truncate, /* truncate */ ext2_permission, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* diff -urN linux-2.2.5/fs/ext2/symlink.c linux-fcaps/fs/ext2/symlink.c --- linux-2.2.5/fs/ext2/symlink.c Sat Sep 19 13:38:18 1998 +++ linux-fcaps/fs/ext2/symlink.c Tue Apr 13 23:26:26 1999 @@ -48,7 +48,10 @@ NULL, /* bmap */ NULL, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static struct dentry * ext2_follow_link(struct dentry * dentry, diff -urN linux-2.2.5/fs/fat/file.c linux-fcaps/fs/fat/file.c --- linux-2.2.5/fs/fat/file.c Sun Feb 28 09:47:37 1999 +++ linux-fcaps/fs/fat/file.c Tue Apr 13 23:26:20 1999 @@ -62,7 +62,10 @@ fat_bmap, /* bmap */ fat_truncate, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* #Specification: msdos / special devices / mmap @@ -112,7 +115,10 @@ NULL, /* bmap */ fat_truncate, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static struct file_operations fat_file_operations_readpage = { @@ -147,7 +153,10 @@ NULL, /* bmap */ fat_truncate, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; #define MSDOS_PREFETCH 32 diff -urN linux-2.2.5/fs/fifo.c linux-fcaps/fs/fifo.c --- linux-2.2.5/fs/fifo.c Fri Nov 13 10:07:26 1998 +++ linux-fcaps/fs/fifo.c Tue Apr 13 23:26:40 1999 @@ -145,7 +145,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; void init_fifo(struct inode * inode) diff -urN linux-2.2.5/fs/hfs/dir_cap.c linux-fcaps/fs/hfs/dir_cap.c --- linux-2.2.5/fs/hfs/dir_cap.c Mon Nov 2 09:35:16 1998 +++ linux-fcaps/fs/hfs/dir_cap.c Tue Apr 13 23:26:12 1999 @@ -92,7 +92,10 @@ NULL, /* bmap */ NULL, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; struct inode_operations hfs_cap_fdir_inode_operations = { @@ -113,7 +116,10 @@ NULL, /* bmap */ NULL, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; struct inode_operations hfs_cap_rdir_inode_operations = { @@ -134,7 +140,10 @@ NULL, /* bmap */ NULL, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /*================ File-local functions ================*/ diff -urN linux-2.2.5/fs/hfs/dir_dbl.c linux-fcaps/fs/hfs/dir_dbl.c --- linux-2.2.5/fs/hfs/dir_dbl.c Mon Nov 2 09:35:16 1998 +++ linux-fcaps/fs/hfs/dir_dbl.c Tue Apr 13 23:26:12 1999 @@ -92,7 +92,10 @@ NULL, /* bmap */ NULL, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/hfs/dir_nat.c linux-fcaps/fs/hfs/dir_nat.c --- linux-2.2.5/fs/hfs/dir_nat.c Mon Nov 2 09:35:16 1998 +++ linux-fcaps/fs/hfs/dir_nat.c Tue Apr 13 23:18:19 1999 @@ -100,7 +100,8 @@ NULL, /* permission */ NULL, /* smap */ NULL, /* updatepage */ - NULL /* revalidate */ + NULL, /* revalidate */ + NULL, /* capability */ }; struct inode_operations hfs_nat_hdir_inode_operations = { @@ -123,7 +124,8 @@ NULL, /* permission */ NULL, /* smap */ NULL, /* updatepage */ - NULL /* revalidate */ + NULL, /* revalidate */ + NULL, /* capability */ }; /*================ File-local functions ================*/ diff -urN linux-2.2.5/fs/hfs/file.c linux-fcaps/fs/hfs/file.c --- linux-2.2.5/fs/hfs/file.c Mon Nov 2 09:35:16 1998 +++ linux-fcaps/fs/hfs/file.c Tue Apr 13 23:26:11 1999 @@ -70,7 +70,8 @@ NULL, /* permission */ NULL, /* smap */ NULL, /* updatepage */ - NULL /* revalidate */ + NULL, /* revalidate */ + NULL, /* capability */ }; /*================ Variable-like macros ================*/ diff -urN linux-2.2.5/fs/hfs/file_cap.c linux-fcaps/fs/hfs/file_cap.c --- linux-2.2.5/fs/hfs/file_cap.c Mon Nov 2 09:35:16 1998 +++ linux-fcaps/fs/hfs/file_cap.c Tue Apr 13 23:17:34 1999 @@ -84,7 +84,8 @@ NULL, /* permission */ NULL, /* smap */ NULL, /* updatepage */ - NULL /* revalidata */ + NULL, /* revalidate */ + NULL, /* capability */ }; /*================ File-local functions ================*/ diff -urN linux-2.2.5/fs/hfs/file_hdr.c linux-fcaps/fs/hfs/file_hdr.c --- linux-2.2.5/fs/hfs/file_hdr.c Mon Feb 15 23:55:00 1999 +++ linux-fcaps/fs/hfs/file_hdr.c Tue Apr 13 23:18:37 1999 @@ -78,7 +78,8 @@ NULL, /* permission */ NULL, /* smap */ NULL, /* updatepage */ - NULL /* revalidate */ + NULL, /* revalidate */ + NULL, /* capability */ }; const struct hfs_hdr_layout hfs_dbl_fil_hdr_layout = { diff -urN linux-2.2.5/fs/hpfs/hpfs_fs.c linux-fcaps/fs/hpfs/hpfs_fs.c --- linux-2.2.5/fs/hpfs/hpfs_fs.c Mon Oct 5 10:04:34 1998 +++ linux-fcaps/fs/hpfs/hpfs_fs.c Tue Apr 13 23:26:23 1999 @@ -184,6 +184,10 @@ &hpfs_bmap, /* bmap */ NULL, /* truncate */ NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* directory ops */ @@ -227,6 +231,10 @@ NULL, /* bmap */ NULL, /* truncate */ NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* Four 512-byte buffers and the 2k block obtained by concatenating them */ diff -urN linux-2.2.5/fs/isofs/dir.c linux-fcaps/fs/isofs/dir.c --- linux-2.2.5/fs/isofs/dir.c Thu Nov 12 11:44:09 1998 +++ linux-fcaps/fs/isofs/dir.c Tue Apr 13 23:26:33 1999 @@ -61,7 +61,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static int isofs_name_translate(char * old, int len, char * new) diff -urN linux-2.2.5/fs/isofs/file.c linux-fcaps/fs/isofs/file.c --- linux-2.2.5/fs/isofs/file.c Sun Mar 7 15:25:23 1999 +++ linux-fcaps/fs/isofs/file.c Tue Apr 13 23:26:32 1999 @@ -52,5 +52,9 @@ NULL, /* writepage */ isofs_bmap, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/isofs/symlink.c linux-fcaps/fs/isofs/symlink.c --- linux-2.2.5/fs/isofs/symlink.c Sat Sep 19 13:42:23 1998 +++ linux-fcaps/fs/isofs/symlink.c Tue Apr 13 23:26:32 1999 @@ -41,7 +41,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static int isofs_readlink(struct dentry * dentry, char * buffer, int buflen) diff -urN linux-2.2.5/fs/minix/dir.c linux-fcaps/fs/minix/dir.c --- linux-2.2.5/fs/minix/dir.c Wed Nov 11 11:49:59 1998 +++ linux-fcaps/fs/minix/dir.c Tue Apr 13 23:26:33 1999 @@ -56,7 +56,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static int minix_readdir(struct file * filp, diff -urN linux-2.2.5/fs/minix/file.c linux-fcaps/fs/minix/file.c --- linux-2.2.5/fs/minix/file.c Mon Aug 24 13:02:44 1998 +++ linux-fcaps/fs/minix/file.c Tue Apr 13 23:26:34 1999 @@ -64,7 +64,11 @@ NULL, /* writepage */ minix_bmap, /* bmap */ minix_truncate, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static ssize_t minix_file_write(struct file * filp, const char * buf, diff -urN linux-2.2.5/fs/minix/symlink.c linux-fcaps/fs/minix/symlink.c --- linux-2.2.5/fs/minix/symlink.c Sat Sep 19 13:42:44 1998 +++ linux-fcaps/fs/minix/symlink.c Tue Apr 13 23:26:34 1999 @@ -37,7 +37,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static struct dentry * minix_follow_link(struct dentry * dentry, diff -urN linux-2.2.5/fs/msdos/namei.c linux-fcaps/fs/msdos/namei.c --- linux-2.2.5/fs/msdos/namei.c Fri Dec 18 07:09:35 1998 +++ linux-fcaps/fs/msdos/namei.c Tue Apr 13 23:26:40 1999 @@ -1004,6 +1004,7 @@ NULL, /* smap */ NULL, /* updatepage */ NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/ncpfs/dir.c linux-fcaps/fs/ncpfs/dir.c --- linux-2.2.5/fs/ncpfs/dir.c Tue Dec 1 22:46:46 1998 +++ linux-fcaps/fs/ncpfs/dir.c Tue Apr 13 23:26:20 1999 @@ -92,6 +92,7 @@ NULL, /* smap */ NULL, /* updatepage */ NULL, /* revalidate */ + NULL, /* capability */ }; static ssize_t diff -urN linux-2.2.5/fs/ncpfs/file.c linux-fcaps/fs/ncpfs/file.c --- linux-2.2.5/fs/ncpfs/file.c Mon Aug 24 13:02:44 1998 +++ linux-fcaps/fs/ncpfs/file.c Tue Apr 13 23:26:19 1999 @@ -271,5 +271,10 @@ NULL, /* rename */ NULL, /* readlink */ NULL, /* bmap */ - NULL /* truncate */ + NULL, /* truncate */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/nfs/dir.c linux-fcaps/fs/nfs/dir.c --- linux-2.2.5/fs/nfs/dir.c Fri Mar 5 16:19:34 1999 +++ linux-fcaps/fs/nfs/dir.c Tue Apr 13 23:26:28 1999 @@ -100,6 +100,7 @@ NULL, /* smap */ NULL, /* updatepage */ nfs_revalidate, /* revalidate */ + NULL, /* capability */ }; static int diff -urN linux-2.2.5/fs/nfs/file.c linux-fcaps/fs/nfs/file.c --- linux-2.2.5/fs/nfs/file.c Fri Mar 19 14:20:47 1999 +++ linux-fcaps/fs/nfs/file.c Tue Apr 13 23:26:27 1999 @@ -77,6 +77,7 @@ NULL, /* smap */ nfs_updatepage, /* updatepage */ nfs_revalidate, /* revalidate */ + NULL, /* capability */ }; /* Hack for future NFS swap support */ diff -urN linux-2.2.5/fs/nfs/symlink.c linux-fcaps/fs/nfs/symlink.c --- linux-2.2.5/fs/nfs/symlink.c Sat Sep 19 13:43:09 1998 +++ linux-fcaps/fs/nfs/symlink.c Tue Apr 13 23:26:27 1999 @@ -41,7 +41,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static int nfs_readlink(struct dentry *dentry, char *buffer, int buflen) diff -urN linux-2.2.5/fs/ntfs/fs.c linux-fcaps/fs/ntfs/fs.c --- linux-2.2.5/fs/ntfs/fs.c Fri Mar 19 08:07:34 1999 +++ linux-fcaps/fs/ntfs/fs.c Tue Apr 13 23:20:29 1999 @@ -446,6 +446,7 @@ NULL, /* smap */ NULL, /* updatepage */ NULL, /* revalidate */ + NULL, /* capability */ }; #ifdef CONFIG_NTFS_RW @@ -631,6 +632,7 @@ NULL, /* smap */ NULL, /* updatepage */ NULL, /* revalidate */ + NULL, /* capability */ }; static struct file_operations ntfs_dir_operations = { @@ -680,6 +682,7 @@ NULL, /* smap */ NULL, /* updatepage */ NULL, /* revalidate */ + NULL, /* capability */ }; /* ntfs_read_inode is called by the Virtual File System (the kernel layer that diff -urN linux-2.2.5/fs/pipe.c linux-fcaps/fs/pipe.c --- linux-2.2.5/fs/pipe.c Fri Nov 13 10:07:26 1998 +++ linux-fcaps/fs/pipe.c Tue Apr 13 23:26:16 1999 @@ -452,7 +452,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; int do_pipe(int *fd) diff -urN linux-2.2.5/fs/proc/array.c linux-fcaps/fs/proc/array.c --- linux-2.2.5/fs/proc/array.c Wed Mar 10 21:49:10 1999 +++ linux-fcaps/fs/proc/array.c Tue Apr 13 23:26:38 1999 @@ -1519,7 +1519,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static ssize_t arraylong_read(struct file * file, char * buf, @@ -1567,5 +1571,9 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/proc/base.c linux-fcaps/fs/proc/base.c --- linux-2.2.5/fs/proc/base.c Mon Aug 24 13:02:43 1998 +++ linux-fcaps/fs/proc/base.c Tue Apr 13 23:26:39 1999 @@ -49,7 +49,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* diff -urN linux-2.2.5/fs/proc/fd.c linux-fcaps/fs/proc/fd.c --- linux-2.2.5/fs/proc/fd.c Sun Nov 15 10:15:31 1998 +++ linux-fcaps/fs/proc/fd.c Tue Apr 13 23:26:38 1999 @@ -55,7 +55,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - proc_permission /* permission */ + proc_permission, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* diff -urN linux-2.2.5/fs/proc/generic.c linux-fcaps/fs/proc/generic.c --- linux-2.2.5/fs/proc/generic.c Mon Aug 24 13:02:44 1998 +++ linux-fcaps/fs/proc/generic.c Tue Apr 13 23:26:35 1999 @@ -64,7 +64,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* @@ -87,7 +91,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/proc/kmsg.c linux-fcaps/fs/proc/kmsg.c --- linux-2.2.5/fs/proc/kmsg.c Tue Nov 17 10:09:00 1998 +++ linux-fcaps/fs/proc/kmsg.c Tue Apr 13 23:26:37 1999 @@ -76,5 +76,9 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/proc/link.c linux-fcaps/fs/proc/link.c --- linux-2.2.5/fs/proc/link.c Sat Sep 19 15:11:37 1998 +++ linux-fcaps/fs/proc/link.c Tue Apr 13 23:26:39 1999 @@ -53,7 +53,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - proc_permission /* permission */ + proc_permission, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static struct dentry * proc_follow_link(struct dentry *dentry, diff -urN linux-2.2.5/fs/proc/mem.c linux-fcaps/fs/proc/mem.c --- linux-2.2.5/fs/proc/mem.c Wed Sep 23 15:24:37 1998 +++ linux-fcaps/fs/proc/mem.c Tue Apr 13 23:26:39 1999 @@ -340,5 +340,9 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - proc_permission /* permission */ + proc_permission, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/proc/net.c linux-fcaps/fs/proc/net.c --- linux-2.2.5/fs/proc/net.c Mon Aug 24 13:14:09 1998 +++ linux-fcaps/fs/proc/net.c Tue Apr 13 23:26:36 1999 @@ -117,5 +117,9 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/proc/omirr.c linux-fcaps/fs/proc/omirr.c --- linux-2.2.5/fs/proc/omirr.c Mon Aug 24 13:14:09 1998 +++ linux-fcaps/fs/proc/omirr.c Tue Apr 13 23:26:35 1999 @@ -294,5 +294,8 @@ NULL, /* bmap */ NULL, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/proc/openpromfs.c linux-fcaps/fs/proc/openpromfs.c --- linux-2.2.5/fs/proc/openpromfs.c Wed Nov 18 09:06:05 1998 +++ linux-fcaps/fs/proc/openpromfs.c Tue Apr 13 23:26:35 1999 @@ -581,7 +581,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static struct file_operations openpromfs_nodenum_ops = { @@ -615,7 +619,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static struct file_operations openprom_alias_operations = { @@ -649,7 +657,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static int lookup_children(u16 n, const char * name, int len) diff -urN linux-2.2.5/fs/proc/proc_devtree.c linux-fcaps/fs/proc/proc_devtree.c --- linux-2.2.5/fs/proc/proc_devtree.c Sat Sep 19 13:43:36 1998 +++ linux-fcaps/fs/proc/proc_devtree.c Tue Apr 13 23:26:34 1999 @@ -62,7 +62,10 @@ NULL, /* bmap */ NULL, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static struct dentry *devtree_follow_link(struct dentry *dentry, diff -urN linux-2.2.5/fs/proc/root.c linux-fcaps/fs/proc/root.c --- linux-2.2.5/fs/proc/root.c Fri Jan 15 15:38:59 1999 +++ linux-fcaps/fs/proc/root.c Tue Apr 13 23:26:39 1999 @@ -75,7 +75,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* @@ -98,7 +102,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* @@ -140,7 +148,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* @@ -297,7 +309,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; struct proc_dir_entry proc_openprom = { @@ -482,7 +498,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static struct inode_operations proc_link_inode_operations = { @@ -502,7 +522,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static struct proc_dir_entry proc_root_loadavg = { diff -urN linux-2.2.5/fs/proc/scsi.c linux-fcaps/fs/proc/scsi.c --- linux-2.2.5/fs/proc/scsi.c Mon Aug 24 13:14:10 1998 +++ linux-fcaps/fs/proc/scsi.c Tue Apr 13 23:26:36 1999 @@ -75,7 +75,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; int get_not_present_info(char *buffer, char **start, off_t offset, int length) diff -urN linux-2.2.5/fs/qnx4/dir.c linux-fcaps/fs/qnx4/dir.c --- linux-2.2.5/fs/qnx4/dir.c Tue Sep 1 10:43:13 1998 +++ linux-fcaps/fs/qnx4/dir.c Tue Apr 13 23:12:15 1999 @@ -122,5 +122,8 @@ NULL, /* bmap */ NULL, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/qnx4/file.c linux-fcaps/fs/qnx4/file.c --- linux-2.2.5/fs/qnx4/file.c Fri Mar 26 13:57:41 1999 +++ linux-fcaps/fs/qnx4/file.c Tue Apr 13 23:26:14 1999 @@ -198,7 +198,10 @@ NULL, #endif NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static int qnx4_readpage(struct file *file, struct page *page) diff -urN linux-2.2.5/fs/qnx4/symlinks.c linux-fcaps/fs/qnx4/symlinks.c --- linux-2.2.5/fs/qnx4/symlinks.c Mon Jan 4 11:42:43 1999 +++ linux-fcaps/fs/qnx4/symlinks.c Tue Apr 13 23:12:42 1999 @@ -46,7 +46,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static struct dentry *qnx4_follow_link(struct dentry *dentry, diff -urN linux-2.2.5/fs/romfs/inode.c linux-fcaps/fs/romfs/inode.c --- linux-2.2.5/fs/romfs/inode.c Sat Sep 19 13:45:18 1998 +++ linux-fcaps/fs/romfs/inode.c Tue Apr 13 23:26:15 1999 @@ -521,6 +521,9 @@ NULL, /* truncate */ NULL, /* permission */ NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static struct file_operations romfs_dir_operations = { @@ -563,6 +566,9 @@ NULL, /* truncate */ NULL, /* permission */ NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static struct inode_operations romfs_link_inode_operations = { @@ -583,7 +589,10 @@ NULL, /* bmap */ NULL, /* truncate */ NULL, /* permission */ - NULL, /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static mode_t romfs_modemap[] = diff -urN linux-2.2.5/fs/smbfs/dir.c linux-fcaps/fs/smbfs/dir.c --- linux-2.2.5/fs/smbfs/dir.c Wed Dec 16 12:17:22 1998 +++ linux-fcaps/fs/smbfs/dir.c Tue Apr 13 23:26:22 1999 @@ -67,6 +67,7 @@ NULL, /* smap */ NULL, /* updatepage */ smb_revalidate_inode, /* revalidate */ + NULL, /* capability */ }; static ssize_t diff -urN linux-2.2.5/fs/smbfs/file.c linux-fcaps/fs/smbfs/file.c --- linux-2.2.5/fs/smbfs/file.c Wed Feb 17 15:59:32 1999 +++ linux-fcaps/fs/smbfs/file.c Tue Apr 13 23:26:21 1999 @@ -388,4 +388,5 @@ NULL, /* smap */ smb_updatepage, /* updatepage */ smb_revalidate_inode, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/sysv/dir.c linux-fcaps/fs/sysv/dir.c --- linux-2.2.5/fs/sysv/dir.c Wed Nov 11 11:49:59 1998 +++ linux-fcaps/fs/sysv/dir.c Tue Apr 13 23:26:23 1999 @@ -63,7 +63,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir) diff -urN linux-2.2.5/fs/sysv/file.c linux-fcaps/fs/sysv/file.c --- linux-2.2.5/fs/sysv/file.c Mon Aug 24 13:02:44 1998 +++ linux-fcaps/fs/sysv/file.c Tue Apr 13 23:26:23 1999 @@ -70,7 +70,11 @@ NULL, /* writepage */ sysv_bmap, /* bmap */ sysv_truncate, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; ssize_t sysv_file_read(struct file * filp, char * buf, diff -urN linux-2.2.5/fs/sysv/symlink.c linux-fcaps/fs/sysv/symlink.c --- linux-2.2.5/fs/sysv/symlink.c Sat Sep 19 13:45:42 1998 +++ linux-fcaps/fs/sysv/symlink.c Tue Apr 13 23:26:22 1999 @@ -43,7 +43,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; static struct dentry *sysv_follow_link(struct dentry * dentry, diff -urN linux-2.2.5/fs/ufs/dir.c linux-fcaps/fs/ufs/dir.c --- linux-2.2.5/fs/ufs/dir.c Thu Jan 14 10:31:41 1999 +++ linux-fcaps/fs/ufs/dir.c Tue Apr 13 23:26:19 1999 @@ -222,4 +222,7 @@ NULL, /* truncate */ ufs_permission, /* permission */ NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/ufs/file.c linux-fcaps/fs/ufs/file.c --- linux-2.2.5/fs/ufs/file.c Thu Jan 14 10:31:41 1999 +++ linux-fcaps/fs/ufs/file.c Tue Apr 13 23:26:18 1999 @@ -84,7 +84,10 @@ ufs_bmap, /* bmap */ ufs_truncate, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* diff -urN linux-2.2.5/fs/ufs/symlink.c linux-fcaps/fs/ufs/symlink.c --- linux-2.2.5/fs/ufs/symlink.c Thu Jan 14 10:31:41 1999 +++ linux-fcaps/fs/ufs/symlink.c Tue Apr 13 23:26:18 1999 @@ -134,5 +134,8 @@ NULL, /* bmap */ NULL, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/umsdos/dir.c linux-fcaps/fs/umsdos/dir.c --- linux-2.2.5/fs/umsdos/dir.c Sun Nov 29 11:43:13 1998 +++ linux-fcaps/fs/umsdos/dir.c Tue Apr 13 23:26:25 1999 @@ -806,4 +806,5 @@ NULL, /* smap */ NULL, /* updatepage */ NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/umsdos/file.c linux-fcaps/fs/umsdos/file.c --- linux-2.2.5/fs/umsdos/file.c Fri Sep 11 11:26:56 1998 +++ linux-fcaps/fs/umsdos/file.c Tue Apr 13 23:26:25 1999 @@ -104,7 +104,10 @@ fat_bmap, /* bmap */ UMSDOS_truncate, /* truncate */ NULL, /* permission */ - fat_smap /* smap */ + fat_smap, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* For other with larger and unaligned file system */ @@ -143,6 +146,9 @@ UMSDOS_truncate, /* truncate */ NULL, /* permission */ NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* For other with larger and unaligned file system with readpage */ @@ -180,5 +186,8 @@ NULL, /* bmap */ UMSDOS_truncate, /* truncate */ NULL, /* permission */ - NULL, /* smap */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/umsdos/rdir.c linux-fcaps/fs/umsdos/rdir.c --- linux-2.2.5/fs/umsdos/rdir.c Tue Dec 1 22:47:18 1998 +++ linux-fcaps/fs/umsdos/rdir.c Tue Apr 13 23:26:24 1999 @@ -254,4 +254,5 @@ NULL, /* smap */ NULL, /* updatepage */ NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/umsdos/symlink.c linux-fcaps/fs/umsdos/symlink.c --- linux-2.2.5/fs/umsdos/symlink.c Sat Sep 19 13:46:28 1998 +++ linux-fcaps/fs/umsdos/symlink.c Tue Apr 13 23:26:24 1999 @@ -142,6 +142,7 @@ NULL, /* permission */ NULL, /* smap */ NULL, /* updatepage */ - NULL /* revalidate */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/fs/vfat/namei.c linux-fcaps/fs/vfat/namei.c --- linux-2.2.5/fs/vfat/namei.c Sun Feb 28 09:47:37 1999 +++ linux-fcaps/fs/vfat/namei.c Tue Apr 13 23:26:20 1999 @@ -1764,7 +1764,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; diff -urN linux-2.2.5/include/linux/capability.h linux-fcaps/include/linux/capability.h --- linux-2.2.5/include/linux/capability.h Sun Mar 28 10:03:27 1999 +++ linux-fcaps/include/linux/capability.h Sun Apr 18 22:15:25 1999 @@ -10,12 +10,14 @@ #define _LINUX_CAPABILITY_H #include -#include /* User-level do most of the mapping between kernel and user capabilities based on the version tag given by the kernel. The kernel might be somewhat backwards compatible, but don't bet on - it. */ + it. See, + + ftp://linux.kernel.org/pub/linux/libs/linux-privs + */ /* XXX - Note, cap_t, is defined by POSIX to be an "opaque" pointer to a set of three capability sets. The transposition of 3*the @@ -23,11 +25,20 @@ library since the draft standard requires the use of malloc/free etc.. */ -#define _LINUX_CAPABILITY_VERSION 0x19980330 +#define _LINUX_CAPABILITY_VERSION 0x19990414 + +#define _CAPABILITY_TYPE_PROCESS 0x00000001 +#define _CAPABILITY_TYPE_FILE 0x00000002 +#define _CAPABILITY_TYPE_FILDES 0x00000003 typedef struct __user_cap_header_struct { __u32 version; - int pid; + int type; + union { + int pid; /* process manipulation */ + const char *path; /* filename manipulation */ + unsigned int fildes; /* filedescriptor manipulation */ + } u; } *cap_user_header_t; typedef struct __user_cap_data_struct { @@ -264,6 +275,10 @@ #define CAP_SYS_TTY_CONFIG 26 +/* Allow changes to capability flags associated with files */ + +#define CAP_SETFCAP 27 + #ifdef __KERNEL__ /* @@ -328,6 +343,13 @@ #define cap_mask(c,mask) do { cap_t(c) &= cap_t(mask); } while(0) #define cap_is_fs_cap(c) (CAP_TO_MASK(c) & CAP_FS_MASK) + +/* + * filesystem capability operations (arguments to vfs_cap_inode) + */ + +#define _CAP_FS_SET 0x0001 +#define _CAP_FS_GET 0x0002 #endif /* __KERNEL__ */ diff -urN linux-2.2.5/include/linux/fs.h linux-fcaps/include/linux/fs.h --- linux-2.2.5/include/linux/fs.h Sun Mar 28 10:03:27 1999 +++ linux-fcaps/include/linux/fs.h Sun Apr 18 22:16:13 1999 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -568,6 +569,15 @@ extern int vfs_rmdir(struct inode *, struct dentry *); extern int vfs_unlink(struct inode *, struct dentry *); extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); +extern int vfs_cap_dentry(struct dentry *, int, kernel_cap_t *, + kernel_cap_t *, kernel_cap_t *); + +extern int fs_capability_fn_register(int + (*fs_cap_fn)(struct dentry *dentry, + int operation, + kernel_cap_t *effective, + kernel_cap_t *inheritable, + kernel_cap_t *permitted)); /* * This is the "filldir" function type, used by readdir() to let @@ -617,6 +627,8 @@ int (*smap) (struct inode *,int); int (*updatepage) (struct file *, struct page *, unsigned long, unsigned int, int); int (*revalidate) (struct dentry *); + int (*capability) (struct inode *, int, + kernel_cap_t *, kernel_cap_t *, kernel_cap_t *); }; struct super_operations { diff -urN linux-2.2.5/include/linux/sched.h linux-fcaps/include/linux/sched.h --- linux-2.2.5/include/linux/sched.h Sun Mar 28 10:03:29 1999 +++ linux-fcaps/include/linux/sched.h Mon Apr 19 22:37:25 1999 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -21,6 +22,7 @@ #include #include #include +#include #include /* @@ -66,7 +68,6 @@ extern int last_pid; #include -#include #include #include #include @@ -594,11 +595,7 @@ extern inline int capable(int cap) { -#if 1 /* ok now */ if (cap_raised(current->cap_effective, cap)) -#else - if (cap_is_fs_cap(cap) ? current->fsuid == 0 : current->euid == 0) -#endif { current->flags |= PF_SUPERPRIV; return 1; diff -urN linux-2.2.5/kernel/capability.c linux-fcaps/kernel/capability.c --- linux-2.2.5/kernel/capability.c Fri Nov 20 11:43:19 1998 +++ linux-fcaps/kernel/capability.c Thu Apr 22 22:54:43 1999 @@ -6,70 +6,172 @@ */ #include +#include +#include +#include + #include +/* verify that the user knows the correct capability structure */ + +static int check_cap_version(cap_user_header_t header) +{ + __u32 version; + + if (get_user(version, &header->version)) + return -EFAULT; + + if (version != _LINUX_CAPABILITY_VERSION) { + version = _LINUX_CAPABILITY_VERSION; + if (put_user(version, &header->version)) + return -EFAULT; + return -EINVAL; + } + + return 0; +} + + /* Note: never hold tasklist_lock while spinning for this one */ spinlock_t task_capability_lock; -/* - * For sys_getproccap() and sys_setproccap(), any of the three - * capability set pointers may be NULL -- indicating that that set is - * uninteresting and/or not to be changed. - */ +static int getpcap(int pid, struct __user_cap_data_struct *data) +{ + int error = 0; + struct task_struct *target; + + if (pid < 0) + return -EINVAL; + + spin_lock(&task_capability_lock); + + if (pid && pid != current->pid) { + read_lock(&tasklist_lock); + target = find_task_by_pid(pid); /* identify target of query */ + if (!target) + error = -ESRCH; + } else { + target = current; + } + + if (!error) { + data->permitted = cap_t(target->cap_permitted); + data->inheritable = cap_t(target->cap_inheritable); + data->effective = cap_t(target->cap_effective); + } + + if (target != current) + read_unlock(&tasklist_lock); + + spin_unlock(&task_capability_lock); + + return error; +} + +static int dofdcap(unsigned int fd, int operation, kernel_cap_t *effective, + kernel_cap_t *inheritable, kernel_cap_t *permitted) +{ + struct file * file; + int error = -EBADF; + + lock_kernel(); + file = fget(fd); + if (file == NULL) { + goto out; + } + if (!IS_ERR(file->f_dentry)) { + error = vfs_cap_dentry(file->f_dentry, operation, + effective, inheritable, permitted); + } + fput(file); + +out: + unlock_kernel(); + + return error; +} + +static int dofcap(const char *filename, int operation, kernel_cap_t *effective, + kernel_cap_t *inheritable, kernel_cap_t *permitted) +{ + struct dentry * dentry; + int error; + + lock_kernel(); + dentry = namei(filename); + error = PTR_ERR(dentry); + if (!IS_ERR(dentry)) { + error = vfs_cap_dentry(dentry, operation, + effective, inheritable, permitted); + dput(dentry); + } + unlock_kernel(); + + return error; +} asmlinkage int sys_capget(cap_user_header_t header, cap_user_data_t dataptr) { - int error, pid; - __u32 version; - struct task_struct *target; - struct __user_cap_data_struct data; - - if (get_user(version, &header->version)) - return -EFAULT; - - error = -EINVAL; - if (version != _LINUX_CAPABILITY_VERSION) { - version = _LINUX_CAPABILITY_VERSION; - if (put_user(version, &header->version)) - error = -EFAULT; - return error; - } - - if (get_user(pid, &header->pid)) - return -EFAULT; - - if (pid < 0) - return -EINVAL; - - error = 0; - - spin_lock(&task_capability_lock); - - if (pid && pid != current->pid) { - read_lock(&tasklist_lock); - target = find_task_by_pid(pid); /* identify target of query */ - if (!target) - error = -ESRCH; - } else { - target = current; - } - - if (!error) { - data.permitted = cap_t(target->cap_permitted); - data.inheritable = cap_t(target->cap_inheritable); - data.effective = cap_t(target->cap_effective); - } - - if (target != current) - read_unlock(&tasklist_lock); - spin_unlock(&task_capability_lock); - - if (!error) { - if (copy_to_user(dataptr, &data, sizeof data)) - return -EFAULT; - } + int error, type; + struct __user_cap_data_struct data; - return error; + error = check_cap_version(header); + if (error) { + return error; + } + + if (get_user(type, &header->type)) + return -EFAULT; + + switch (type) { + + case _CAPABILITY_TYPE_PROCESS: + { + int pid; + + if (get_user(pid, &header->u.pid)) + return -EFAULT; + + error = getpcap(pid, &data); + break; + } + + case _CAPABILITY_TYPE_FILDES: + { + unsigned int fd; + + if (get_user(fd, &header->u.fildes)) { + return -EFAULT; + } + + error = dofdcap(fd, _CAP_FS_GET, &data.effective, + &data.inheritable, &data.permitted); + break; + } + + case _CAPABILITY_TYPE_FILE: + { + const char * filename; + + if (get_user(filename, &header->u.path)) { + return -EFAULT; + } + + error = dofcap(filename, _CAP_FS_GET, &data.effective, + &data.inheritable, &data.permitted); + break; + } + + default: + return -EINVAL; + } + + if (!error) { + if (copy_to_user(dataptr, &data, sizeof data)) + return -EFAULT; + } + + return error; } /* set capabilities for all processes in a given process group */ @@ -79,18 +181,17 @@ kernel_cap_t *inheritable, kernel_cap_t *permitted) { - struct task_struct *target; + struct task_struct *target; - /* FIXME: do we need to have a write lock here..? */ - read_lock(&tasklist_lock); - for_each_task(target) { - if (target->pgrp != pgrp) - continue; - target->cap_effective = *effective; - target->cap_inheritable = *inheritable; - target->cap_permitted = *permitted; - } - read_unlock(&tasklist_lock); + read_lock(&tasklist_lock); + for_each_task(target) { + if (target->pgrp != pgrp) + continue; + target->cap_effective = *effective; + target->cap_inheritable = *inheritable; + target->cap_permitted = *permitted; + } + read_unlock(&tasklist_lock); } /* set capabilities for all processes other than 1 and self */ @@ -99,19 +200,18 @@ kernel_cap_t *inheritable, kernel_cap_t *permitted) { - struct task_struct *target; + struct task_struct *target; - /* FIXME: do we need to have a write lock here..? */ - read_lock(&tasklist_lock); - /* ALL means everyone other than self or 'init' */ - for_each_task(target) { - if (target == current || target->pid == 1) - continue; - target->cap_effective = *effective; - target->cap_inheritable = *inheritable; - target->cap_permitted = *permitted; - } - read_unlock(&tasklist_lock); + read_lock(&tasklist_lock); + /* ALL means everyone other than self or 'init' */ + for_each_task(target) { + if (target == current || target->pid == 1) + continue; + target->cap_effective = *effective; + target->cap_inheritable = *inheritable; + target->cap_permitted = *permitted; + } + read_unlock(&tasklist_lock); } /* @@ -124,91 +224,147 @@ * E: must be set to a subset of (new target) Permitted */ -asmlinkage int sys_capset(cap_user_header_t header, const cap_user_data_t data) +static int setpcap(int pid, kernel_cap_t *effective, kernel_cap_t *inheritable, + kernel_cap_t *permitted) { - kernel_cap_t inheritable, permitted, effective; - __u32 version; - struct task_struct *target; - int error, pid; - - if (get_user(version, &header->version)) - return -EFAULT; - - if (version != _LINUX_CAPABILITY_VERSION) { - version = _LINUX_CAPABILITY_VERSION; - if (put_user(version, &header->version)) - return -EFAULT; - return -EINVAL; - } - - if (get_user(pid, &header->pid)) - return -EFAULT; - - if (pid && !capable(CAP_SETPCAP)) - return -EPERM; - - if (copy_from_user(&effective, &data->effective, sizeof(effective)) || - copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) || - copy_from_user(&permitted, &data->permitted, sizeof(permitted))) - return -EFAULT; - - error = -EPERM; - spin_lock(&task_capability_lock); - - if (pid > 0 && pid != current->pid) { - read_lock(&tasklist_lock); - target = find_task_by_pid(pid); /* identify target of query */ - if (!target) { - error = -ESRCH; - goto out; - } - } else { - target = current; - } - - - /* verify restrictions on target's new Inheritable set */ - if (!cap_issubset(inheritable, - cap_combine(target->cap_inheritable, - current->cap_permitted))) { - goto out; - } - - /* verify restrictions on target's new Permitted set */ - if (!cap_issubset(permitted, - cap_combine(target->cap_permitted, - current->cap_permitted))) { - goto out; - } - - /* verify the _new_Effective_ is a subset of the _new_Permitted_ */ - if (!cap_issubset(effective, permitted)) { - goto out; - } - - /* having verified that the proposed changes are legal, - we now put them into effect. */ - error = 0; - - if (pid < 0) { - if (pid == -1) /* all procs other than current and init */ - cap_set_all(&effective, &inheritable, &permitted); - - else /* all procs in process group */ - cap_set_pg(-pid, &effective, &inheritable, &permitted); - goto spin_out; - } else { - /* FIXME: do we need to have a write lock here..? */ - target->cap_effective = effective; - target->cap_inheritable = inheritable; - target->cap_permitted = permitted; - } + struct task_struct *target; + int error = -EPERM; + + spin_lock(&task_capability_lock); + + if (pid > 0 && pid != current->pid) { + read_lock(&tasklist_lock); + target = find_task_by_pid(pid); /* identify target of query */ + if (!target) { + error = -ESRCH; + goto out; + } + } else { + target = current; + } + + + /* verify restrictions on target's new Inheritable set */ + if (!cap_issubset(*inheritable, + cap_combine(target->cap_inheritable, + current->cap_permitted))) { + goto out; + } + + /* verify restrictions on target's new Permitted set */ + if (!cap_issubset(*permitted, + cap_combine(target->cap_permitted, + current->cap_permitted))) { + goto out; + } + + /* verify the _new_Effective_ is a subset of the _new_Permitted_ */ + if (!cap_issubset(*effective, *permitted)) { + goto out; + } + + /* having verified that the proposed changes are legal, + we now put them into effect. */ + error = 0; + + if (pid < 0) { + if (pid == -1) /* all procs other than current and init */ + cap_set_all(effective, inheritable, permitted); + + else /* all procs in process group */ + cap_set_pg(-pid, effective, inheritable, permitted); + goto spin_out; + } else { + /* FIXME: do we need to have a write lock here..? */ + target->cap_effective = *effective; + target->cap_inheritable = *inheritable; + target->cap_permitted = *permitted; + } out: - if (target != current) { - read_unlock(&tasklist_lock); - } + if (target != current) { + read_unlock(&tasklist_lock); + } + spin_out: - spin_unlock(&task_capability_lock); - return error; + spin_unlock(&task_capability_lock); + + return error; +} + +asmlinkage int sys_capset(cap_user_header_t header, const cap_user_data_t data) +{ + kernel_cap_t effective, permitted, inheritable; + int error, type; + + error = check_cap_version(header); + if (error) { + return error; + } + + if (get_user(type, &header->type)) + return -EFAULT; + + if (copy_from_user(&effective, &data->effective, sizeof(effective)) || + copy_from_user(&inheritable, &data->inheritable, + sizeof(inheritable)) || + copy_from_user(&permitted, &data->permitted, sizeof(permitted))) { + return -EFAULT; + } + + switch (type) { + + case _CAPABILITY_TYPE_PROCESS: + { + int pid; + + if (get_user(pid, &header->u.pid)) { + return -EFAULT; + } + if (pid && !capable(CAP_SETPCAP)) { + return -EPERM; + } + + error = setpcap(pid, &effective, &inheritable, &permitted); + + break; + } + + case _CAPABILITY_TYPE_FILDES: + { + unsigned int fd; + + if (get_user(fd, &header->u.fildes)) { + return -EFAULT; + } + if (!capable(CAP_SETFCAP)) { + return -EPERM; + } + + error = dofdcap(fd, _CAP_FS_SET, &effective, &inheritable, + &permitted); + break; + } + + case _CAPABILITY_TYPE_FILE: + { + const char *filename; + + if (get_user(filename, &header->u.path)) { + return -EFAULT; + } + if (!capable(CAP_SETFCAP)) { + return -EPERM; + } + + error = dofcap(filename, _CAP_FS_SET, &effective, &inheritable, + &permitted); + break; + } + + default: + return -EINVAL; + } + + return error; } diff -urN linux-2.2.5/kernel/ksyms.c linux-fcaps/kernel/ksyms.c --- linux-2.2.5/kernel/ksyms.c Mon Mar 22 10:03:32 1999 +++ linux-fcaps/kernel/ksyms.c Mon Apr 19 19:44:37 1999 @@ -398,3 +398,6 @@ /* library functions */ EXPORT_SYMBOL(strnicmp); + +/* capabilities */ +EXPORT_SYMBOL(fs_capability_fn_register); diff -urN linux-2.2.5/kernel/sysctl.c linux-fcaps/kernel/sysctl.c --- linux-2.2.5/kernel/sysctl.c Sat Feb 6 12:22:24 1999 +++ linux-fcaps/kernel/sysctl.c Tue Apr 13 23:21:23 1999 @@ -125,7 +125,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - proc_sys_permission + proc_sys_permission, + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; extern struct proc_dir_entry proc_sys_root; diff -urN linux-2.2.5/net/irda/irproc.c linux-fcaps/net/irda/irproc.c --- linux-2.2.5/net/irda/irproc.c Sun Mar 7 15:26:44 1999 +++ linux-fcaps/net/irda/irproc.c Tue Apr 13 23:26:11 1999 @@ -93,7 +93,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; struct proc_dir_entry proc_irda = { diff -urN linux-2.2.5/net/wanrouter/wanproc.c linux-fcaps/net/wanrouter/wanproc.c --- linux-2.2.5/net/wanrouter/wanproc.c Sun Nov 15 09:52:29 1998 +++ linux-fcaps/net/wanrouter/wanproc.c Tue Apr 13 23:23:50 1999 @@ -129,7 +129,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - router_proc_perms + router_proc_perms, + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /* @@ -169,7 +173,11 @@ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - router_proc_perms + router_proc_perms, + NULL, /* smap */ + NULL, /* updatepage */ + NULL, /* revalidate */ + NULL, /* capability */ }; /*