* Re: [v14 3/4] ext4: adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR interface support
From: Jan Kara @ 2015-04-24 16:40 UTC (permalink / raw)
To: Li Xi
Cc: linux-fsdevel, linux-ext4, linux-api, tytso, adilger, jack, viro,
hch, dmonakhov
In-Reply-To: <1429728997-21464-4-git-send-email-lixi@ddn.com>
On Thu 23-04-15 03:56:36, Li Xi wrote:
> This patch adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR ioctl interface
> support for ext4. The interface is kept consistent with
> XFS_IOC_FSGETXATTR/XFS_IOC_FSGETXATTR.
>
> Signed-off-by: Li Xi <lixi@ddn.com>
The patch looks good to me. You can add:
Reviewed-by: Jan Kara <jack@suse.cz>
Honza
> ---
> fs/ext4/ext4.h | 9 ++
> fs/ext4/ioctl.c | 367 ++++++++++++++++++++++++++++++++++++-----------
> fs/xfs/libxfs/xfs_fs.h | 47 +++----
> include/uapi/linux/fs.h | 32 ++++
> 4 files changed, 338 insertions(+), 117 deletions(-)
>
> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> index 0729a42..9995c53 100644
> --- a/fs/ext4/ext4.h
> +++ b/fs/ext4/ext4.h
> @@ -384,6 +384,13 @@ struct flex_groups {
> #define EXT4_FL_USER_VISIBLE 0x304BDFFF /* User visible flags */
> #define EXT4_FL_USER_MODIFIABLE 0x204380FF /* User modifiable flags */
>
> +#define EXT4_FL_XFLAG_VISIBLE (EXT4_SYNC_FL | \
> + EXT4_IMMUTABLE_FL | \
> + EXT4_APPEND_FL | \
> + EXT4_NODUMP_FL | \
> + EXT4_NOATIME_FL | \
> + EXT4_PROJINHERIT_FL)
> +
> /* Flags that should be inherited by new inodes from their parent. */
> #define EXT4_FL_INHERITED (EXT4_SECRM_FL | EXT4_UNRM_FL | EXT4_COMPR_FL |\
> EXT4_SYNC_FL | EXT4_NODUMP_FL | EXT4_NOATIME_FL |\
> @@ -618,6 +625,8 @@ enum {
> #define EXT4_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct ext4_encryption_policy)
> #define EXT4_IOC_GET_ENCRYPTION_PWSALT _IOW('f', 20, __u8[16])
> #define EXT4_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct ext4_encryption_policy)
> +#define EXT4_IOC_FSGETXATTR FS_IOC_FSGETXATTR
> +#define EXT4_IOC_FSSETXATTR FS_IOC_FSSETXATTR
>
> #if defined(__KERNEL__) && defined(CONFIG_COMPAT)
> /*
> diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
> index 2cb9e17..100b774 100644
> --- a/fs/ext4/ioctl.c
> +++ b/fs/ext4/ioctl.c
> @@ -14,6 +14,7 @@
> #include <linux/mount.h>
> #include <linux/file.h>
> #include <linux/random.h>
> +#include <linux/quotaops.h>
> #include <asm/uaccess.h>
> #include "ext4_jbd2.h"
> #include "ext4.h"
> @@ -206,6 +207,229 @@ static int uuid_is_zero(__u8 u[16])
> return 1;
> }
>
> +static int ext4_ioctl_setflags(struct inode *inode,
> + unsigned int flags)
> +{
> + struct ext4_inode_info *ei = EXT4_I(inode);
> + handle_t *handle = NULL;
> + int err = EPERM, migrate = 0;
> + struct ext4_iloc iloc;
> + unsigned int oldflags, mask, i;
> + unsigned int jflag;
> +
> + /* Is it quota file? Do not allow user to mess with it */
> + if (IS_NOQUOTA(inode))
> + goto flags_out;
> +
> + oldflags = ei->i_flags;
> +
> + /* The JOURNAL_DATA flag is modifiable only by root */
> + jflag = flags & EXT4_JOURNAL_DATA_FL;
> +
> + /*
> + * The IMMUTABLE and APPEND_ONLY flags can only be changed by
> + * the relevant capability.
> + *
> + * This test looks nicer. Thanks to Pauline Middelink
> + */
> + if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
> + if (!capable(CAP_LINUX_IMMUTABLE))
> + goto flags_out;
> + }
> +
> + /*
> + * The JOURNAL_DATA flag can only be changed by
> + * the relevant capability.
> + */
> + if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
> + if (!capable(CAP_SYS_RESOURCE))
> + goto flags_out;
> + }
> + if ((flags ^ oldflags) & EXT4_EXTENTS_FL)
> + migrate = 1;
> +
> + if (flags & EXT4_EOFBLOCKS_FL) {
> + /* we don't support adding EOFBLOCKS flag */
> + if (!(oldflags & EXT4_EOFBLOCKS_FL)) {
> + err = -EOPNOTSUPP;
> + goto flags_out;
> + }
> + } else if (oldflags & EXT4_EOFBLOCKS_FL)
> + ext4_truncate(inode);
> +
> + handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
> + if (IS_ERR(handle)) {
> + err = PTR_ERR(handle);
> + goto flags_out;
> + }
> + if (IS_SYNC(inode))
> + ext4_handle_sync(handle);
> + err = ext4_reserve_inode_write(handle, inode, &iloc);
> + if (err)
> + goto flags_err;
> +
> + for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
> + if (!(mask & EXT4_FL_USER_MODIFIABLE))
> + continue;
> + if (mask & flags)
> + ext4_set_inode_flag(inode, i);
> + else
> + ext4_clear_inode_flag(inode, i);
> + }
> +
> + ext4_set_inode_flags(inode);
> + inode->i_ctime = ext4_current_time(inode);
> +
> + err = ext4_mark_iloc_dirty(handle, inode, &iloc);
> +flags_err:
> + ext4_journal_stop(handle);
> + if (err)
> + goto flags_out;
> +
> + if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL))
> + err = ext4_change_inode_journal_flag(inode, jflag);
> + if (err)
> + goto flags_out;
> + if (migrate) {
> + if (flags & EXT4_EXTENTS_FL)
> + err = ext4_ext_migrate(inode);
> + else
> + err = ext4_ind_migrate(inode);
> + }
> +
> +flags_out:
> + return err;
> +}
> +
> +static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
> +{
> + struct inode *inode = file_inode(filp);
> + struct super_block *sb = inode->i_sb;
> + struct ext4_inode_info *ei = EXT4_I(inode);
> + int err, rc;
> + handle_t *handle;
> + kprojid_t kprojid;
> + struct ext4_iloc iloc;
> + struct ext4_inode *raw_inode;
> + struct dquot *transfer_to[EXT4_MAXQUOTAS] = { };
> +
> + if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
> + EXT4_FEATURE_RO_COMPAT_PROJECT)) {
> + BUG_ON(__kprojid_val(EXT4_I(inode)->i_projid)
> + != EXT4_DEF_PROJID);
> + if (projid != EXT4_DEF_PROJID)
> + return -EOPNOTSUPP;
> + else
> + return 0;
> + }
> +
> + if (EXT4_INODE_SIZE(sb) <= EXT4_GOOD_OLD_INODE_SIZE)
> + return -EOPNOTSUPP;
> +
> + kprojid = make_kprojid(&init_user_ns, (projid_t)projid);
> +
> + if (projid_eq(kprojid, EXT4_I(inode)->i_projid))
> + return 0;
> +
> + err = mnt_want_write_file(filp);
> + if (err)
> + return err;
> +
> + err = -EPERM;
> + mutex_lock(&inode->i_mutex);
> + /* Is it quota file? Do not allow user to mess with it */
> + if (IS_NOQUOTA(inode))
> + goto out_unlock;
> +
> + err = ext4_get_inode_loc(inode, &iloc);
> + if (err)
> + goto out_unlock;
> +
> + raw_inode = ext4_raw_inode(&iloc);
> + if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) {
> + err = -EOVERFLOW;
> + brelse(iloc.bh);
> + goto out_unlock;
> + }
> + brelse(iloc.bh);
> +
> + dquot_initialize(inode);
> +
> + handle = ext4_journal_start(inode, EXT4_HT_QUOTA,
> + EXT4_QUOTA_INIT_BLOCKS(sb) +
> + EXT4_QUOTA_DEL_BLOCKS(sb) + 3);
> + if (IS_ERR(handle)) {
> + err = PTR_ERR(handle);
> + goto out_unlock;
> + }
> +
> + err = ext4_reserve_inode_write(handle, inode, &iloc);
> + if (err)
> + goto out_stop;
> +
> + transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid));
> + if (transfer_to[PRJQUOTA]) {
> + err = __dquot_transfer(inode, transfer_to);
> + dqput(transfer_to[PRJQUOTA]);
> + if (err)
> + goto out_dirty;
> + }
> +
> + EXT4_I(inode)->i_projid = kprojid;
> + inode->i_ctime = ext4_current_time(inode);
> +out_dirty:
> + rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
> + if (!err)
> + err = rc;
> +out_stop:
> + ext4_journal_stop(handle);
> +out_unlock:
> + mutex_unlock(&inode->i_mutex);
> + mnt_drop_write_file(filp);
> + return err;
> +}
> +
> +/* Transfer internal flags to xflags */
> +static inline __u32 ext4_iflags_to_xflags(unsigned long iflags)
> +{
> + __u32 xflags = 0;
> +
> + if (iflags & EXT4_SYNC_FL)
> + xflags |= FS_XFLAG_SYNC;
> + if (iflags & EXT4_IMMUTABLE_FL)
> + xflags |= FS_XFLAG_IMMUTABLE;
> + if (iflags & EXT4_APPEND_FL)
> + xflags |= FS_XFLAG_APPEND;
> + if (iflags & EXT4_NODUMP_FL)
> + xflags |= FS_XFLAG_NODUMP;
> + if (iflags & EXT4_NOATIME_FL)
> + xflags |= FS_XFLAG_NOATIME;
> + if (iflags & EXT4_PROJINHERIT_FL)
> + xflags |= FS_XFLAG_PROJINHERIT;
> + return xflags;
> +}
> +
> +/* Transfer xflags flags to internal */
> +static inline unsigned long ext4_xflags_to_iflags(__u32 xflags)
> +{
> + unsigned long iflags = 0;
> +
> + if (xflags & FS_XFLAG_SYNC)
> + iflags |= EXT4_SYNC_FL;
> + if (xflags & FS_XFLAG_IMMUTABLE)
> + iflags |= EXT4_IMMUTABLE_FL;
> + if (xflags & FS_XFLAG_APPEND)
> + iflags |= EXT4_APPEND_FL;
> + if (xflags & FS_XFLAG_NODUMP)
> + iflags |= EXT4_NODUMP_FL;
> + if (xflags & FS_XFLAG_NOATIME)
> + iflags |= EXT4_NOATIME_FL;
> + if (xflags & FS_XFLAG_PROJINHERIT)
> + iflags |= EXT4_PROJINHERIT_FL;
> +
> + return iflags;
> +}
> +
> long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> {
> struct inode *inode = file_inode(filp);
> @@ -221,11 +445,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> flags = ei->i_flags & EXT4_FL_USER_VISIBLE;
> return put_user(flags, (int __user *) arg);
> case EXT4_IOC_SETFLAGS: {
> - handle_t *handle = NULL;
> - int err, migrate = 0;
> - struct ext4_iloc iloc;
> - unsigned int oldflags, mask, i;
> - unsigned int jflag;
> + int err;
>
> if (!inode_owner_or_capable(inode))
> return -EACCES;
> @@ -239,89 +459,8 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
>
> flags = ext4_mask_flags(inode->i_mode, flags);
>
> - err = -EPERM;
> mutex_lock(&inode->i_mutex);
> - /* Is it quota file? Do not allow user to mess with it */
> - if (IS_NOQUOTA(inode))
> - goto flags_out;
> -
> - oldflags = ei->i_flags;
> -
> - /* The JOURNAL_DATA flag is modifiable only by root */
> - jflag = flags & EXT4_JOURNAL_DATA_FL;
> -
> - /*
> - * The IMMUTABLE and APPEND_ONLY flags can only be changed by
> - * the relevant capability.
> - *
> - * This test looks nicer. Thanks to Pauline Middelink
> - */
> - if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
> - if (!capable(CAP_LINUX_IMMUTABLE))
> - goto flags_out;
> - }
> -
> - /*
> - * The JOURNAL_DATA flag can only be changed by
> - * the relevant capability.
> - */
> - if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
> - if (!capable(CAP_SYS_RESOURCE))
> - goto flags_out;
> - }
> - if ((flags ^ oldflags) & EXT4_EXTENTS_FL)
> - migrate = 1;
> -
> - if (flags & EXT4_EOFBLOCKS_FL) {
> - /* we don't support adding EOFBLOCKS flag */
> - if (!(oldflags & EXT4_EOFBLOCKS_FL)) {
> - err = -EOPNOTSUPP;
> - goto flags_out;
> - }
> - } else if (oldflags & EXT4_EOFBLOCKS_FL)
> - ext4_truncate(inode);
> -
> - handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
> - if (IS_ERR(handle)) {
> - err = PTR_ERR(handle);
> - goto flags_out;
> - }
> - if (IS_SYNC(inode))
> - ext4_handle_sync(handle);
> - err = ext4_reserve_inode_write(handle, inode, &iloc);
> - if (err)
> - goto flags_err;
> -
> - for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
> - if (!(mask & EXT4_FL_USER_MODIFIABLE))
> - continue;
> - if (mask & flags)
> - ext4_set_inode_flag(inode, i);
> - else
> - ext4_clear_inode_flag(inode, i);
> - }
> -
> - ext4_set_inode_flags(inode);
> - inode->i_ctime = ext4_current_time(inode);
> -
> - err = ext4_mark_iloc_dirty(handle, inode, &iloc);
> -flags_err:
> - ext4_journal_stop(handle);
> - if (err)
> - goto flags_out;
> -
> - if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL))
> - err = ext4_change_inode_journal_flag(inode, jflag);
> - if (err)
> - goto flags_out;
> - if (migrate) {
> - if (flags & EXT4_EXTENTS_FL)
> - err = ext4_ext_migrate(inode);
> - else
> - err = ext4_ind_migrate(inode);
> - }
> -
> -flags_out:
> + err = ext4_ioctl_setflags(inode, flags);
> mutex_unlock(&inode->i_mutex);
> mnt_drop_write_file(filp);
> return err;
> @@ -697,6 +836,60 @@ encryption_policy_out:
> return -EOPNOTSUPP;
> #endif
> }
> + case EXT4_IOC_FSGETXATTR:
> + {
> + struct fsxattr fa;
> +
> + memset(&fa, 0, sizeof(struct fsxattr));
> + ext4_get_inode_flags(ei);
> + fa.fsx_xflags = ext4_iflags_to_xflags(ei->i_flags & EXT4_FL_USER_VISIBLE);
> +
> + if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
> + EXT4_FEATURE_RO_COMPAT_PROJECT)) {
> + fa.fsx_projid = (__u32)from_kprojid(&init_user_ns,
> + EXT4_I(inode)->i_projid);
> + }
> +
> + if (copy_to_user((struct fsxattr __user *)arg,
> + &fa, sizeof(fa)))
> + return -EFAULT;
> + return 0;
> + }
> + case EXT4_IOC_FSSETXATTR:
> + {
> + struct fsxattr fa;
> + int err;
> +
> + if (copy_from_user(&fa, (struct fsxattr __user *)arg,
> + sizeof(fa)))
> + return -EFAULT;
> +
> + /* Make sure caller has proper permission */
> + if (!inode_owner_or_capable(inode))
> + return -EACCES;
> +
> + err = mnt_want_write_file(filp);
> + if (err)
> + return err;
> +
> + flags = ext4_xflags_to_iflags(fa.fsx_xflags);
> + flags = ext4_mask_flags(inode->i_mode, flags);
> +
> + mutex_lock(&inode->i_mutex);
> + flags = (ei->i_flags & ~EXT4_FL_XFLAG_VISIBLE) |
> + (flags & EXT4_FL_XFLAG_VISIBLE);
> + err = ext4_ioctl_setflags(inode, flags);
> + mutex_unlock(&inode->i_mutex);
> + mnt_drop_write_file(filp);
> + if (err)
> + return err;
> +
> + err = ext4_ioctl_setproject(filp, fa.fsx_projid);
> + if (err)
> + return err;
> +
> + return 0;
> + }
> default:
> return -ENOTTY;
> }
> diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
> index 18dc721..64c7ae6 100644
> --- a/fs/xfs/libxfs/xfs_fs.h
> +++ b/fs/xfs/libxfs/xfs_fs.h
> @@ -36,38 +36,25 @@ struct dioattr {
> #endif
>
> /*
> - * Structure for XFS_IOC_FSGETXATTR[A] and XFS_IOC_FSSETXATTR.
> - */
> -#ifndef HAVE_FSXATTR
> -struct fsxattr {
> - __u32 fsx_xflags; /* xflags field value (get/set) */
> - __u32 fsx_extsize; /* extsize field value (get/set)*/
> - __u32 fsx_nextents; /* nextents field value (get) */
> - __u32 fsx_projid; /* project identifier (get/set) */
> - unsigned char fsx_pad[12];
> -};
> -#endif
> -
> -/*
> * Flags for the bs_xflags/fsx_xflags field
> * There should be a one-to-one correspondence between these flags and the
> * XFS_DIFLAG_s.
> */
> -#define XFS_XFLAG_REALTIME 0x00000001 /* data in realtime volume */
> -#define XFS_XFLAG_PREALLOC 0x00000002 /* preallocated file extents */
> -#define XFS_XFLAG_IMMUTABLE 0x00000008 /* file cannot be modified */
> -#define XFS_XFLAG_APPEND 0x00000010 /* all writes append */
> -#define XFS_XFLAG_SYNC 0x00000020 /* all writes synchronous */
> -#define XFS_XFLAG_NOATIME 0x00000040 /* do not update access time */
> -#define XFS_XFLAG_NODUMP 0x00000080 /* do not include in backups */
> -#define XFS_XFLAG_RTINHERIT 0x00000100 /* create with rt bit set */
> -#define XFS_XFLAG_PROJINHERIT 0x00000200 /* create with parents projid */
> -#define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */
> -#define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */
> -#define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */
> -#define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */
> -#define XFS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */
> -#define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
> +#define XFS_XFLAG_REALTIME FS_XFLAG_REALTIME /* data in realtime volume */
> +#define XFS_XFLAG_PREALLOC FS_XFLAG_PREALLOC /* preallocated file extents */
> +#define XFS_XFLAG_IMMUTABLE FS_XFLAG_IMMUTABLE /* file cannot be modified */
> +#define XFS_XFLAG_APPEND FS_XFLAG_APPEND /* all writes append */
> +#define XFS_XFLAG_SYNC FS_XFLAG_SYNC /* all writes synchronous */
> +#define XFS_XFLAG_NOATIME FS_XFLAG_NOATIME /* do not update access time */
> +#define XFS_XFLAG_NODUMP FS_XFLAG_NODUMP /* do not include in backups */
> +#define XFS_XFLAG_RTINHERIT FS_XFLAG_RTINHERIT /* create with rt bit set */
> +#define XFS_XFLAG_PROJINHERIT FS_XFLAG_PROJINHERIT /* create with parents projid */
> +#define XFS_XFLAG_NOSYMLINKS FS_XFLAG_NOSYMLINKS /* disallow symlink creation */
> +#define XFS_XFLAG_EXTSIZE FS_XFLAG_EXTSIZE /* extent size allocator hint */
> +#define XFS_XFLAG_EXTSZINHERIT FS_XFLAG_EXTSZINHERIT /* inherit inode extent size */
> +#define XFS_XFLAG_NODEFRAG FS_XFLAG_NODEFRAG /* do not defragment */
> +#define XFS_XFLAG_FILESTREAM FS_XFLAG_FILESTREAM /* use filestream allocator */
> +#define XFS_XFLAG_HASATTR FS_XFLAG_HASATTR /* no DIFLAG for this */
>
> /*
> * Structure for XFS_IOC_GETBMAP.
> @@ -503,8 +490,8 @@ typedef struct xfs_swapext
> #define XFS_IOC_ALLOCSP _IOW ('X', 10, struct xfs_flock64)
> #define XFS_IOC_FREESP _IOW ('X', 11, struct xfs_flock64)
> #define XFS_IOC_DIOINFO _IOR ('X', 30, struct dioattr)
> -#define XFS_IOC_FSGETXATTR _IOR ('X', 31, struct fsxattr)
> -#define XFS_IOC_FSSETXATTR _IOW ('X', 32, struct fsxattr)
> +#define XFS_IOC_FSGETXATTR FS_IOC_FSGETXATTR
> +#define XFS_IOC_FSSETXATTR FS_IOC_FSSETXATTR
> #define XFS_IOC_ALLOCSP64 _IOW ('X', 36, struct xfs_flock64)
> #define XFS_IOC_FREESP64 _IOW ('X', 37, struct xfs_flock64)
> #define XFS_IOC_GETBMAP _IOWR('X', 38, struct getbmap)
> diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
> index f15d980..627f58e 100644
> --- a/include/uapi/linux/fs.h
> +++ b/include/uapi/linux/fs.h
> @@ -58,6 +58,36 @@ struct inodes_stat_t {
> long dummy[5]; /* padding for sysctl ABI compatibility */
> };
>
> +/*
> + * Structure for FS_IOC_FSGETXATTR and FS_IOC_FSSETXATTR.
> + */
> +struct fsxattr {
> + __u32 fsx_xflags; /* xflags field value (get/set) */
> + __u32 fsx_extsize; /* extsize field value (get/set)*/
> + __u32 fsx_nextents; /* nextents field value (get) */
> + __u32 fsx_projid; /* project identifier (get/set) */
> + unsigned char fsx_pad[12];
> +};
> +
> +/*
> + * Flags for the fsx_xflags field
> + */
> +#define FS_XFLAG_REALTIME 0x00000001 /* data in realtime volume */
> +#define FS_XFLAG_PREALLOC 0x00000002 /* preallocated file extents */
> +#define FS_XFLAG_IMMUTABLE 0x00000008 /* file cannot be modified */
> +#define FS_XFLAG_APPEND 0x00000010 /* all writes append */
> +#define FS_XFLAG_SYNC 0x00000020 /* all writes synchronous */
> +#define FS_XFLAG_NOATIME 0x00000040 /* do not update access time */
> +#define FS_XFLAG_NODUMP 0x00000080 /* do not include in backups */
> +#define FS_XFLAG_RTINHERIT 0x00000100 /* create with rt bit set */
> +#define FS_XFLAG_PROJINHERIT 0x00000200 /* create with parents projid */
> +#define FS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */
> +#define FS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */
> +#define FS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */
> +#define FS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */
> +#define FS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */
> +#define FS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
> +
>
> #define NR_FILE 8192 /* this can well be larger on a larger system */
>
> @@ -165,6 +195,8 @@ struct inodes_stat_t {
> #define FS_IOC_GETVERSION _IOR('v', 1, long)
> #define FS_IOC_SETVERSION _IOW('v', 2, long)
> #define FS_IOC_FIEMAP _IOWR('f', 11, struct fiemap)
> +#define FS_IOC_FSGETXATTR _IOR('X', 31, struct fsxattr)
> +#define FS_IOC_FSSETXATTR _IOW('X', 32, struct fsxattr)
> #define FS_IOC32_GETFLAGS _IOR('f', 1, int)
> #define FS_IOC32_SETFLAGS _IOW('f', 2, int)
> #define FS_IOC32_GETVERSION _IOR('v', 1, int)
> --
> 1.7.1
>
--
Jan Kara <jack@suse.cz>
SUSE Labs, CR
^ permalink raw reply
* Re: Regression: Requiring CAP_SYS_ADMIN for /proc/<pid>/pagemap causes application-level breakage
From: Mark Williamson @ 2015-04-24 16:43 UTC (permalink / raw)
To: Mark Seaborn
Cc: kernel list, Kirill A. Shutemov, Pavel Emelyanov,
Konstantin Khlebnikov, Andrew Morton, Linus Torvalds,
Andy Lutomirski, linux-api, Finn Grimwood, Daniel James
In-Reply-To: <CAL82V5P-6_3kKfkgBuv1WMSu5xQ-0mUs7pHXegyPAzgroTgLtA@mail.gmail.com>
Hi Mark,
On Fri, Apr 24, 2015 at 4:26 PM, Mark Seaborn <mseaborn@chromium.org> wrote:
> I'm curious, what do you use the physical page addresses for?
>
> Since you pointed to http://undo-software.com, which talks about
> reversible debugging tools, I can guess you would use the soft-dirty
> flag to implement copy-on-write snapshotting. I'm guessing you might
> use physical page addresses for determining when the same page is
> mapped twice (in the same process or different processes)?
That's pretty much it. Actually, we're effectively using the physical
addresses to emulate soft-dirty. For certain operations (e.g. some
system calls) we need to track what memory has changed since we last
looked at the process state. We have a mechanism that forks a child
process, runs the system call, then refers to pagemap to figure out
what's been modified.
Currently, our mechanism compares the physical addresses of pages
before and after the syscall so that we can see which pages got CoWed.
This is perhaps a slightly "unconventional" use of the interface but
we support kernels that predate the soft-dirty mechanism and (as far
as we know) this is probably the best way we can answer "What got
changed?" on those releases.
Using the soft-dirty mechanism where available should make our code
both cleaner and faster, so if we can fix the pagemap file to allow
that then we'll be quite happy!
Cheers,
Mark
^ permalink raw reply
* Re: Regression: Requiring CAP_SYS_ADMIN for /proc/<pid>/pagemap causes application-level breakage
From: Mark Williamson @ 2015-04-24 16:46 UTC (permalink / raw)
To: Linus Torvalds
Cc: Linux Kernel Mailing List, Kirill A. Shutemov, Pavel Emelyanov,
Konstantin Khlebnikov, Andrew Morton, Mark Seaborn,
Andy Lutomirski, Linux API, Finn Grimwood, Daniel James
In-Reply-To: <CA+55aFymwdHBs02GQkqQYwYF9Ru5dMKd4=2whLUfPwZSPU7ZGA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Hi Linus,
Thanks for responding so quickly!
On Fri, Apr 24, 2015 at 5:08 PM, Linus Torvalds
<torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org> wrote:
> So the one exception to the regression rule is "security fixes", but
> even for security fixes we do try to be as reasonable as humanly
> possible to make them not break things.
Understood - there are clear reasons something had to be done here.
> Now, as you mentioned, one option is to not outright disallow accesses
> to the /proc/PID/pagemap, but to at least hide the page frame numbers.
> However, I don't believe that we have a good enough scrambling model
> to make that reasonable. Remember: any attacker will be able to see
> our scrambling code, so it would need to be both cryptographically
> secure *and* use a truly random per-VM secret key. Quite frankly,
> that's a _lot_ of effort for dubious gain...
*nod*
> So the "just show physical addresses as zero for non-root users"
> (instead of the outright ban on opening the file) is likely the only
> really viable alternative.
>
> It sounds like that could work for you. So if you can modify the app
> to do that, and send me a tested kernel patch that moves the
> permission check into the read phase (remember to use the open-time
> credentials in "file->f_cred" rather than the read-time credentials in
> "current" - otherwise you can trick some suid program to read the fily
> that an unauthorized user opened), then we can have this fixed. Does
> that sound reasonable?
That sounds very reasonable, thank you! We'll cook up a patch and get
back to you.
Thanks,
Mark
^ permalink raw reply
* Re: [RFC] capabilities: Ambient capabilities
From: Serge Hallyn @ 2015-04-24 17:53 UTC (permalink / raw)
To: Christoph Lameter
Cc: Andy Lutomirski, Jarkko Sakkinen, Andrew Lutomirski, Ted Ts'o,
Andrew Morton, Andrew G. Morgan, Linux API, Mimi Zohar,
Michael Kerrisk, Austin S Hemmelgarn, linux-security-module,
Aaron Jones, Serge Hallyn, LKML, Markku Savela, Kees Cook,
Jonathan Corbet
In-Reply-To: <alpine.DEB.2.11.1504230900260.32203-gkYfJU5Cukgdnm+yROfE0A@public.gmane.org>
Quoting Christoph Lameter (cl-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org):
> On Thu, 9 Apr 2015, Christoph Lameter wrote:
>
> > > I'll submit a new version this week with the securebits. Sorry for the delay.
> > Are we going to get a new version?
>
> Replying to my own here. Cant we simply use the SETPCAP approach as per
> the patch I posted?
Andy had objections to that, but it seems ok to me.
-serge
^ permalink raw reply
* Re: [RFC] capabilities: Ambient capabilities
From: Andy Lutomirski @ 2015-04-24 18:41 UTC (permalink / raw)
To: Serge Hallyn
Cc: Christoph Lameter, Jarkko Sakkinen, Andrew Lutomirski,
Ted Ts'o, Andrew Morton, Andrew G. Morgan, Linux API,
Mimi Zohar, Michael Kerrisk, Austin S Hemmelgarn,
linux-security-module, Aaron Jones, Serge Hallyn, LKML,
Markku Savela, Kees Cook, Jonathan Corbet
In-Reply-To: <20150424175348.GL16377@ubuntumail>
On Fri, Apr 24, 2015 at 10:53 AM, Serge Hallyn <serge.hallyn@ubuntu.com> wrote:
> Quoting Christoph Lameter (cl@linux.com):
>> On Thu, 9 Apr 2015, Christoph Lameter wrote:
>>
>> > > I'll submit a new version this week with the securebits. Sorry for the delay.
>> > Are we going to get a new version?
>>
>> Replying to my own here. Cant we simply use the SETPCAP approach as per
>> the patch I posted?
>
> Andy had objections to that, but it seems ok to me.
>
I object because CAP_SETPCAP is very powerful whereas
CAP_NET_BIND_SERVICE, for example, isn't. I'm fine with having a
switch to turn off ambient caps, but requiring the "on" state to give
processes superpowers seems unfortunate.
Sorry for the huge delay. I got caught up with travel and the merge
window. Here's a sneak peek:
https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=cap_ambient
I need to write the user code to go with it and test it a bit before
sending it out for real.
--Andy
^ permalink raw reply
* Re: [RFC] capabilities: Ambient capabilities
From: Serge Hallyn @ 2015-04-24 19:09 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Christoph Lameter, Jarkko Sakkinen, Andrew Lutomirski,
Ted Ts'o, Andrew Morton, Andrew G. Morgan, Linux API,
Mimi Zohar, Michael Kerrisk, Austin S Hemmelgarn,
linux-security-module, Aaron Jones, Serge Hallyn, LKML,
Markku Savela, Kees Cook, Jonathan Corbet
In-Reply-To: <CALCETrW5_85mFFTkzCVNA5N1KQeNBrkw2d8FF3H3LYtmz6UAPw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Quoting Andy Lutomirski (luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org):
> On Fri, Apr 24, 2015 at 10:53 AM, Serge Hallyn <serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA@public.gmane.org> wrote:
> > Quoting Christoph Lameter (cl-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org):
> >> On Thu, 9 Apr 2015, Christoph Lameter wrote:
> >>
> >> > > I'll submit a new version this week with the securebits. Sorry for the delay.
> >> > Are we going to get a new version?
> >>
> >> Replying to my own here. Cant we simply use the SETPCAP approach as per
> >> the patch I posted?
> >
> > Andy had objections to that, but it seems ok to me.
> >
>
> I object because CAP_SETPCAP is very powerful whereas
> CAP_NET_BIND_SERVICE, for example, isn't. I'm fine with having a
> switch to turn off ambient caps, but requiring the "on" state to give
Would only really be needed for the initial 'enable ambient caps for this
process tree', though. Once that was set, add/remove'ing caps from the
ambient set wouldn't need to be required.
> processes superpowers seems unfortunate.
>
> Sorry for the huge delay. I got caught up with travel and the merge
> window. Here's a sneak peek:
>
> https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=cap_ambient
>
> I need to write the user code to go with it and test it a bit before
> sending it out for real.
Ok, thanks
-serge
^ permalink raw reply
* Re: [RFC] capabilities: Ambient capabilities
From: Christoph Lameter @ 2015-04-24 19:25 UTC (permalink / raw)
To: Serge Hallyn
Cc: Andy Lutomirski, Jarkko Sakkinen, Andrew Lutomirski, Ted Ts'o,
Andrew Morton, Andrew G. Morgan, Linux API, Mimi Zohar,
Michael Kerrisk, Austin S Hemmelgarn, linux-security-module,
Aaron Jones, Serge Hallyn, LKML, Markku Savela, Kees Cook,
Jonathan Corbet
In-Reply-To: <20150424190935.GN16377@ubuntumail>
On Fri, 24 Apr 2015, Serge Hallyn wrote:
> > I object because CAP_SETPCAP is very powerful whereas
> > CAP_NET_BIND_SERVICE, for example, isn't. I'm fine with having a
> > switch to turn off ambient caps, but requiring the "on" state to give
>
> Would only really be needed for the initial 'enable ambient caps for this
> process tree', though. Once that was set, add/remove'ing caps from the
> ambient set wouldn't need to be required.
Exactly. Its much simpler than alternate approaches. And its convoluted
enough.
^ permalink raw reply
* Re: [RFC] capabilities: Ambient capabilities
From: Andy Lutomirski @ 2015-04-24 19:53 UTC (permalink / raw)
To: Serge Hallyn
Cc: Christoph Lameter, Jarkko Sakkinen, Andrew Lutomirski,
Ted Ts'o, Andrew Morton, Andrew G. Morgan, Linux API,
Mimi Zohar, Michael Kerrisk, Austin S Hemmelgarn,
linux-security-module, Aaron Jones, Serge Hallyn, LKML,
Markku Savela, Kees Cook, Jonathan Corbet
In-Reply-To: <20150424190935.GN16377@ubuntumail>
On Fri, Apr 24, 2015 at 12:09 PM, Serge Hallyn <serge.hallyn@ubuntu.com> wrote:
> Quoting Andy Lutomirski (luto@amacapital.net):
>> On Fri, Apr 24, 2015 at 10:53 AM, Serge Hallyn <serge.hallyn@ubuntu.com> wrote:
>> > Quoting Christoph Lameter (cl@linux.com):
>> >> On Thu, 9 Apr 2015, Christoph Lameter wrote:
>> >>
>> >> > > I'll submit a new version this week with the securebits. Sorry for the delay.
>> >> > Are we going to get a new version?
>> >>
>> >> Replying to my own here. Cant we simply use the SETPCAP approach as per
>> >> the patch I posted?
>> >
>> > Andy had objections to that, but it seems ok to me.
>> >
>>
>> I object because CAP_SETPCAP is very powerful whereas
>> CAP_NET_BIND_SERVICE, for example, isn't. I'm fine with having a
>> switch to turn off ambient caps, but requiring the "on" state to give
>
> Would only really be needed for the initial 'enable ambient caps for this
> process tree', though. Once that was set, add/remove'ing caps from the
> ambient set wouldn't need to be required.
That's sort of what my patch does -- you need CAP_SETPCAP to switch
the securebit.
But Christoph's patch required it to add caps to the ambient set, right?
--Andy
^ permalink raw reply
* Re: [RFC] capabilities: Ambient capabilities
From: Christoph Lameter @ 2015-04-24 20:13 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Serge Hallyn, Jarkko Sakkinen, Andrew Lutomirski, Ted Ts'o,
Andrew Morton, Andrew G. Morgan, Linux API, Mimi Zohar,
Michael Kerrisk, Austin S Hemmelgarn, linux-security-module,
Aaron Jones, Serge Hallyn, LKML, Markku Savela, Kees Cook,
Jonathan Corbet
In-Reply-To: <CALCETrV7S0dLkNWMSYsL7MFuLgdpQwUEAjW6zTwRE8uhh_AuBQ@mail.gmail.com>
On Fri, 24 Apr 2015, Andy Lutomirski wrote:
> That's sort of what my patch does -- you need CAP_SETPCAP to switch
> the securebit.
>
> But Christoph's patch required it to add caps to the ambient set, right?
Yes but you seem to be just adding one additional step without too much of
a benefit because you still need CAP_SETPCAP.
^ permalink raw reply
* Re: [RFC] capabilities: Ambient capabilities
From: Andy Lutomirski @ 2015-04-24 20:18 UTC (permalink / raw)
To: Christoph Lameter
Cc: Serge Hallyn, Jarkko Sakkinen, Andrew Lutomirski, Ted Ts'o,
Andrew Morton, Andrew G. Morgan, Linux API, Mimi Zohar,
Michael Kerrisk, Austin S Hemmelgarn, linux-security-module,
Aaron Jones, Serge Hallyn, LKML, Markku Savela, Kees Cook,
Jonathan Corbet
In-Reply-To: <alpine.DEB.2.11.1504241512570.11839-gkYfJU5Cukgdnm+yROfE0A@public.gmane.org>
On Fri, Apr 24, 2015 at 1:13 PM, Christoph Lameter <cl-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org> wrote:
> On Fri, 24 Apr 2015, Andy Lutomirski wrote:
>
>> That's sort of what my patch does -- you need CAP_SETPCAP to switch
>> the securebit.
>>
>> But Christoph's patch required it to add caps to the ambient set, right?
>
> Yes but you seem to be just adding one additional step without too much of
> a benefit because you still need CAP_SETPCAP.
>
No, because I set the default to on :)
Also, in my model you can do:
$ sudo capset cap_whatever=eip something
$ ./something
and the program can make its cap be ambient and run a helper. In the
CAP_SETPCAP model, that doesn't work.
--Andy
--
Andy Lutomirski
AMA Capital Management, LLC
^ permalink raw reply
* Re: [PATCH v3 2/4] of: overlay: global sysfs enable attribute
From: Greg KH @ 2015-04-24 20:29 UTC (permalink / raw)
To: Pantelis Antoniou
Cc: Rob Herring, Grant Likely, Andrew Morton, Matt Porter, Koen Kooi,
Guenter Roeck, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, Pantelis Antoniou
In-Reply-To: <1429868744-19863-3-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
On Fri, Apr 24, 2015 at 12:45:42PM +0300, Pantelis Antoniou wrote:
> A throw once master enable switch to protect against any
> further overlay applications if the administrator desires so.
>
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
> ---
> drivers/of/overlay.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 44 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
> index f17f5ef..c335809 100644
> --- a/drivers/of/overlay.c
> +++ b/drivers/of/overlay.c
> @@ -21,6 +21,7 @@
> #include <linux/err.h>
> #include <linux/idr.h>
> #include <linux/sysfs.h>
> +#include <linux/atomic.h>
>
> #include "of_private.h"
>
> @@ -55,8 +56,12 @@ struct of_overlay {
> struct kobject kobj;
> };
>
> +/* master enable switch; once set to 0 can't be re-enabled */
> +static atomic_t ov_enable = ATOMIC_INIT(1);
> +
> static int of_overlay_apply_one(struct of_overlay *ov,
> struct device_node *target, const struct device_node *overlay);
> +static int overlay_removal_is_ok(struct of_overlay *ov);
>
> static int of_overlay_apply_single_property(struct of_overlay *ov,
> struct device_node *target, struct property *prop)
> @@ -339,6 +344,37 @@ void of_overlay_release(struct kobject *kobj)
> kfree(ov);
> }
>
> +static ssize_t enable_show(struct kobject *kobj,
> + struct kobj_attribute *attr, char *buf)
> +{
> + return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&ov_enable));
> +}
> +
> +static ssize_t enable_store(struct kobject *kobj,
> + struct kobj_attribute *attr, const char *buf, size_t count)
> +{
> + int ret;
> + long new_enable;
> +
> + ret = kstrtol(buf, 10, &new_enable);
> + if (ret != 0)
> + return ret;
> + if ((unsigned long)new_enable > 1)
> + return -EINVAL;
> + /* if we've disabled it, no going back */
> + if (atomic_read(&ov_enable) == 0)
> + return -EPERM;
> + atomic_set(&ov_enable, (int)new_enable);
> + return count;
> +}
> +
> +static struct kobj_attribute enable_attr = __ATTR_RW(enable);
> +
> +static const struct attribute *overlay_global_attrs[] = {
> + &enable_attr.attr,
> + NULL
> +};
Why not make this an attribute group and then attach it to the kobj_type
to create the files in a race-free manner?
> +
> static struct kobj_type of_overlay_ktype = {
> .release = of_overlay_release,
> };
> @@ -360,6 +396,10 @@ int of_overlay_create(struct device_node *tree)
> struct of_overlay *ov;
> int err, id;
>
> + /* administratively disabled */
> + if (!atomic_read(&ov_enable))
> + return -EPERM;
> +
> /* allocate the overlay structure */
> ov = kzalloc(sizeof(*ov), GFP_KERNEL);
> if (ov == NULL)
> @@ -596,5 +636,8 @@ int of_overlay_init(void)
> if (!ov_kset)
> return -ENOMEM;
>
> - return 0;
> + rc = sysfs_create_files(&ov_kset->kobj, overlay_global_attrs);
> + WARN(rc, "%s: error adding global attributes\n", __func__);
What can a user do with this warning message? If nothing, then don't
print it out, right?
You are creating sysfs files _after_ the kobject has been announced to
userspace, causing nasty race conditions. Please don't do that.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH v3 4/4] Documentation: ABI: /sys/firmware/devicetree/overlays
From: Greg KH @ 2015-04-24 20:31 UTC (permalink / raw)
To: Pantelis Antoniou
Cc: Rob Herring, Grant Likely, Andrew Morton, Matt Porter, Koen Kooi,
Guenter Roeck, devicetree, linux-kernel, linux-api,
Pantelis Antoniou
In-Reply-To: <1429868744-19863-5-git-send-email-pantelis.antoniou@konsulko.com>
On Fri, Apr 24, 2015 at 12:45:44PM +0300, Pantelis Antoniou wrote:
> Documentation ABI entry for overlays sysfs entries.
>
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
> ---
> .../ABI/testing/sysfs-firmware-devicetree-overlays | 23 ++++++++++++++++++++++
> 1 file changed, 23 insertions(+)
> create mode 100644 Documentation/ABI/testing/sysfs-firmware-devicetree-overlays
>
> diff --git a/Documentation/ABI/testing/sysfs-firmware-devicetree-overlays b/Documentation/ABI/testing/sysfs-firmware-devicetree-overlays
> new file mode 100644
> index 0000000..6b81f1c
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-firmware-devicetree-overlays
> @@ -0,0 +1,23 @@
> +What: /sys/firmware/devicetree/overlays/
> +Date: March 2015
> +Contact: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
> +Description:
> + This directory contains the applied device tree overlays of
> + the running system, as directories of the overlay id.
"as"?
> +
> + enable: The master enable switch, by default is 1, and when
> + set to 0 it cannot be re-enabled for security reasons.
What are those reasons?
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH v3 2/4] of: overlay: global sysfs enable attribute
From: Greg KH @ 2015-04-24 20:36 UTC (permalink / raw)
To: Pantelis Antoniou
Cc: Rob Herring, Grant Likely, Andrew Morton, Matt Porter, Koen Kooi,
Guenter Roeck, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, Pantelis Antoniou
In-Reply-To: <1429868744-19863-3-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
On Fri, Apr 24, 2015 at 12:45:42PM +0300, Pantelis Antoniou wrote:
> A throw once master enable switch to protect against any
> further overlay applications if the administrator desires so.
>
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
> ---
> drivers/of/overlay.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 44 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
> index f17f5ef..c335809 100644
> --- a/drivers/of/overlay.c
> +++ b/drivers/of/overlay.c
> @@ -21,6 +21,7 @@
> #include <linux/err.h>
> #include <linux/idr.h>
> #include <linux/sysfs.h>
> +#include <linux/atomic.h>
>
> #include "of_private.h"
>
> @@ -55,8 +56,12 @@ struct of_overlay {
> struct kobject kobj;
> };
>
> +/* master enable switch; once set to 0 can't be re-enabled */
> +static atomic_t ov_enable = ATOMIC_INIT(1);
> +
> static int of_overlay_apply_one(struct of_overlay *ov,
> struct device_node *target, const struct device_node *overlay);
> +static int overlay_removal_is_ok(struct of_overlay *ov);
>
> static int of_overlay_apply_single_property(struct of_overlay *ov,
> struct device_node *target, struct property *prop)
> @@ -339,6 +344,37 @@ void of_overlay_release(struct kobject *kobj)
> kfree(ov);
> }
>
> +static ssize_t enable_show(struct kobject *kobj,
> + struct kobj_attribute *attr, char *buf)
> +{
> + return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&ov_enable));
> +}
> +
> +static ssize_t enable_store(struct kobject *kobj,
> + struct kobj_attribute *attr, const char *buf, size_t count)
> +{
> + int ret;
> + long new_enable;
> +
> + ret = kstrtol(buf, 10, &new_enable);
strtobool()?
^ permalink raw reply
* Re: [RFC] capabilities: Ambient capabilities
From: Serge E. Hallyn @ 2015-04-24 21:15 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Christoph Lameter, Serge Hallyn, Jarkko Sakkinen,
Andrew Lutomirski, Ted Ts'o, Andrew Morton, Andrew G. Morgan,
Linux API, Mimi Zohar, Michael Kerrisk, Austin S Hemmelgarn,
linux-security-module, Aaron Jones, Serge Hallyn, LKML,
Markku Savela, Kees Cook, Jonathan Corbet
In-Reply-To: <CALCETrUrFm9n_4xTj4ELkzTSnWHfxQtANqz2wpzU7riTihLDaA@mail.gmail.com>
On Fri, Apr 24, 2015 at 01:18:44PM -0700, Andy Lutomirski wrote:
> On Fri, Apr 24, 2015 at 1:13 PM, Christoph Lameter <cl@linux.com> wrote:
> > On Fri, 24 Apr 2015, Andy Lutomirski wrote:
> >
> >> That's sort of what my patch does -- you need CAP_SETPCAP to switch
> >> the securebit.
> >>
> >> But Christoph's patch required it to add caps to the ambient set, right?
> >
> > Yes but you seem to be just adding one additional step without too much of
> > a benefit because you still need CAP_SETPCAP.
> >
>
> No, because I set the default to on :)
Right - I definately prefer
. default off
. CAP_SETPCAP required to turn it on (for self and children)
. once on, anyone can copy bits from (whatever we decided) to pA.
> Also, in my model you can do:
>
> $ sudo capset cap_whatever=eip something
> $ ./something
>
> and the program can make its cap be ambient and run a helper. In the
> CAP_SETPCAP model, that doesn't work.
>
> --Andy
>
> --
> Andy Lutomirski
> AMA Capital Management, LLC
> --
> 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/
^ permalink raw reply
* Re: [PATCH v2 01/11] stm class: Introduce an abstraction for System Trace Module devices
From: Mathieu Poirier @ 2015-04-24 22:07 UTC (permalink / raw)
To: Alexander Shishkin
Cc: Greg Kroah-Hartman,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Paul Bolle,
peter.lachner-ral2JQCrhuEAvxtiuMwx3w,
norbert.schulz-ral2JQCrhuEAvxtiuMwx3w,
keven.boell-ral2JQCrhuEAvxtiuMwx3w,
yann.fouassier-ral2JQCrhuEAvxtiuMwx3w,
laurent.fert-ral2JQCrhuEAvxtiuMwx3w,
linux-api-u79uwXL29TY76Z2rM5mHXA, Pratik Patel
In-Reply-To: <1427056381-27614-2-git-send-email-alexander.shishkin-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
[...]
> +
> +static int __init stm_core_init(void)
> +{
> + int err;
> +
> + err = class_register(&stm_class);
> + if (err)
> + return err;
> +
> + err = class_register(&stm_source_class);
> + if (err)
> + goto err_stm;
> +
> + err = stp_configfs_init();
You can't move "stp_configfs_init()" here and leave "stm_core_init()"
as a "postcore_initcall()". Function "stp_configfs_init()" calls
"configfs_register_subsystem()" which, after some time, will end up
calling "configfs_new_dirent()". In there an access to the cache
allocator is done on "configfs_dir_cachep", but it is only initialised
in "configfs_init()" at "module_init()" time, resulting in a -ENOMEM
error.
I don't see how it can be different on x86 but on ARM it is definitely
a problem.
Mathieu
> + if (err)
> + goto err_src;
> +
> + init_srcu_struct(&stm_source_srcu);
> +
> + stm_core_up++;
> +
> + return 0;
> +
> +err_src:
> + class_unregister(&stm_source_class);
> +err_stm:
> + class_unregister(&stm_class);
> +
> + return err;
> +}
> +
> +postcore_initcall(stm_core_init);
> +
> +static void __exit stm_core_exit(void)
> +{
> + class_unregister(&stm_source_class);
> + class_unregister(&stm_class);
> + stp_configfs_exit();
> +}
> +
> +module_exit(stm_core_exit);
> +
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("System Trace Module device class");
> +MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>");
> diff --git a/drivers/hwtracing/stm/policy.c b/drivers/hwtracing/stm/policy.c
> new file mode 100644
> index 0000000000..b5c59a0e0c
> --- /dev/null
> +++ b/drivers/hwtracing/stm/policy.c
> @@ -0,0 +1,467 @@
> +/*
> + * System Trace Module (STM) master/channel allocation policy management
> + * Copyright (c) 2014, Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * A master/channel allocation policy allows mapping string identifiers to
> + * master and channel ranges, where allocation can be done.
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include <linux/types.h>
> +#include <linux/module.h>
> +#include <linux/device.h>
> +#include <linux/configfs.h>
> +#include <linux/slab.h>
> +#include <linux/stm.h>
> +#include "stm.h"
> +
> +/*
> + * STP Master/Channel allocation policy configfs layout.
> + */
> +
> +struct stp_policy {
> + struct config_group group;
> + struct stm_device *stm;
> +};
> +
> +struct stp_policy_node {
> + struct config_group group;
> + struct stm_device *stm;
> + struct stp_policy *policy;
> + unsigned int first_master;
> + unsigned int last_master;
> + unsigned int first_channel;
> + unsigned int last_channel;
> +};
> +
> +void stp_policy_node_get_ranges(struct stp_policy_node *policy_node,
> + unsigned int *mstart, unsigned int *mend,
> + unsigned int *cstart, unsigned int *cend)
> +{
> + *mstart = policy_node->first_master;
> + *mend = policy_node->last_master;
> + *cstart = policy_node->first_channel;
> + *cend = policy_node->last_channel;
> +}
> +
> +static inline char *stp_policy_node_name(struct stp_policy_node *policy_node)
> +{
> + return policy_node->group.cg_item.ci_name ? : "<none>";
> +}
> +
> +static inline struct stp_policy *to_stp_policy(struct config_item *item)
> +{
> + return item ?
> + container_of(to_config_group(item), struct stp_policy, group) :
> + NULL;
> +}
> +
> +static inline struct stp_policy_node *
> +to_stp_policy_node(struct config_item *item)
> +{
> + return item ?
> + container_of(to_config_group(item), struct stp_policy_node,
> + group) :
> + NULL;
> +}
> +
> +static ssize_t stp_policy_node_masters_show(struct stp_policy_node *policy_node,
> + char *page)
> +{
> + ssize_t count;
> +
> + count = sprintf(page, "%u %u\n", policy_node->first_master,
> + policy_node->last_master);
> +
> + return count;
> +}
> +
> +static ssize_t
> +stp_policy_node_masters_store(struct stp_policy_node *policy_node,
> + const char *page, size_t count)
> +{
> + struct stm_device *stm = policy_node->stm;
> + unsigned int first, last;
> + char *p = (char *) page;
> +
> + if (sscanf(p, "%u %u", &first, &last) != 2)
> + return -EINVAL;
> +
> + /* must be within [sw_start..sw_end], which is an inclusive range */
> + if (first > INT_MAX || last > INT_MAX || first > last ||
> + first < stm->data->sw_start ||
> + last > stm->data->sw_end)
> + return -ERANGE;
> +
> + policy_node->first_master = first;
> + policy_node->last_master = last;
> +
> + return count;
> +}
> +
> +static ssize_t
> +stp_policy_node_channels_show(struct stp_policy_node *policy_node, char *page)
> +{
> + ssize_t count;
> +
> + count = sprintf(page, "%u %u\n", policy_node->first_channel,
> + policy_node->last_channel);
> +
> + return count;
> +}
> +
> +static ssize_t
> +stp_policy_node_channels_store(struct stp_policy_node *policy_node,
> + const char *page, size_t count)
> +{
> + unsigned int first, last;
> + char *p = (char *) page;
> +
> + if (sscanf(p, "%u %u", &first, &last) != 2)
> + return -EINVAL;
> +
> + if (first > INT_MAX || last > INT_MAX || first > last ||
> + last >= policy_node->stm->data->sw_nchannels)
> + return -ERANGE;
> +
> + policy_node->first_channel = first;
> + policy_node->last_channel = last;
> +
> + return count;
> +}
> +
> +static void stp_policy_node_release(struct config_item *item)
> +{
> + kfree(to_stp_policy_node(item));
> +}
> +
> +struct stp_policy_node_attribute {
> + struct configfs_attribute attr;
> + ssize_t (*show)(struct stp_policy_node *, char *);
> + ssize_t (*store)(struct stp_policy_node *, const char *, size_t);
> +};
> +
> +static ssize_t stp_policy_node_attr_show(struct config_item *item,
> + struct configfs_attribute *attr,
> + char *page)
> +{
> + struct stp_policy_node *policy_node = to_stp_policy_node(item);
> + struct stp_policy_node_attribute *pn_attr =
> + container_of(attr, struct stp_policy_node_attribute, attr);
> + ssize_t count = 0;
> +
> + if (pn_attr->show)
> + count = pn_attr->show(policy_node, page);
> +
> + return count;
> +}
> +
> +static ssize_t stp_policy_node_attr_store(struct config_item *item,
> + struct configfs_attribute *attr,
> + const char *page, size_t len)
> +{
> + struct stp_policy_node *policy_node = to_stp_policy_node(item);
> + struct stp_policy_node_attribute *pn_attr =
> + container_of(attr, struct stp_policy_node_attribute, attr);
> + ssize_t count = -EINVAL;
> +
> + if (pn_attr->store)
> + count = pn_attr->store(policy_node, page, len);
> +
> + return count;
> +}
> +
> +static struct configfs_item_operations stp_policy_node_item_ops = {
> + .release = stp_policy_node_release,
> + .show_attribute = stp_policy_node_attr_show,
> + .store_attribute = stp_policy_node_attr_store,
> +};
> +
> +static struct stp_policy_node_attribute stp_policy_node_attr_range = {
> + .attr = {
> + .ca_owner = THIS_MODULE,
> + .ca_name = "masters",
> + .ca_mode = S_IRUGO | S_IWUSR,
> + },
> + .show = stp_policy_node_masters_show,
> + .store = stp_policy_node_masters_store,
> +};
> +
> +static struct stp_policy_node_attribute stp_policy_node_attr_channels = {
> + .attr = {
> + .ca_owner = THIS_MODULE,
> + .ca_name = "channels",
> + .ca_mode = S_IRUGO | S_IWUSR,
> + },
> + .show = stp_policy_node_channels_show,
> + .store = stp_policy_node_channels_store,
> +};
> +
> +static struct configfs_attribute *stp_policy_node_attrs[] = {
> + &stp_policy_node_attr_range.attr,
> + &stp_policy_node_attr_channels.attr,
> + NULL,
> +};
> +
> +static struct config_item_type stp_policy_type;
> +static struct config_item_type stp_policy_node_type;
> +
> +static struct config_group *
> +stp_policy_node_make(struct config_group *group, const char *name)
> +{
> + struct stp_policy_node *policy_node, *parent_node;
> + struct stp_policy *policy;
> +
> + if (group->cg_item.ci_type == &stp_policy_type) {
> + policy = container_of(group, struct stp_policy, group);
> + } else {
> + parent_node = container_of(group, struct stp_policy_node,
> + group);
> + policy = parent_node->policy;
> + }
> +
> + if (!policy->stm)
> + return ERR_PTR(-ENODEV);
> +
> + policy_node = kzalloc(sizeof(struct stp_policy_node), GFP_KERNEL);
> + if (!policy_node)
> + return ERR_PTR(-ENOMEM);
> +
> + config_group_init_type_name(&policy_node->group, name,
> + &stp_policy_node_type);
> +
> + policy_node->policy = policy;
> + policy_node->stm = policy->stm;
> +
> + /* default values for the attributes */
> + policy_node->first_master = policy->stm->data->sw_start;
> + policy_node->last_master = policy->stm->data->sw_end;
> + policy_node->first_channel = 0;
> + policy_node->last_channel = policy->stm->data->sw_nchannels - 1;
> +
> + return &policy_node->group;
> +}
> +
> +static void
> +stp_policy_node_drop(struct config_group *group, struct config_item *item)
> +{
> + config_item_put(item);
> +}
> +
> +static struct configfs_group_operations stp_policy_node_group_ops = {
> + .make_group = stp_policy_node_make,
> + .drop_item = stp_policy_node_drop,
> +};
> +
> +static struct config_item_type stp_policy_node_type = {
> + .ct_item_ops = &stp_policy_node_item_ops,
> + .ct_group_ops = &stp_policy_node_group_ops,
> + .ct_attrs = stp_policy_node_attrs,
> + .ct_owner = THIS_MODULE,
> +};
> +
> +/*
> + * Root group: policies.
> + */
> +static struct configfs_attribute stp_policy_attr_device = {
> + .ca_owner = THIS_MODULE,
> + .ca_name = "device",
> + .ca_mode = S_IRUGO | S_IWUSR,
> +};
> +
> +static struct configfs_attribute *stp_policy_attrs[] = {
> + &stp_policy_attr_device,
> + NULL,
> +};
> +
> +static ssize_t stp_policy_attr_show(struct config_item *item,
> + struct configfs_attribute *attr,
> + char *page)
> +{
> + struct stp_policy *policy = to_stp_policy(item);
> +
> + return sprintf(page, "%s\n",
> + (policy && policy->stm) ?
> + policy->stm->data->name :
> + "<none>");
> +}
> +
> +static ssize_t stp_policy_attr_store(struct config_item *item,
> + struct configfs_attribute *attr,
> + const char *page, size_t len)
> +{
> + struct stp_policy *policy = to_stp_policy(item);
> + ssize_t count = -EINVAL;
> + struct device *dev;
> +
> + dev = stm_find_device(page, len);
> + if (dev) {
> + count = len;
> + if (policy->stm)
> + put_device(policy->stm->dev);
> +
> + policy->stm = dev_get_drvdata(dev);
> +
> + mutex_lock(&policy->stm->policy_mutex);
> + policy->stm->policy = policy;
> + mutex_unlock(&policy->stm->policy_mutex);
> + }
> +
> + return count;
> +}
> +
> +void stp_policy_unbind(struct stp_policy *policy)
> +{
> + put_device(policy->stm->dev);
> +
> + mutex_lock(&policy->stm->policy_mutex);
> + policy->stm->policy = NULL;
> + mutex_unlock(&policy->stm->policy_mutex);
> +
> + policy->stm = NULL;
> +}
> +
> +static void stp_policy_release(struct config_item *item)
> +{
> + struct stp_policy *policy = to_stp_policy(item);
> +
> + stp_policy_unbind(policy);
> + kfree(policy);
> +}
> +
> +static struct configfs_item_operations stp_policy_item_ops = {
> + .release = stp_policy_release,
> + .show_attribute = stp_policy_attr_show,
> + .store_attribute = stp_policy_attr_store,
> +};
> +
> +static struct configfs_group_operations stp_policy_group_ops = {
> + .make_group = stp_policy_node_make,
> +};
> +
> +static struct config_item_type stp_policy_type = {
> + .ct_item_ops = &stp_policy_item_ops,
> + .ct_group_ops = &stp_policy_group_ops,
> + .ct_attrs = stp_policy_attrs,
> + .ct_owner = THIS_MODULE,
> +};
> +
> +static struct config_group *
> +stp_policies_make(struct config_group *group, const char *name)
> +{
> + struct stp_policy *policy;
> +
> + policy = kzalloc(sizeof(*policy), GFP_KERNEL);
> + if (!policy)
> + return ERR_PTR(-ENOMEM);
> +
> + config_group_init_type_name(&policy->group, name,
> + &stp_policy_type);
> + policy->stm = NULL;
> +
> + return &policy->group;
> +}
> +
> +static struct configfs_group_operations stp_policies_group_ops = {
> + .make_group = stp_policies_make,
> +};
> +
> +static struct config_item_type stp_policies_type = {
> + .ct_group_ops = &stp_policies_group_ops,
> + .ct_owner = THIS_MODULE,
> +};
> +
> +static struct configfs_subsystem stp_policy_subsys = {
> + .su_group = {
> + .cg_item = {
> + .ci_namebuf = "stp-policy",
> + .ci_type = &stp_policies_type,
> + },
> + },
> +};
> +
> +/*
> + * Lock the policy mutex from the outside
> + */
> +static struct stp_policy_node *
> +__stp_policy_node_lookup(struct stp_policy *policy, char *s)
> +{
> + struct stp_policy_node *policy_node, *ret;
> + struct list_head *head = &policy->group.cg_children;
> + struct config_item *item;
> + char *start, *end = s;
> +
> + if (list_empty(head))
> + return NULL;
> +
> + /* return the first entry if everything else fails */
> + item = list_entry(head->next, struct config_item, ci_entry);
> + ret = to_stp_policy_node(item);
> +
> +next:
> + for (;;) {
> + start = strsep(&end, "/");
> + if (!start)
> + break;
> +
> + if (!*start)
> + continue;
> +
> + list_for_each_entry(item, head, ci_entry) {
> + policy_node = to_stp_policy_node(item);
> +
> + if (!strcmp(start,
> + policy_node->group.cg_item.ci_name)) {
> + ret = policy_node;
> +
> + if (!end)
> + goto out;
> +
> + head = &policy_node->group.cg_children;
> + goto next;
> + }
> + }
> + break;
> + }
> +
> +out:
> + return ret;
> +}
> +
> +struct stp_policy_node *
> +stp_policy_node_lookup(struct stp_policy *policy, char *s)
> +{
> + struct stp_policy_node *policy_node;
> +
> + mutex_lock(&stp_policy_subsys.su_mutex);
> + policy_node = __stp_policy_node_lookup(policy, s);
> + mutex_unlock(&stp_policy_subsys.su_mutex);
> +
> + return policy_node;
> +}
> +
> +int __init stp_configfs_init(void)
> +{
> + int err;
> +
> + config_group_init(&stp_policy_subsys.su_group);
> + mutex_init(&stp_policy_subsys.su_mutex);
> + err = configfs_register_subsystem(&stp_policy_subsys);
> +
> + return err;
> +}
> +
> +void __exit stp_configfs_exit(void)
> +{
> + configfs_unregister_subsystem(&stp_policy_subsys);
> +}
> diff --git a/drivers/hwtracing/stm/stm.h b/drivers/hwtracing/stm/stm.h
> new file mode 100644
> index 0000000000..4d088a1400
> --- /dev/null
> +++ b/drivers/hwtracing/stm/stm.h
> @@ -0,0 +1,79 @@
> +/*
> + * System Trace Module (STM) infrastructure
> + * Copyright (c) 2014, Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * STM class implements generic infrastructure for System Trace Module devices
> + * as defined in MIPI STPv2 specification.
> + */
> +
> +#ifndef _CLASS_STM_H_
> +#define _CLASS_STM_H_
> +
> +struct stp_policy;
> +struct stp_policy_node;
> +
> +struct stp_policy_node *
> +stp_policy_node_lookup(struct stp_policy *policy, char *s);
> +void stp_policy_unbind(struct stp_policy *policy);
> +
> +void stp_policy_node_get_ranges(struct stp_policy_node *policy_node,
> + unsigned int *mstart, unsigned int *mend,
> + unsigned int *cstart, unsigned int *cend);
> +int stp_configfs_init(void);
> +void stp_configfs_exit(void);
> +
> +struct stp_master {
> + unsigned int nr_free;
> + unsigned long chan_map[0];
> +};
> +
> +struct stm_device {
> + struct device *dev;
> + struct module *owner;
> + struct stp_policy *policy;
> + struct mutex policy_mutex;
> + int major;
> + unsigned int sw_nmasters;
> + struct stm_data *data;
> + spinlock_t link_lock;
> + struct list_head link_list;
> + /* master allocation */
> + spinlock_t mc_lock;
> + struct stp_master *masters[0];
> +};
> +
> +struct stm_output {
> + unsigned int master;
> + unsigned int channel;
> + unsigned int nr_chans;
> +};
> +
> +struct stm_file {
> + struct stm_device *stm;
> + struct stp_policy_node *policy_node;
> + struct stm_output output;
> +};
> +
> +struct device *stm_find_device(const char *name, size_t len);
> +
> +struct stm_source_device {
> + struct device *dev;
> + struct stm_source_data *data;
> + spinlock_t link_lock;
> + struct stm_device *link;
> + struct list_head link_entry;
> + /* one output per stm_source device */
> + struct stp_policy_node *policy_node;
> + struct stm_output output;
> +};
> +
> +#endif /* _CLASS_STM_H_ */
> diff --git a/include/linux/stm.h b/include/linux/stm.h
> new file mode 100644
> index 0000000000..976c94d8f1
> --- /dev/null
> +++ b/include/linux/stm.h
> @@ -0,0 +1,102 @@
> +/*
> + * System Trace Module (STM) infrastructure apis
> + * Copyright (C) 2014 Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + */
> +
> +#ifndef _STM_H_
> +#define _STM_H_
> +
> +#include <linux/device.h>
> +
> +struct stp_policy;
> +
> +struct stm_device;
> +
> +/**
> + * struct stm_data - STM device description and callbacks
> + * @name: device name
> + * @stm: internal structure, only used by stm class code
> + * @sw_start: first STP master available to software
> + * @sw_end: last STP master available to software
> + * @sw_nchannels: number of STP channels per master
> + * @sw_mmiosz: size of one channel's IO space, for mmap, optional
> + * @write: write callback
> + * @mmio_addr: mmap callback, optional
> + * @link: called when a new stm_source gets linked to us, optional
> + * @unlink: likewise for unlinking, again optional
> + * @ioctl: ioctl callback for device-specific commands
> + *
> + * Fill out this structure before calling stm_register_device() to create
> + * an STM device and stm_unregister_device() to destroy it. It will also be
> + * passed back to @write(), @mmio_addr(), @link(), @unlink() and @ioctl()
> + * callbacks.
> + *
> + * Normally, an STM device will have a range of masters available to software
> + * and the rest being statically assigned to various hardware trace sources.
> + * The former is defined by the the range [@sw_start..@sw_end] of the device
> + * description. That is, the lowest master that can be allocated to software
> + * writers is @sw_start and data from this writer will appear is @sw_start
> + * master in the STP stream.
> + */
> +struct stm_data {
> + const char *name;
> + struct stm_device *stm;
> + unsigned int sw_start;
> + unsigned int sw_end;
> + unsigned int sw_nchannels;
> + unsigned int sw_mmiosz;
> + ssize_t (*write)(struct stm_data *, unsigned int,
> + unsigned int, const char *, size_t);
> + phys_addr_t (*mmio_addr)(struct stm_data *, unsigned int,
> + unsigned int, unsigned int);
> + void (*link)(struct stm_data *, unsigned int,
> + unsigned int);
> + void (*unlink)(struct stm_data *, unsigned int,
> + unsigned int);
> + long (*ioctl)(struct stm_data *, unsigned int,
> + unsigned long);
> +};
> +
> +int stm_register_device(struct device *parent, struct stm_data *stm_data,
> + struct module *owner);
> +void stm_unregister_device(struct stm_data *stm_data);
> +
> +struct stm_source_device;
> +
> +/**
> + * struct stm_source_data - STM source device description and callbacks
> + * @name: device name, will be used for policy lookup
> + * @src: internal structure, only used by stm class code
> + * @nr_chans: number of channels to allocate
> + * @link: called when this source gets linked to an STM device
> + * @unlink: called when this source is about to get unlinked from its STM
> + *
> + * Fill in this structure before calling stm_source_register_device() to
> + * register a source device. Also pass it to unregister and write calls.
> + */
> +struct stm_source_data {
> + const char *name;
> + struct stm_source_device *src;
> + unsigned int percpu;
> + unsigned int nr_chans;
> + int (*link)(struct stm_source_data *data);
> + void (*unlink)(struct stm_source_data *data);
> +};
> +
> +int stm_source_register_device(struct device *parent,
> + struct stm_source_data *data);
> +void stm_source_unregister_device(struct stm_source_data *data);
> +
> +int stm_source_write(struct stm_source_data *data, unsigned int chan,
> + const char *buf, size_t count);
> +
> +#endif /* _STM_H_ */
> diff --git a/include/uapi/linux/stm.h b/include/uapi/linux/stm.h
> new file mode 100644
> index 0000000000..042b58b53b
> --- /dev/null
> +++ b/include/uapi/linux/stm.h
> @@ -0,0 +1,47 @@
> +/*
> + * System Trace Module (STM) userspace interfaces
> + * Copyright (c) 2014, Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * STM class implements generic infrastructure for System Trace Module devices
> + * as defined in MIPI STPv2 specification.
> + */
> +
> +#ifndef _UAPI_LINUX_STM_H
> +#define _UAPI_LINUX_STM_H
> +
> +/**
> + * struct stp_policy_id - identification for the STP policy
> + * @size: size of the structure including real id[] length
> + * @master: assigned master
> + * @channel: first assigned channel
> + * @width: number of requested channels
> + * @id: identification string
> + *
> + * User must calculate the total size of the structure and put it into
> + * @size field, fill out the @id and desired @width. In return, kernel
> + * fills out @master, @channel and @width.
> + */
> +struct stp_policy_id {
> + __u32 size;
> + __u16 master;
> + __u16 channel;
> + __u16 width;
> + /* padding */
> + __u16 __reserved_0;
> + __u32 __reserved_1;
> + char id[0];
> +};
> +
> +#define STP_POLICY_ID_SET _IOWR('%', 0, struct stp_policy_id)
> +#define STP_POLICY_ID_GET _IOR('%', 1, struct stp_policy_id)
> +
> +#endif /* _UAPI_LINUX_STM_H */
> --
> 2.1.4
>
^ permalink raw reply
* Re: [RFC] capabilities: Ambient capabilities
From: Andy Lutomirski @ 2015-04-24 22:55 UTC (permalink / raw)
To: Serge E. Hallyn
Cc: Jarkko Sakkinen, Ted Ts'o, Andrew G. Morgan, Andrew Morton,
Serge Hallyn, Michael Kerrisk, Mimi Zohar, Linux API,
Austin S Hemmelgarn, linux-security-module, Aaron Jones,
Christoph Lameter, LKML, Serge Hallyn, Markku Savela, Kees Cook,
Jonathan Corbet
In-Reply-To: <20150424211511.GB28613-7LNsyQBKDXoIagZqoN9o3w@public.gmane.org>
On Apr 24, 2015 2:15 PM, "Serge E. Hallyn" <serge-A9i7LUbDfNHQT0dZR+AlfA@public.gmane.org> wrote:
>
> On Fri, Apr 24, 2015 at 01:18:44PM -0700, Andy Lutomirski wrote:
> > On Fri, Apr 24, 2015 at 1:13 PM, Christoph Lameter <cl-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org> wrote:
> > > On Fri, 24 Apr 2015, Andy Lutomirski wrote:
> > >
> > >> That's sort of what my patch does -- you need CAP_SETPCAP to switch
> > >> the securebit.
> > >>
> > >> But Christoph's patch required it to add caps to the ambient set, right?
> > >
> > > Yes but you seem to be just adding one additional step without too much of
> > > a benefit because you still need CAP_SETPCAP.
> > >
> >
> > No, because I set the default to on :)
>
> Right - I definately prefer
>
> . default off
> . CAP_SETPCAP required to turn it on (for self and children)
> . once on, anyone can copy bits from (whatever we decided) to pA.
>
Why default off? If there's some weird reason that switching it on
could cause a security problem, then I'd agree, but I haven't spotted
a reason yet.
--Andy
^ permalink raw reply
* Re: [RFC] capabilities: Ambient capabilities
From: Serge Hallyn @ 2015-04-25 2:45 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Serge E. Hallyn, Jarkko Sakkinen, Ted Ts'o, Andrew G. Morgan,
Andrew Morton, Michael Kerrisk, Mimi Zohar, Linux API,
Austin S Hemmelgarn, linux-security-module, Aaron Jones,
Christoph Lameter, LKML, Serge Hallyn, Markku Savela, Kees Cook,
Jonathan Corbet
In-Reply-To: <CALCETrUdNp18ZeOC8pRYn_YPUp8nFyH7aS+dFoBf34XNmER-nA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Quoting Andy Lutomirski (luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org):
> On Apr 24, 2015 2:15 PM, "Serge E. Hallyn" <serge-A9i7LUbDfNHQT0dZR+AlfA@public.gmane.org> wrote:
> >
> > On Fri, Apr 24, 2015 at 01:18:44PM -0700, Andy Lutomirski wrote:
> > > On Fri, Apr 24, 2015 at 1:13 PM, Christoph Lameter <cl-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org> wrote:
> > > > On Fri, 24 Apr 2015, Andy Lutomirski wrote:
> > > >
> > > >> That's sort of what my patch does -- you need CAP_SETPCAP to switch
> > > >> the securebit.
> > > >>
> > > >> But Christoph's patch required it to add caps to the ambient set, right?
> > > >
> > > > Yes but you seem to be just adding one additional step without too much of
> > > > a benefit because you still need CAP_SETPCAP.
> > > >
> > >
> > > No, because I set the default to on :)
> >
> > Right - I definately prefer
> >
> > . default off
> > . CAP_SETPCAP required to turn it on (for self and children)
> > . once on, anyone can copy bits from (whatever we decided) to pA.
> >
>
> Why default off? If there's some weird reason that switching it on
> could cause a security problem, then I'd agree, but I haven't spotted
> a reason yet.
Cause it's less scary?
I'll just wait for the new patchset :)
^ permalink raw reply
* Re: [PATCH] of: Move OF flags to be visible even when !CONFIG_OF
From: Wolfram Sang @ 2015-04-26 12:45 UTC (permalink / raw)
To: Pantelis Antoniou
Cc: Rob Herring, Grant Likely, Matt Porter, Koen Kooi, Guenter Roeck,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, Pantelis Antoniou
In-Reply-To: <1429868516-19519-1-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 499 bytes --]
On Fri, Apr 24, 2015 at 12:41:56PM +0300, Pantelis Antoniou wrote:
> We need those to be visible even when compiling with CONFIG_OF
> disabled, since even the empty of_node_*_flag() method use the
> flag.
>
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
Acked-by: Wolfram Sang <wsa+renesas-jBu1N2QxHDJrcw3mvpCnnVaTQe2KTcn/@public.gmane.org>
You should have mentioned that this is needed to get a bugfix for
OF_DYNAMIC in i2c upstream!
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [v14 3/4] ext4: adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR interface support
From: Dave Chinner @ 2015-04-26 23:20 UTC (permalink / raw)
To: Li Xi
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-ext4-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, tytso-3s7WtUTddSA,
adilger-m1MBpc4rdrD3fQ9qLvQP4Q, jack-AlSwsSmVLrQ,
viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, hch-wEGCiKHe2LqWVfeAwA7xHQ,
dmonakhov-GEFAQzZX7r8dnm+yROfE0A
In-Reply-To: <1429728997-21464-4-git-send-email-lixi-LfVdkaOWEx8@public.gmane.org>
On Thu, Apr 23, 2015 at 03:56:36AM +0900, Li Xi wrote:
> This patch adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR ioctl interface
> support for ext4. The interface is kept consistent with
> XFS_IOC_FSGETXATTR/XFS_IOC_FSGETXATTR.
Have you run this patchthrough XFS testing to make sure everything
sill works?
Cheers,
Dave.
--
Dave Chinner
david-FqsqvQoI3Ljby3iVrkZq2A@public.gmane.org
^ permalink raw reply
* Re: [PATCH v6 1/8] virtio: introduce virtio_is_little_endian() helper
From: Cornelia Huck @ 2015-04-27 9:07 UTC (permalink / raw)
To: Greg Kurz
Cc: Thomas Huth, kvm, Michael S. Tsirkin, linux-api, linux-kernel,
virtualization
In-Reply-To: <20150424122423.19156.34555.stgit@bahia.local>
On Fri, 24 Apr 2015 14:24:27 +0200
Greg Kurz <gkurz@linux.vnet.ibm.com> wrote:
> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> ---
> include/linux/virtio_config.h | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
> index ca3ed78..bd1a582 100644
> --- a/include/linux/virtio_config.h
> +++ b/include/linux/virtio_config.h
> @@ -205,35 +205,40 @@ int virtqueue_set_affinity(struct virtqueue *vq, int cpu)
> return 0;
> }
>
> +static inline bool virtio_is_little_endian(struct virtio_device *vdev)
> +{
> + return virtio_has_feature(vdev, VIRTIO_F_VERSION_1);
> +}
> +
While this reads a bit funny in this patch, it will end up correctly at
the end of the series, so
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
^ permalink raw reply
* Re: [PATCH v6 2/8] tun: add tun_is_little_endian() helper
From: Cornelia Huck @ 2015-04-27 9:08 UTC (permalink / raw)
To: Greg Kurz
Cc: Thomas Huth, kvm, Michael S. Tsirkin, linux-api, linux-kernel,
virtualization
In-Reply-To: <20150424122435.19156.18985.stgit@bahia.local>
On Fri, 24 Apr 2015 14:24:38 +0200
Greg Kurz <gkurz@linux.vnet.ibm.com> wrote:
> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> ---
> drivers/net/tun.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
^ permalink raw reply
* Re: [PATCH v6 3/8] macvtap: introduce macvtap_is_little_endian() helper
From: Cornelia Huck @ 2015-04-27 9:08 UTC (permalink / raw)
To: Greg Kurz
Cc: Thomas Huth, kvm, Michael S. Tsirkin, linux-api, linux-kernel,
virtualization
In-Reply-To: <20150424122446.19156.93123.stgit@bahia.local>
On Fri, 24 Apr 2015 14:24:48 +0200
Greg Kurz <gkurz@linux.vnet.ibm.com> wrote:
> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> ---
> drivers/net/macvtap.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
^ permalink raw reply
* Re: [PATCH v6 4/8] vringh: introduce vringh_is_little_endian() helper
From: Cornelia Huck @ 2015-04-27 9:09 UTC (permalink / raw)
To: Greg Kurz
Cc: Thomas Huth, kvm, Michael S. Tsirkin, linux-api, linux-kernel,
virtualization
In-Reply-To: <20150424122456.19156.56558.stgit@bahia.local>
On Fri, 24 Apr 2015 14:24:58 +0200
Greg Kurz <gkurz@linux.vnet.ibm.com> wrote:
> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> ---
> include/linux/vringh.h | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
^ permalink raw reply
* Re: [PATCH v6 5/8] vhost: introduce vhost_is_little_endian() helper
From: Cornelia Huck @ 2015-04-27 9:09 UTC (permalink / raw)
To: Greg Kurz
Cc: Thomas Huth, kvm, Michael S. Tsirkin, linux-api, linux-kernel,
virtualization
In-Reply-To: <20150424122507.19156.55673.stgit@bahia.local>
On Fri, 24 Apr 2015 14:25:12 +0200
Greg Kurz <gkurz@linux.vnet.ibm.com> wrote:
> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> ---
> drivers/vhost/vhost.h | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
^ permalink raw reply
* Re: [PATCH v6 6/8] virtio: add explicit big-endian support to memory accessors
From: Cornelia Huck @ 2015-04-27 9:14 UTC (permalink / raw)
To: Greg Kurz
Cc: Rusty Russell, Michael S. Tsirkin, Thomas Huth,
kvm-u79uwXL29TY76Z2rM5mHXA, linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
In-Reply-To: <20150424122521.19156.65586.stgit-GiB8zCg7hOfDOqzlkpFKJg@public.gmane.org>
On Fri, 24 Apr 2015 14:26:24 +0200
Greg Kurz <gkurz-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:
> The current memory accessors logic is:
> - little endian if little_endian
> - native endian (i.e. no byteswap) if !little_endian
>
> If we want to fully support cross-endian vhost, we also need to be
> able to convert to big endian.
>
> Instead of changing the little_endian argument to some 3-value enum, this
> patch changes the logic to:
> - little endian if little_endian
> - big endian if !little_endian
>
> The native endian case is handled by all users with a trivial helper. This
> patch doesn't change any functionality, nor it does add overhead.
>
> Signed-off-by: Greg Kurz <gkurz-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> ---
>
> Changes since v5:
> - changed endian checking helpers as suggested by Thomas (use || and line
> breaker)
>
> drivers/net/macvtap.c | 3 ++-
> drivers/net/tun.c | 3 ++-
> drivers/vhost/vhost.h | 3 ++-
> include/linux/virtio_byteorder.h | 24 ++++++++++++++----------
> include/linux/virtio_config.h | 3 ++-
> include/linux/vringh.h | 3 ++-
> 6 files changed, 24 insertions(+), 15 deletions(-)
>
Reviewed-by: Cornelia Huck <cornelia.huck-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox