Security testing tree patch review for 2.6.26 - Kernel

This is a discussion on Security testing tree patch review for 2.6.26 - Kernel ; Please review the following security patches for 2.6.26, which have been undergoing testing in the "next" tree and affect multiple LSMs. The following changes since commit 4b119e21d0c66c22e8ca03df05d9de623d0eb50f: Linus Torvalds (1): Linux 2.6.25 are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git ...

+ Reply to Thread
Results 1 to 19 of 19

Thread: Security testing tree patch review for 2.6.26

  1. Security testing tree patch review for 2.6.26


    Please review the following security patches for 2.6.26, which have
    been undergoing testing in the "next" tree and affect multiple LSMs.


    The following changes since commit 4b119e21d0c66c22e8ca03df05d9de623d0eb50f:
    Linus Torvalds (1):
    Linux 2.6.25

    are available in the git repository at:

    git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git for-linus

    Ahmed S. Darwish (10):
    LSM: Introduce inode_getsecid and ipc_getsecid hooks
    SELinux: setup new inode/ipc getsecid hooks
    Audit: use new LSM hooks instead of SELinux exports
    Netlink: Use generic LSM hook
    SELinux: remove redundant exports
    LSM/Audit: Introduce generic Audit LSM hooks
    Audit: internally use the new LSM audit hooks
    SELinux: use new audit hooks, remove redundant exports
    Audit: Final renamings and cleanup
    Security: Introduce security= boot parameter

    James Morris (2):
    Tell git about security/selinux/include/audit.h
    security: fix up documentation for security_module_enable

    Documentation/kernel-parameters.txt | 6 ++
    include/linux/audit.h | 29 ++++++++
    include/linux/security.h | 114 +++++++++++++++++++++++++++++-
    include/linux/selinux.h | 134 -----------------------------------
    kernel/audit.c | 24 +++----
    kernel/audit.h | 25 -------
    kernel/auditfilter.c | 99 ++++++++++----------------
    kernel/auditsc.c | 74 ++++++++++---------
    net/netlink/af_netlink.c | 3 +-
    security/dummy.c | 51 +++++++++++++-
    security/security.c | 73 +++++++++++++++++++-
    security/selinux/exports.c | 42 -----------
    security/selinux/hooks.c | 34 ++++++++-
    security/selinux/include/audit.h | 65 +++++++++++++++++
    security/selinux/ss/services.c | 45 +++++++++---
    security/smack/smack.h | 2 +
    security/smack/smack_lsm.c | 7 ++-
    security/smack/smackfs.c | 11 +++-
    18 files changed, 503 insertions(+), 335 deletions(-)
    create mode 100644 security/selinux/include/audit.h
    --
    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/

  2. [PATCH 02/12] SELinux: setup new inode/ipc getsecid hooks

    From: Ahmed S. Darwish

    Setup the new inode_getsecid and ipc_getsecid() LSM hooks
    for SELinux.

    Signed-off-by: Casey Schaufler
    Signed-off-by: Ahmed S. Darwish
    Acked-by: James Morris
    Reviewed-by: Paul Moore
    ---
    security/selinux/hooks.c | 19 +++++++++++++++++--
    1 files changed, 17 insertions(+), 2 deletions(-)

    diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
    index d39b59c..65bf7f7 100644
    --- a/security/selinux/hooks.c
    +++ b/security/selinux/hooks.c
    @@ -2743,6 +2743,12 @@ static int selinux_inode_killpriv(struct dentry *dentry)
    return secondary_ops->inode_killpriv(dentry);
    }

    +static void selinux_inode_getsecid(const struct inode *inode, u32 *secid)
    +{
    + struct inode_security_struct *isec = inode->i_security;
    + *secid = isec->sid;
    +}
    +
    /* file security operations */

    static int selinux_revalidate_file_permission(struct file *file, int mask)
    @@ -3139,7 +3145,8 @@ static int selinux_task_getsid(struct task_struct *p)

    static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
    {
    - selinux_get_task_sid(p, secid);
    + struct task_security_struct *tsec = p->security;
    + *secid = tsec->sid;
    }

    static int selinux_task_setgroups(struct group_info *group_info)
    @@ -4109,7 +4116,7 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *
    goto out;

    if (sock && family == PF_UNIX)
    - selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid);
    + selinux_inode_getsecid(SOCK_INODE(sock), &peer_secid);
    else if (skb)
    selinux_skb_peerlbl_sid(skb, family, &peer_secid);

    @@ -4989,6 +4996,12 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
    return ipc_has_perm(ipcp, av);
    }

    +static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
    +{
    + struct ipc_security_struct *isec = ipcp->security;
    + *secid = isec->sid;
    +}
    +
    /* module stacking operations */
    static int selinux_register_security (const char *name, struct security_operations *ops)
    {
    @@ -5299,6 +5312,7 @@ static struct security_operations selinux_ops = {
    .inode_listsecurity = selinux_inode_listsecurity,
    .inode_need_killpriv = selinux_inode_need_killpriv,
    .inode_killpriv = selinux_inode_killpriv,
    + .inode_getsecid = selinux_inode_getsecid,

    .file_permission = selinux_file_permission,
    .file_alloc_security = selinux_file_alloc_security,
    @@ -5339,6 +5353,7 @@ static struct security_operations selinux_ops = {
    .task_to_inode = selinux_task_to_inode,

    .ipc_permission = selinux_ipc_permission,
    + .ipc_getsecid = selinux_ipc_getsecid,

    .msg_msg_alloc_security = selinux_msg_msg_alloc_security,
    .msg_msg_free_security = selinux_msg_msg_free_security,
    --
    1.5.4.2

    --
    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/

  3. [PATCH 06/12] LSM/Audit: Introduce generic Audit LSM hooks

    From: Ahmed S. Darwish

    Introduce a generic Audit interface for security modules
    by adding the following new LSM hooks:

    audit_rule_init(field, op, rulestr, lsmrule)
    audit_rule_known(krule)
    audit_rule_match(secid, field, op, rule, actx)
    audit_rule_free(rule)

    Those hooks are only available if CONFIG_AUDIT is enabled.

    Signed-off-by: Casey Schaufler
    Signed-off-by: Ahmed S. Darwish
    Acked-by: James Morris
    Reviewed-by: Paul Moore
    ---
    include/linux/security.h | 72 ++++++++++++++++++++++++++++++++++++++++++++++
    security/dummy.c | 31 +++++++++++++++++++-
    security/security.c | 25 ++++++++++++++++
    3 files changed, 127 insertions(+), 1 deletions(-)

    diff --git a/include/linux/security.h b/include/linux/security.h
    index 45717d9..697f228 100644
    --- a/include/linux/security.h
    +++ b/include/linux/security.h
    @@ -37,6 +37,7 @@
    extern unsigned securebits;

    struct ctl_table;
    +struct audit_krule;

    /*
    * These functions are in security/capability.c and are used
    @@ -1235,6 +1236,37 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
    * @secdata contains the security context.
    * @seclen contains the length of the security context.
    *
    + * Security hooks for Audit
    + *
    + * @audit_rule_init:
    + * Allocate and initialize an LSM audit rule structure.
    + * @field contains the required Audit action. Fields flags are defined in include/linux/audit.h
    + * @op contains the operator the rule uses.
    + * @rulestr contains the context where the rule will be applied to.
    + * @lsmrule contains a pointer to receive the result.
    + * Return 0 if @lsmrule has been successfully set,
    + * -EINVAL in case of an invalid rule.
    + *
    + * @audit_rule_known:
    + * Specifies whether given @rule contains any fields related to current LSM.
    + * @rule contains the audit rule of interest.
    + * Return 1 in case of relation found, 0 otherwise.
    + *
    + * @audit_rule_match:
    + * Determine if given @secid matches a rule previously approved
    + * by @audit_rule_known.
    + * @secid contains the security id in question.
    + * @field contains the field which relates to current LSM.
    + * @op contains the operator that will be used for matching.
    + * @rule points to the audit rule that will be checked against.
    + * @actx points to the audit context associated with the check.
    + * Return 1 if secid matches the rule, 0 if it does not, -ERRNO on failure.
    + *
    + * @audit_rule_free:
    + * Deallocate the LSM audit rule structure previously allocated by
    + * audit_rule_init.
    + * @rule contains the allocated rule
    + *
    * This is the main security structure.
    */
    struct security_operations {
    @@ -1494,6 +1526,13 @@ struct security_operations {

    #endif /* CONFIG_KEYS */

    +#ifdef CONFIG_AUDIT
    + int (*audit_rule_init)(u32 field, u32 op, char *rulestr, void **lsmrule);
    + int (*audit_rule_known)(struct audit_krule *krule);
    + int (*audit_rule_match)(u32 secid, u32 field, u32 op, void *lsmrule,
    + struct audit_context *actx);
    + void (*audit_rule_free)(void *lsmrule);
    +#endif /* CONFIG_AUDIT */
    };

    /* prototypes */
    @@ -2700,5 +2739,38 @@ static inline int security_key_permission(key_ref_t key_ref,
    #endif
    #endif /* CONFIG_KEYS */

    +#ifdef CONFIG_AUDIT
    +#ifdef CONFIG_SECURITY
    +int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule);
    +int security_audit_rule_known(struct audit_krule *krule);
    +int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule,
    + struct audit_context *actx);
    +void security_audit_rule_free(void *lsmrule);
    +
    +#else
    +
    +static inline int security_audit_rule_init(u32 field, u32 op, char *rulestr,
    + void **lsmrule)
    +{
    + return 0;
    +}
    +
    +static inline int security_audit_rule_known(struct audit_krule *krule)
    +{
    + return 0;
    +}
    +
    +static inline int security_audit_rule_match(u32 secid, u32 field, u32 op,
    + void *lsmrule, struct audit_context *actx)
    +{
    + return 0;
    +}
    +
    +static inline void security_audit_rule_free(void *lsmrule)
    +{ }
    +
    +#endif /* CONFIG_SECURITY */
    +#endif /* CONFIG_AUDIT */
    +
    #endif /* ! __LINUX_SECURITY_H */

    diff --git a/security/dummy.c b/security/dummy.c
    index fb2e942..1ac9f8e 100644
    --- a/security/dummy.c
    +++ b/security/dummy.c
    @@ -993,6 +993,30 @@ static inline int dummy_key_permission(key_ref_t key_ref,
    }
    #endif /* CONFIG_KEYS */

    +#ifdef CONFIG_AUDIT
    +static inline int dummy_audit_rule_init(u32 field, u32 op, char *rulestr,
    + void **lsmrule)
    +{
    + return 0;
    +}
    +
    +static inline int dummy_audit_rule_known(struct audit_krule *krule)
    +{
    + return 0;
    +}
    +
    +static inline int dummy_audit_rule_match(u32 secid, u32 field, u32 op,
    + void *lsmrule,
    + struct audit_context *actx)
    +{
    + return 0;
    +}
    +
    +static inline void dummy_audit_rule_free(void *lsmrule)
    +{ }
    +
    +#endif /* CONFIG_AUDIT */
    +
    struct security_operations dummy_security_ops;

    #define set_to_dummy_if_null(ops, function) \
    @@ -1182,6 +1206,11 @@ void security_fixup_ops (struct security_operations *ops)
    set_to_dummy_if_null(ops, key_free);
    set_to_dummy_if_null(ops, key_permission);
    #endif /* CONFIG_KEYS */
    -
    +#ifdef CONFIG_AUDIT
    + set_to_dummy_if_null(ops, audit_rule_init);
    + set_to_dummy_if_null(ops, audit_rule_known);
    + set_to_dummy_if_null(ops, audit_rule_match);
    + set_to_dummy_if_null(ops, audit_rule_free);
    +#endif
    }

    diff --git a/security/security.c b/security/security.c
    index 33e59a7..bf189d2 100644
    --- a/security/security.c
    +++ b/security/security.c
    @@ -1120,3 +1120,28 @@ int security_key_permission(key_ref_t key_ref,
    }

    #endif /* CONFIG_KEYS */
    +
    +#ifdef CONFIG_AUDIT
    +
    +int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule)
    +{
    + return security_ops->audit_rule_init(field, op, rulestr, lsmrule);
    +}
    +
    +int security_audit_rule_known(struct audit_krule *krule)
    +{
    + return security_ops->audit_rule_known(krule);
    +}
    +
    +void security_audit_rule_free(void *lsmrule)
    +{
    + security_ops->audit_rule_free(lsmrule);
    +}
    +
    +int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule,
    + struct audit_context *actx)
    +{
    + return security_ops->audit_rule_match(secid, field, op, lsmrule, actx);
    +}
    +
    +#endif /* CONFIG_AUDIT */
    --
    1.5.4.2

    --
    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/

  4. [PATCH 03/12] Audit: use new LSM hooks instead of SELinux exports

    From: Ahmed S. Darwish

    Stop using the following exported SELinux interfaces:
    selinux_get_inode_sid(inode, sid)
    selinux_get_ipc_sid(ipcp, sid)
    selinux_get_task_sid(tsk, sid)
    selinux_sid_to_string(sid, ctx, len)
    kfree(ctx)

    and use following generic LSM equivalents respectively:
    security_inode_getsecid(inode, secid)
    security_ipc_getsecid*(ipcp, secid)
    security_task_getsecid(tsk, secid)
    security_sid_to_secctx(sid, ctx, len)
    security_release_secctx(ctx, len)

    Call security_release_secctx only if security_secid_to_secctx
    succeeded.

    Signed-off-by: Casey Schaufler
    Signed-off-by: Ahmed S. Darwish
    Acked-by: James Morris
    Reviewed-by: Paul Moore
    ---
    kernel/audit.c | 17 ++++++++-------
    kernel/auditfilter.c | 8 ++++--
    kernel/auditsc.c | 55 ++++++++++++++++++++++++++-----------------------
    3 files changed, 43 insertions(+), 37 deletions(-)

    diff --git a/kernel/audit.c b/kernel/audit.c
    index b782b04..784a48e 100644
    --- a/kernel/audit.c
    +++ b/kernel/audit.c
    @@ -265,13 +265,13 @@ static int audit_log_config_change(char *function_name, int new, int old,
    char *ctx = NULL;
    u32 len;

    - rc = selinux_sid_to_string(sid, &ctx, &len);
    + rc = security_secid_to_secctx(sid, &ctx, &len);
    if (rc) {
    audit_log_format(ab, " sid=%u", sid);
    allow_changes = 0; /* Something weird, deny request */
    } else {
    audit_log_format(ab, " subj=%s", ctx);
    - kfree(ctx);
    + security_release_secctx(ctx, len);
    }
    }
    audit_log_format(ab, " res=%d", allow_changes);
    @@ -550,12 +550,13 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type,
    audit_log_format(*ab, "user pid=%d uid=%u auid=%u",
    pid, uid, auid);
    if (sid) {
    - rc = selinux_sid_to_string(sid, &ctx, &len);
    + rc = security_secid_to_secctx(sid, &ctx, &len);
    if (rc)
    audit_log_format(*ab, " ssid=%u", sid);
    - else
    + else {
    audit_log_format(*ab, " subj=%s", ctx);
    - kfree(ctx);
    + security_release_secctx(ctx, len);
    + }
    }

    return rc;
    @@ -758,18 +759,18 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
    break;
    }
    case AUDIT_SIGNAL_INFO:
    - err = selinux_sid_to_string(audit_sig_sid, &ctx, &len);
    + err = security_secid_to_secctx(audit_sig_sid, &ctx, &len);
    if (err)
    return err;
    sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL);
    if (!sig_data) {
    - kfree(ctx);
    + security_release_secctx(ctx, len);
    return -ENOMEM;
    }
    sig_data->uid = audit_sig_uid;
    sig_data->pid = audit_sig_pid;
    memcpy(sig_data->ctx, ctx, len);
    - kfree(ctx);
    + security_release_secctx(ctx, len);
    audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO,
    0, 0, sig_data, sizeof(*sig_data) + len);
    kfree(sig_data);
    diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
    index 2f2914b..35e58a1 100644
    --- a/kernel/auditfilter.c
    +++ b/kernel/auditfilter.c
    @@ -28,6 +28,7 @@
    #include
    #include
    #include
    +#include
    #include
    #include "audit.h"

    @@ -1515,11 +1516,12 @@ static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action,
    if (sid) {
    char *ctx = NULL;
    u32 len;
    - if (selinux_sid_to_string(sid, &ctx, &len))
    + if (security_secid_to_secctx(sid, &ctx, &len))
    audit_log_format(ab, " ssid=%u", sid);
    - else
    + else {
    audit_log_format(ab, " subj=%s", ctx);
    - kfree(ctx);
    + security_release_secctx(ctx, len);
    + }
    }
    audit_log_format(ab, " op=%s rule key=", action);
    if (rule->filterkey)
    diff --git a/kernel/auditsc.c b/kernel/auditsc.c
    index 782262e..6a83c70 100644
    --- a/kernel/auditsc.c
    +++ b/kernel/auditsc.c
    @@ -530,7 +530,7 @@ static int audit_filter_rules(struct task_struct *tsk,
    logged upon error */
    if (f->se_rule) {
    if (need_sid) {
    - selinux_get_task_sid(tsk, &sid);
    + security_task_getsecid(tsk, &sid);
    need_sid = 0;
    }
    result = selinux_audit_rule_match(sid, f->type,
    @@ -885,11 +885,11 @@ void audit_log_task_context(struct audit_buffer *ab)
    int error;
    u32 sid;

    - selinux_get_task_sid(current, &sid);
    + security_task_getsecid(current, &sid);
    if (!sid)
    return;

    - error = selinux_sid_to_string(sid, &ctx, &len);
    + error = security_secid_to_secctx(sid, &ctx, &len);
    if (error) {
    if (error != -EINVAL)
    goto error_path;
    @@ -897,7 +897,7 @@ void audit_log_task_context(struct audit_buffer *ab)
    }

    audit_log_format(ab, " subj=%s", ctx);
    - kfree(ctx);
    + security_release_secctx(ctx, len);
    return;

    error_path:
    @@ -941,7 +941,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
    u32 sid, char *comm)
    {
    struct audit_buffer *ab;
    - char *s = NULL;
    + char *ctx = NULL;
    u32 len;
    int rc = 0;

    @@ -951,15 +951,16 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,

    audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, auid,
    uid, sessionid);
    - if (selinux_sid_to_string(sid, &s, &len)) {
    + if (security_secid_to_secctx(sid, &ctx, &len)) {
    audit_log_format(ab, " obj=(none)");
    rc = 1;
    - } else
    - audit_log_format(ab, " obj=%s", s);
    + } else {
    + audit_log_format(ab, " obj=%s", ctx);
    + security_release_secctx(ctx, len);
    + }
    audit_log_format(ab, " ocomm=");
    audit_log_untrustedstring(ab, comm);
    audit_log_end(ab);
    - kfree(s);

    return rc;
    }
    @@ -1271,14 +1272,15 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
    if (axi->osid != 0) {
    char *ctx = NULL;
    u32 len;
    - if (selinux_sid_to_string(
    + if (security_secid_to_secctx(
    axi->osid, &ctx, &len)) {
    audit_log_format(ab, " osid=%u",
    axi->osid);
    call_panic = 1;
    - } else
    + } else {
    audit_log_format(ab, " obj=%s", ctx);
    - kfree(ctx);
    + security_release_secctx(ctx, len);
    + }
    }
    break; }

    @@ -1392,13 +1394,14 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
    if (n->osid != 0) {
    char *ctx = NULL;
    u32 len;
    - if (selinux_sid_to_string(
    + if (security_secid_to_secctx(
    n->osid, &ctx, &len)) {
    audit_log_format(ab, " osid=%u", n->osid);
    call_panic = 2;
    - } else
    + } else {
    audit_log_format(ab, " obj=%s", ctx);
    - kfree(ctx);
    + security_release_secctx(ctx, len);
    + }
    }

    audit_log_end(ab);
    @@ -1775,7 +1778,7 @@ static void audit_copy_inode(struct audit_names *name, const struct inode *inode
    name->uid = inode->i_uid;
    name->gid = inode->i_gid;
    name->rdev = inode->i_rdev;
    - selinux_get_inode_sid(inode, &name->osid);
    + security_inode_getsecid(inode, &name->osid);
    }

    /**
    @@ -2190,8 +2193,7 @@ int __audit_ipc_obj(struct kern_ipc_perm *ipcp)
    ax->uid = ipcp->uid;
    ax->gid = ipcp->gid;
    ax->mode = ipcp->mode;
    - selinux_get_ipc_sid(ipcp, &ax->osid);
    -
    + security_ipc_getsecid(ipcp, &ax->osid);
    ax->d.type = AUDIT_IPC;
    ax->d.next = context->aux;
    context->aux = (void *)ax;
    @@ -2343,7 +2345,7 @@ void __audit_ptrace(struct task_struct *t)
    context->target_auid = audit_get_loginuid(t);
    context->target_uid = t->uid;
    context->target_sessionid = audit_get_sessionid(t);
    - selinux_get_task_sid(t, &context->target_sid);
    + security_task_getsecid(t, &context->target_sid);
    memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
    }

    @@ -2371,7 +2373,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
    audit_sig_uid = tsk->loginuid;
    else
    audit_sig_uid = tsk->uid;
    - selinux_get_task_sid(tsk, &audit_sig_sid);
    + security_task_getsecid(tsk, &audit_sig_sid);
    }
    if (!audit_signals || audit_dummy_context())
    return 0;
    @@ -2384,7 +2386,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
    ctx->target_auid = audit_get_loginuid(t);
    ctx->target_uid = t->uid;
    ctx->target_sessionid = audit_get_sessionid(t);
    - selinux_get_task_sid(t, &ctx->target_sid);
    + security_task_getsecid(t, &ctx->target_sid);
    memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
    return 0;
    }
    @@ -2405,7 +2407,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
    axp->target_auid[axp->pid_count] = audit_get_loginuid(t);
    axp->target_uid[axp->pid_count] = t->uid;
    axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t);
    - selinux_get_task_sid(t, &axp->target_sid[axp->pid_count]);
    + security_task_getsecid(t, &axp->target_sid[axp->pid_count]);
    memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
    axp->pid_count++;

    @@ -2435,16 +2437,17 @@ void audit_core_dumps(long signr)
    ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
    audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u",
    auid, current->uid, current->gid, sessionid);
    - selinux_get_task_sid(current, &sid);
    + security_task_getsecid(current, &sid);
    if (sid) {
    char *ctx = NULL;
    u32 len;

    - if (selinux_sid_to_string(sid, &ctx, &len))
    + if (security_secid_to_secctx(sid, &ctx, &len))
    audit_log_format(ab, " ssid=%u", sid);
    - else
    + else {
    audit_log_format(ab, " subj=%s", ctx);
    - kfree(ctx);
    + security_release_secctx(ctx, len);
    + }
    }
    audit_log_format(ab, " pid=%d comm=", current->pid);
    audit_log_untrustedstring(ab, current->comm);
    --
    1.5.4.2

    --
    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/

  5. [PATCH 01/12] LSM: Introduce inode_getsecid and ipc_getsecid hooks

    From: Ahmed S. Darwish

    Introduce inode_getsecid(inode, secid) and ipc_getsecid(ipcp, secid)
    LSM hooks. These hooks will be used instead of similar exported
    SELinux interfaces.

    Let {inode,ipc,task}_getsecid hooks set the secid to 0 by default
    if CONFIG_SECURITY is not defined or if the hook is set to
    NULL (dummy). This is done to notify the caller that no valid
    secid exists.

    Signed-off-by: Casey Schaufler
    Signed-off-by: Ahmed S. Darwish
    Acked-by: James Morris
    Reviewed-by: Paul Moore
    ---
    include/linux/security.h | 30 +++++++++++++++++++++++++++++-
    security/dummy.c | 16 +++++++++++++++-
    security/security.c | 10 ++++++++++
    3 files changed, 54 insertions(+), 2 deletions(-)

    diff --git a/include/linux/security.h b/include/linux/security.h
    index c673dfd..45717d9 100644
    --- a/include/linux/security.h
    +++ b/include/linux/security.h
    @@ -468,6 +468,11 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
    * @dentry is the dentry being changed.
    * Return 0 on success. If error is returned, then the operation
    * causing setuid bit removal is failed.
    + * @inode_getsecid:
    + * Get the secid associated with the node.
    + * @inode contains a pointer to the inode.
    + * @secid contains a pointer to the location where result will be saved.
    + * In case of failure, @secid will be set to zero.
    *
    * Security hooks for file operations
    *
    @@ -636,6 +641,8 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
    * @task_getsecid:
    * Retrieve the security identifier of the process @p.
    * @p contains the task_struct for the process and place is into @secid.
    + * In case of failure, @secid will be set to zero.
    + *
    * @task_setgroups:
    * Check permission before setting the supplementary group set of the
    * current process.
    @@ -997,6 +1004,11 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
    * @ipcp contains the kernel IPC permission structure
    * @flag contains the desired (requested) permission set
    * Return 0 if permission is granted.
    + * @ipc_getsecid:
    + * Get the secid associated with the ipc object.
    + * @ipcp contains the kernel IPC permission structure.
    + * @secid contains a pointer to the location where result will be saved.
    + * In case of failure, @secid will be set to zero.
    *
    * Security hooks for individual messages held in System V IPC message queues
    * @msg_msg_alloc_security:
    @@ -1317,6 +1329,7 @@ struct security_operations {
    int (*inode_getsecurity)(const struct inode *inode, const char *name, void **buffer, bool alloc);
    int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags);
    int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size);
    + void (*inode_getsecid)(const struct inode *inode, u32 *secid);

    int (*file_permission) (struct file * file, int mask);
    int (*file_alloc_security) (struct file * file);
    @@ -1369,6 +1382,7 @@ struct security_operations {
    void (*task_to_inode)(struct task_struct *p, struct inode *inode);

    int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag);
    + void (*ipc_getsecid) (struct kern_ipc_perm *ipcp, u32 *secid);

    int (*msg_msg_alloc_security) (struct msg_msg * msg);
    void (*msg_msg_free_security) (struct msg_msg * msg);
    @@ -1578,6 +1592,7 @@ int security_inode_killpriv(struct dentry *dentry);
    int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc);
    int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags);
    int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size);
    +void security_inode_getsecid(const struct inode *inode, u32 *secid);
    int security_file_permission(struct file *file, int mask);
    int security_file_alloc(struct file *file);
    void security_file_free(struct file *file);
    @@ -1622,6 +1637,7 @@ int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
    void security_task_reparent_to_init(struct task_struct *p);
    void security_task_to_inode(struct task_struct *p, struct inode *inode);
    int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag);
    +void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid);
    int security_msg_msg_alloc(struct msg_msg *msg);
    void security_msg_msg_free(struct msg_msg *msg);
    int security_msg_queue_alloc(struct msg_queue *msq);
    @@ -2022,6 +2038,11 @@ static inline int security_inode_listsecurity(struct inode *inode, char *buffer,
    return 0;
    }

    +static inline void security_inode_getsecid(const struct inode *inode, u32 *secid)
    +{
    + *secid = 0;
    +}
    +
    static inline int security_file_permission (struct file *file, int mask)
    {
    return 0;
    @@ -2137,7 +2158,9 @@ static inline int security_task_getsid (struct task_struct *p)
    }

    static inline void security_task_getsecid (struct task_struct *p, u32 *secid)
    -{ }
    +{
    + *secid = 0;
    +}

    static inline int security_task_setgroups (struct group_info *group_info)
    {
    @@ -2216,6 +2239,11 @@ static inline int security_ipc_permission (struct kern_ipc_perm *ipcp,
    return 0;
    }

    +static inline void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
    +{
    + *secid = 0;
    +}
    +
    static inline int security_msg_msg_alloc (struct msg_msg * msg)
    {
    return 0;
    diff --git a/security/dummy.c b/security/dummy.c
    index 78d8f92..fb2e942 100644
    --- a/security/dummy.c
    +++ b/security/dummy.c
    @@ -424,6 +424,11 @@ static int dummy_inode_listsecurity(struct inode *inode, char *buffer, size_t bu
    return 0;
    }

    +static void dummy_inode_getsecid(const struct inode *inode, u32 *secid)
    +{
    + *secid = 0;
    +}
    +
    static int dummy_file_permission (struct file *file, int mask)
    {
    return 0;
    @@ -542,7 +547,9 @@ static int dummy_task_getsid (struct task_struct *p)
    }

    static void dummy_task_getsecid (struct task_struct *p, u32 *secid)
    -{ }
    +{
    + *secid = 0;
    +}

    static int dummy_task_setgroups (struct group_info *group_info)
    {
    @@ -616,6 +623,11 @@ static int dummy_ipc_permission (struct kern_ipc_perm *ipcp, short flag)
    return 0;
    }

    +static void dummy_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
    +{
    + *secid = 0;
    +}
    +
    static int dummy_msg_msg_alloc_security (struct msg_msg *msg)
    {
    return 0;
    @@ -1058,6 +1070,7 @@ void security_fixup_ops (struct security_operations *ops)
    set_to_dummy_if_null(ops, inode_getsecurity);
    set_to_dummy_if_null(ops, inode_setsecurity);
    set_to_dummy_if_null(ops, inode_listsecurity);
    + set_to_dummy_if_null(ops, inode_getsecid);
    set_to_dummy_if_null(ops, file_permission);
    set_to_dummy_if_null(ops, file_alloc_security);
    set_to_dummy_if_null(ops, file_free_security);
    @@ -1094,6 +1107,7 @@ void security_fixup_ops (struct security_operations *ops)
    set_to_dummy_if_null(ops, task_reparent_to_init);
    set_to_dummy_if_null(ops, task_to_inode);
    set_to_dummy_if_null(ops, ipc_permission);
    + set_to_dummy_if_null(ops, ipc_getsecid);
    set_to_dummy_if_null(ops, msg_msg_alloc_security);
    set_to_dummy_if_null(ops, msg_msg_free_security);
    set_to_dummy_if_null(ops, msg_queue_alloc_security);
    diff --git a/security/security.c b/security/security.c
    index b1387a6..33e59a7 100644
    --- a/security/security.c
    +++ b/security/security.c
    @@ -523,6 +523,11 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer
    return security_ops->inode_listsecurity(inode, buffer, buffer_size);
    }

    +void security_inode_getsecid(const struct inode *inode, u32 *secid)
    +{
    + security_ops->inode_getsecid(inode, secid);
    +}
    +
    int security_file_permission(struct file *file, int mask)
    {
    return security_ops->file_permission(file, mask);
    @@ -712,6 +717,11 @@ int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
    return security_ops->ipc_permission(ipcp, flag);
    }

    +void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
    +{
    + security_ops->ipc_getsecid(ipcp, secid);
    +}
    +
    int security_msg_msg_alloc(struct msg_msg *msg)
    {
    return security_ops->msg_msg_alloc_security(msg);
    --
    1.5.4.2

    --
    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/

  6. [PATCH 05/12] SELinux: remove redundant exports

    From: Ahmed S. Darwish

    Remove the following exported SELinux interfaces:
    selinux_get_inode_sid(inode, sid)
    selinux_get_ipc_sid(ipcp, sid)
    selinux_get_task_sid(tsk, sid)
    selinux_sid_to_string(sid, ctx, len)

    They can be substitued with the following generic equivalents
    respectively:
    new LSM hook, inode_getsecid(inode, secid)
    new LSM hook, ipc_getsecid*(ipcp, secid)
    LSM hook, task_getsecid(tsk, secid)
    LSM hook, sid_to_secctx(sid, ctx, len)

    Signed-off-by: Casey Schaufler
    Signed-off-by: Ahmed S. Darwish
    Acked-by: James Morris
    Reviewed-by: Paul Moore
    ---
    include/linux/selinux.h | 62 --------------------------------------------
    security/selinux/exports.c | 42 -----------------------------
    2 files changed, 0 insertions(+), 104 deletions(-)

    diff --git a/include/linux/selinux.h b/include/linux/selinux.h
    index 8c2cc4c..24b0af1 100644
    --- a/include/linux/selinux.h
    +++ b/include/linux/selinux.h
    @@ -16,7 +16,6 @@

    struct selinux_audit_rule;
    struct audit_context;
    -struct inode;
    struct kern_ipc_perm;

    #ifdef CONFIG_SECURITY_SELINUX
    @@ -70,45 +69,6 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op,
    void selinux_audit_set_callback(int (*callback)(void));

    /**
    - * selinux_sid_to_string - map a security context ID to a string
    - * @sid: security context ID to be converted.
    - * @ctx: address of context string to be returned
    - * @ctxlen: length of returned context string.
    - *
    - * Returns 0 if successful, -errno if not. On success, the context
    - * string will be allocated internally, and the caller must call
    - * kfree() on it after use.
    - */
    -int selinux_sid_to_string(u32 sid, char **ctx, u32 *ctxlen);
    -
    -/**
    - * selinux_get_inode_sid - get the inode's security context ID
    - * @inode: inode structure to get the sid from.
    - * @sid: pointer to security context ID to be filled in.
    - *
    - * Returns nothing
    - */
    -void selinux_get_inode_sid(const struct inode *inode, u32 *sid);
    -
    -/**
    - * selinux_get_ipc_sid - get the ipc security context ID
    - * @ipcp: ipc structure to get the sid from.
    - * @sid: pointer to security context ID to be filled in.
    - *
    - * Returns nothing
    - */
    -void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid);
    -
    -/**
    - * selinux_get_task_sid - return the SID of task
    - * @tsk: the task whose SID will be returned
    - * @sid: pointer to security context ID to be filled in.
    - *
    - * Returns nothing
    - */
    -void selinux_get_task_sid(struct task_struct *tsk, u32 *sid);
    -
    -/**
    * selinux_string_to_sid - map a security context string to a security ID
    * @str: the security context string to be mapped
    * @sid: ID value returned via this.
    @@ -175,28 +135,6 @@ static inline void selinux_audit_set_callback(int (*callback)(void))
    return;
    }

    -static inline int selinux_sid_to_string(u32 sid, char **ctx, u32 *ctxlen)
    -{
    - *ctx = NULL;
    - *ctxlen = 0;
    - return 0;
    -}
    -
    -static inline void selinux_get_inode_sid(const struct inode *inode, u32 *sid)
    -{
    - *sid = 0;
    -}
    -
    -static inline void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid)
    -{
    - *sid = 0;
    -}
    -
    -static inline void selinux_get_task_sid(struct task_struct *tsk, u32 *sid)
    -{
    - *sid = 0;
    -}
    -
    static inline int selinux_string_to_sid(const char *str, u32 *sid)
    {
    *sid = 0;
    diff --git a/security/selinux/exports.c b/security/selinux/exports.c
    index 87d2bb3..64af2d3 100644
    --- a/security/selinux/exports.c
    +++ b/security/selinux/exports.c
    @@ -25,48 +25,6 @@
    /* SECMARK reference count */
    extern atomic_t selinux_secmark_refcount;

    -int selinux_sid_to_string(u32 sid, char **ctx, u32 *ctxlen)
    -{
    - if (selinux_enabled)
    - return security_sid_to_context(sid, ctx, ctxlen);
    - else {
    - *ctx = NULL;
    - *ctxlen = 0;
    - }
    -
    - return 0;
    -}
    -
    -void selinux_get_inode_sid(const struct inode *inode, u32 *sid)
    -{
    - if (selinux_enabled) {
    - struct inode_security_struct *isec = inode->i_security;
    - *sid = isec->sid;
    - return;
    - }
    - *sid = 0;
    -}
    -
    -void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid)
    -{
    - if (selinux_enabled) {
    - struct ipc_security_struct *isec = ipcp->security;
    - *sid = isec->sid;
    - return;
    - }
    - *sid = 0;
    -}
    -
    -void selinux_get_task_sid(struct task_struct *tsk, u32 *sid)
    -{
    - if (selinux_enabled) {
    - struct task_security_struct *tsec = tsk->security;
    - *sid = tsec->sid;
    - return;
    - }
    - *sid = 0;
    -}
    -
    int selinux_string_to_sid(char *str, u32 *sid)
    {
    if (selinux_enabled)
    --
    1.5.4.2

    --
    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/

  7. [PATCH 10/12] Tell git about security/selinux/include/audit.h

    Signed-off-by: James Morris
    ---
    security/selinux/include/audit.h | 65 ++++++++++++++++++++++++++++++++++++++
    1 files changed, 65 insertions(+), 0 deletions(-)
    create mode 100644 security/selinux/include/audit.h

    diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h
    new file mode 100644
    index 0000000..6c8b9ef
    --- /dev/null
    +++ b/security/selinux/include/audit.h
    @@ -0,0 +1,65 @@
    +/*
    + * SELinux support for the Audit LSM hooks
    + *
    + * Most of below header was moved from include/linux/selinux.h which
    + * is released under below copyrights:
    + *
    + * Author: James Morris
    + *
    + * Copyright (C) 2005 Red Hat, Inc., James Morris
    + * Copyright (C) 2006 Trusted Computer Solutions, Inc.
    + * Copyright (C) 2006 IBM Corporation, Timothy R. Chavez
    + *
    + * This program is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License version 2,
    + * as published by the Free Software Foundation.
    + */
    +
    +#ifndef _SELINUX_AUDIT_H
    +#define _SELINUX_AUDIT_H
    +
    +/**
    + * selinux_audit_rule_init - alloc/init an selinux audit rule structure.
    + * @field: the field this rule refers to
    + * @op: the operater the rule uses
    + * @rulestr: the text "target" of the rule
    + * @rule: pointer to the new rule structure returned via this
    + *
    + * Returns 0 if successful, -errno if not. On success, the rule structure
    + * will be allocated internally. The caller must free this structure with
    + * selinux_audit_rule_free() after use.
    + */
    +int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule);
    +
    +/**
    + * selinux_audit_rule_free - free an selinux audit rule structure.
    + * @rule: pointer to the audit rule to be freed
    + *
    + * This will free all memory associated with the given rule.
    + * If @rule is NULL, no operation is performed.
    + */
    +void selinux_audit_rule_free(void *rule);
    +
    +/**
    + * selinux_audit_rule_match - determine if a context ID matches a rule.
    + * @sid: the context ID to check
    + * @field: the field this rule refers to
    + * @op: the operater the rule uses
    + * @rule: pointer to the audit rule to check against
    + * @actx: the audit context (can be NULL) associated with the check
    + *
    + * Returns 1 if the context id matches the rule, 0 if it does not, and
    + * -errno on failure.
    + */
    +int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule,
    + struct audit_context *actx);
    +
    +/**
    + * selinux_audit_rule_known - check to see if rule contains selinux fields.
    + * @rule: rule to be checked
    + * Returns 1 if there are selinux fields specified in the rule, 0 otherwise.
    + */
    +int selinux_audit_rule_known(struct audit_krule *krule);
    +
    +#endif /* _SELINUX_AUDIT_H */
    +
    --
    1.5.4.2

    --
    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/

  8. [PATCH 04/12] Netlink: Use generic LSM hook

    From: Ahmed S. Darwish

    Don't use SELinux exported selinux_get_task_sid symbol.
    Use the generic LSM equivalent instead.

    Signed-off-by: Casey Schaufler
    Signed-off-by: Ahmed S. Darwish
    Acked-by: James Morris
    Acked-by: David S. Miller
    Reviewed-by: Paul Moore
    ---
    net/netlink/af_netlink.c | 3 +--
    1 files changed, 1 insertions(+), 2 deletions(-)

    diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
    index 1ab0da2..61fd277 100644
    --- a/net/netlink/af_netlink.c
    +++ b/net/netlink/af_netlink.c
    @@ -54,7 +54,6 @@
    #include
    #include
    #include
    -#include
    #include

    #include
    @@ -1239,7 +1238,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
    NETLINK_CB(skb).pid = nlk->pid;
    NETLINK_CB(skb).dst_group = dst_group;
    NETLINK_CB(skb).loginuid = audit_get_loginuid(current);
    - selinux_get_task_sid(current, &(NETLINK_CB(skb).sid));
    + security_task_getsecid(current, &(NETLINK_CB(skb).sid));
    memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));

    /* What can I do? Netlink is asynchronous, so that
    --
    1.5.4.2

    --
    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/

  9. [PATCH 08/12] SELinux: use new audit hooks, remove redundant exports

    From: Ahmed S. Darwish

    Setup the new Audit LSM hooks for SELinux.
    Remove the now redundant exported SELinux Audit interface.

    Audit: Export 'audit_krule' and 'audit_field' to the public
    since their internals are needed by the implementation of the
    new LSM hook 'audit_rule_known'.

    Signed-off-by: Casey Schaufler
    Signed-off-by: Ahmed S. Darwish
    Acked-by: James Morris
    ---
    include/linux/audit.h | 29 ++++++++++++++++
    include/linux/selinux.h | 72 ----------------------------------------
    kernel/audit.h | 25 --------------
    security/selinux/hooks.c | 8 ++++
    security/selinux/ss/services.c | 45 +++++++++++++++++++------
    5 files changed, 71 insertions(+), 108 deletions(-)

    diff --git a/include/linux/audit.h b/include/linux/audit.h
    index 2af9ec0..04869c9 100644
    --- a/include/linux/audit.h
    +++ b/include/linux/audit.h
    @@ -353,6 +353,33 @@ struct netlink_skb_parms;
    struct linux_binprm;
    struct mq_attr;
    struct mqstat;
    +struct audit_watch;
    +struct audit_tree;
    +
    +struct audit_krule {
    + int vers_ops;
    + u32 flags;
    + u32 listnr;
    + u32 action;
    + u32 mask[AUDIT_BITMASK_SIZE];
    + u32 buflen; /* for data alloc on list rules */
    + u32 field_count;
    + char *filterkey; /* ties events to rules */
    + struct audit_field *fields;
    + struct audit_field *arch_f; /* quick access to arch field */
    + struct audit_field *inode_f; /* quick access to an inode field */
    + struct audit_watch *watch; /* associated watch */
    + struct audit_tree *tree; /* associated watched tree */
    + struct list_head rlist; /* entry in audit_{watch,tree}.rules list */
    +};
    +
    +struct audit_field {
    + u32 type;
    + u32 val;
    + u32 op;
    + char *se_str;
    + void *se_rule;
    +};

    #define AUDITSC_INVALID 0
    #define AUDITSC_SUCCESS 1
    @@ -536,6 +563,8 @@ extern void audit_log_d_path(struct audit_buffer *ab,
    const char *prefix,
    struct path *path);
    extern void audit_log_lost(const char *message);
    +extern int audit_update_lsm_rules(void);
    +
    /* Private API (for audit.c only) */
    extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
    extern int audit_filter_type(int type);
    diff --git a/include/linux/selinux.h b/include/linux/selinux.h
    index 24b0af1..20f965d 100644
    --- a/include/linux/selinux.h
    +++ b/include/linux/selinux.h
    @@ -21,54 +21,6 @@ struct kern_ipc_perm;
    #ifdef CONFIG_SECURITY_SELINUX

    /**
    - * selinux_audit_rule_init - alloc/init an selinux audit rule structure.
    - * @field: the field this rule refers to
    - * @op: the operater the rule uses
    - * @rulestr: the text "target" of the rule
    - * @rule: pointer to the new rule structure returned via this
    - *
    - * Returns 0 if successful, -errno if not. On success, the rule structure
    - * will be allocated internally. The caller must free this structure with
    - * selinux_audit_rule_free() after use.
    - */
    -int selinux_audit_rule_init(u32 field, u32 op, char *rulestr,
    - struct selinux_audit_rule **rule);
    -
    -/**
    - * selinux_audit_rule_free - free an selinux audit rule structure.
    - * @rule: pointer to the audit rule to be freed
    - *
    - * This will free all memory associated with the given rule.
    - * If @rule is NULL, no operation is performed.
    - */
    -void selinux_audit_rule_free(struct selinux_audit_rule *rule);
    -
    -/**
    - * selinux_audit_rule_match - determine if a context ID matches a rule.
    - * @sid: the context ID to check
    - * @field: the field this rule refers to
    - * @op: the operater the rule uses
    - * @rule: pointer to the audit rule to check against
    - * @actx: the audit context (can be NULL) associated with the check
    - *
    - * Returns 1 if the context id matches the rule, 0 if it does not, and
    - * -errno on failure.
    - */
    -int selinux_audit_rule_match(u32 sid, u32 field, u32 op,
    - struct selinux_audit_rule *rule,
    - struct audit_context *actx);
    -
    -/**
    - * selinux_audit_set_callback - set the callback for policy reloads.
    - * @callback: the function to call when the policy is reloaded
    - *
    - * This sets the function callback function that will update the rules
    - * upon policy reloads. This callback should rebuild all existing rules
    - * using selinux_audit_rule_init().
    - */
    -void selinux_audit_set_callback(int (*callback)(void));
    -
    -/**
    * selinux_string_to_sid - map a security context string to a security ID
    * @str: the security context string to be mapped
    * @sid: ID value returned via this.
    @@ -111,30 +63,6 @@ void selinux_secmark_refcount_inc(void);
    void selinux_secmark_refcount_dec(void);
    #else

    -static inline int selinux_audit_rule_init(u32 field, u32 op,
    - char *rulestr,
    - struct selinux_audit_rule **rule)
    -{
    - return -EOPNOTSUPP;
    -}
    -
    -static inline void selinux_audit_rule_free(struct selinux_audit_rule *rule)
    -{
    - return;
    -}
    -
    -static inline int selinux_audit_rule_match(u32 sid, u32 field, u32 op,
    - struct selinux_audit_rule *rule,
    - struct audit_context *actx)
    -{
    - return 0;
    -}
    -
    -static inline void selinux_audit_set_callback(int (*callback)(void))
    -{
    - return;
    -}
    -
    static inline int selinux_string_to_sid(const char *str, u32 *sid)
    {
    *sid = 0;
    diff --git a/kernel/audit.h b/kernel/audit.h
    index 2554bd5..3cfc54e 100644
    --- a/kernel/audit.h
    +++ b/kernel/audit.h
    @@ -65,34 +65,9 @@ struct audit_watch {
    struct list_head rules; /* associated rules */
    };

    -struct audit_field {
    - u32 type;
    - u32 val;
    - u32 op;
    - char *se_str;
    - struct selinux_audit_rule *se_rule;
    -};
    -
    struct audit_tree;
    struct audit_chunk;

    -struct audit_krule {
    - int vers_ops;
    - u32 flags;
    - u32 listnr;
    - u32 action;
    - u32 mask[AUDIT_BITMASK_SIZE];
    - u32 buflen; /* for data alloc on list rules */
    - u32 field_count;
    - char *filterkey; /* ties events to rules */
    - struct audit_field *fields;
    - struct audit_field *arch_f; /* quick access to arch field */
    - struct audit_field *inode_f; /* quick access to an inode field */
    - struct audit_watch *watch; /* associated watch */
    - struct audit_tree *tree; /* associated watched tree */
    - struct list_head rlist; /* entry in audit_{watch,tree}.rules list */
    -};
    -
    struct audit_entry {
    struct list_head list;
    struct rcu_head rcu;
    diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
    index 65bf7f7..afbaa07 100644
    --- a/security/selinux/hooks.c
    +++ b/security/selinux/hooks.c
    @@ -82,6 +82,7 @@
    #include "netnode.h"
    #include "xfrm.h"
    #include "netlabel.h"
    +#include "audit.h"

    #define XATTR_SELINUX_SUFFIX "selinux"
    #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
    @@ -5435,6 +5436,13 @@ static struct security_operations selinux_ops = {
    .key_free = selinux_key_free,
    .key_permission = selinux_key_permission,
    #endif
    +
    +#ifdef CONFIG_AUDIT
    + .audit_rule_init = selinux_audit_rule_init,
    + .audit_rule_known = selinux_audit_rule_known,
    + .audit_rule_match = selinux_audit_rule_match,
    + .audit_rule_free = selinux_audit_rule_free,
    +#endif
    };

    static __init int selinux_init(void)
    diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
    index 3f2bad2..934f9d0 100644
    --- a/security/selinux/ss/services.c
    +++ b/security/selinux/ss/services.c
    @@ -56,6 +56,7 @@
    #include "netlabel.h"
    #include "xfrm.h"
    #include "ebitmap.h"
    +#include "audit.h"

    extern void selnl_notify_policyload(u32 seqno);
    unsigned int policydb_loaded_version;
    @@ -2273,21 +2274,23 @@ struct selinux_audit_rule {
    struct context au_ctxt;
    };

    -void selinux_audit_rule_free(struct selinux_audit_rule *rule)
    +void selinux_audit_rule_free(void *vrule)
    {
    + struct selinux_audit_rule *rule = vrule;
    +
    if (rule) {
    context_destroy(&rule->au_ctxt);
    kfree(rule);
    }
    }

    -int selinux_audit_rule_init(u32 field, u32 op, char *rulestr,
    - struct selinux_audit_rule **rule)
    +int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
    {
    struct selinux_audit_rule *tmprule;
    struct role_datum *roledatum;
    struct type_datum *typedatum;
    struct user_datum *userdatum;
    + struct selinux_audit_rule **rule = (struct selinux_audit_rule **)vrule;
    int rc = 0;

    *rule = NULL;
    @@ -2374,12 +2377,37 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr,
    return rc;
    }

    -int selinux_audit_rule_match(u32 sid, u32 field, u32 op,
    - struct selinux_audit_rule *rule,
    +/* Check to see if the rule contains any selinux fields */
    +int selinux_audit_rule_known(struct audit_krule *rule)
    +{
    + int i;
    +
    + for (i = 0; i < rule->field_count; i++) {
    + struct audit_field *f = &rule->fields[i];
    + switch (f->type) {
    + case AUDIT_SUBJ_USER:
    + case AUDIT_SUBJ_ROLE:
    + case AUDIT_SUBJ_TYPE:
    + case AUDIT_SUBJ_SEN:
    + case AUDIT_SUBJ_CLR:
    + case AUDIT_OBJ_USER:
    + case AUDIT_OBJ_ROLE:
    + case AUDIT_OBJ_TYPE:
    + case AUDIT_OBJ_LEV_LOW:
    + case AUDIT_OBJ_LEV_HIGH:
    + return 1;
    + }
    + }
    +
    + return 0;
    +}
    +
    +int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
    struct audit_context *actx)
    {
    struct context *ctxt;
    struct mls_level *level;
    + struct selinux_audit_rule *rule = vrule;
    int match = 0;

    if (!rule) {
    @@ -2486,7 +2514,7 @@ out:
    return match;
    }

    -static int (*aurule_callback)(void) = NULL;
    +static int (*aurule_callback)(void) = audit_update_lsm_rules;

    static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid,
    u16 class, u32 perms, u32 *retained)
    @@ -2511,11 +2539,6 @@ static int __init aurule_init(void)
    }
    __initcall(aurule_init);

    -void selinux_audit_set_callback(int (*callback)(void))
    -{
    - aurule_callback = callback;
    -}
    -
    #ifdef CONFIG_NETLABEL
    /**
    * security_netlbl_cache_add - Add an entry to the NetLabel cache
    --
    1.5.4.2

    --
    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/

  10. [PATCH 11/12] Security: Introduce security= boot parameter

    From: Ahmed S. Darwish

    Add the security= boot parameter. This is done to avoid LSM
    registration clashes in case of more than one bult-in module.

    User can choose a security module to enable at boot. If no
    security= boot parameter is specified, only the first LSM
    asking for registration will be loaded. An invalid security
    module name will be treated as if no module has been chosen.

    LSM modules must check now if they are allowed to register
    by calling security_module_enable(ops) first. Modify SELinux
    and SMACK to do so.

    Do not let SMACK register smackfs if it was not chosen on
    boot. Smackfs assumes that smack hooks are registered and
    the initial task security setup (swapper->security) is done.

    Signed-off-by: Ahmed S. Darwish
    Acked-by: James Morris
    ---
    Documentation/kernel-parameters.txt | 6 +++++
    include/linux/security.h | 12 +++++++++++
    security/dummy.c | 4 ++-
    security/security.c | 38 ++++++++++++++++++++++++++++++++++-
    security/selinux/hooks.c | 7 ++++++
    security/smack/smack.h | 2 +
    security/smack/smack_lsm.c | 7 +++++-
    security/smack/smackfs.c | 11 +++++++++-
    8 files changed, 83 insertions(+), 4 deletions(-)

    diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
    index dafd001..436790f 100644
    --- a/Documentation/kernel-parameters.txt
    +++ b/Documentation/kernel-parameters.txt
    @@ -366,6 +366,12 @@ and is between 256 and 4096 characters. It is defined in the file
    possible to determine what the correct size should be.
    This option provides an override for these situations.

    + security= [SECURITY] Choose a security module to enable at boot.
    + If this boot parameter is not specified, only the first
    + security module asking for security registration will be
    + loaded. An invalid security module name will be treated
    + as if no module has been chosen.
    +
    capability.disable=
    [SECURITY] Disable capabilities. This would normally
    be used only if an alternative security model is to be
    diff --git a/include/linux/security.h b/include/linux/security.h
    index 697f228..f4116d6 100644
    --- a/include/linux/security.h
    +++ b/include/linux/security.h
    @@ -36,6 +36,9 @@

    extern unsigned securebits;

    +/* Maximum number of letters for an LSM name string */
    +#define SECURITY_NAME_MAX 10
    +
    struct ctl_table;
    struct audit_krule;

    @@ -137,6 +140,12 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
    /**
    * struct security_operations - main security structure
    *
    + * Security module identifier.
    + *
    + * @name:
    + * A string that acts as a unique identifeir for the LSM with max number
    + * of characters = SECURITY_NAME_MAX.
    + *
    * Security hooks for program execution operations.
    *
    * @bprm_alloc_security:
    @@ -1270,6 +1279,8 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
    * This is the main security structure.
    */
    struct security_operations {
    + char name[SECURITY_NAME_MAX + 1];
    +
    int (*ptrace) (struct task_struct * parent, struct task_struct * child);
    int (*capget) (struct task_struct * target,
    kernel_cap_t * effective,
    @@ -1537,6 +1548,7 @@ struct security_operations {

    /* prototypes */
    extern int security_init (void);
    +extern int security_module_enable(struct security_operations *ops);
    extern int register_security (struct security_operations *ops);
    extern int mod_reg_security (const char *name, struct security_operations *ops);
    extern struct dentry *securityfs_create_file(const char *name, mode_t mode,
    diff --git a/security/dummy.c b/security/dummy.c
    index 1ac9f8e..374d2ae 100644
    --- a/security/dummy.c
    +++ b/security/dummy.c
    @@ -1017,7 +1017,9 @@ static inline void dummy_audit_rule_free(void *lsmrule)

    #endif /* CONFIG_AUDIT */

    -struct security_operations dummy_security_ops;
    +struct security_operations dummy_security_ops = {
    + .name = "dummy",
    +};

    #define set_to_dummy_if_null(ops, function) \
    do { \
    diff --git a/security/security.c b/security/security.c
    index bf189d2..2ed153c 100644
    --- a/security/security.c
    +++ b/security/security.c
    @@ -17,6 +17,8 @@
    #include
    #include

    +/* Boot-time LSM user choice */
    +static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1];

    /* things that live in dummy.c */
    extern struct security_operations dummy_security_ops;
    @@ -67,13 +69,47 @@ int __init security_init(void)
    return 0;
    }

    +/* Save user chosen LSM */
    +static int __init choose_lsm(char *str)
    +{
    + strncpy(chosen_lsm, str, SECURITY_NAME_MAX);
    + return 1;
    +}
    +__setup("security=", choose_lsm);
    +
    +/**
    + * security_module_enable - Load given security module on boot ?
    + * @ops: a pointer to the struct security_operations that is to be checked.
    + *
    + * Each LSM must pass this method before registering its own operations
    + * to avoid security registration races. This method may also be used
    + * to check if your LSM is currently loaded.
    + *
    + * Return true if:
    + * -The passed LSM is the one chosen by user at boot time,
    + * -or user didsn't specify a specific LSM and we're the first to ask
    + * for registeration permissoin,
    + * -or the passed LSM is currently loaded.
    + * Otherwise, return false.
    + */
    +int __init security_module_enable(struct security_operations *ops)
    +{
    + if (!*chosen_lsm)
    + strncpy(chosen_lsm, ops->name, SECURITY_NAME_MAX);
    + else if (strncmp(ops->name, chosen_lsm, SECURITY_NAME_MAX))
    + return 0;
    +
    + return 1;
    +}
    +
    /**
    * register_security - registers a security framework with the kernel
    * @ops: a pointer to the struct security_options that is to be registered
    *
    * This function is to allow a security module to register itself with the
    * kernel security subsystem. Some rudimentary checking is done on the @ops
    - * value passed to this function.
    + * value passed to this function. You'll need to check first if your LSM
    + * is allowed to register its @ops by calling security_module_enable(@ops).
    *
    * If there is already a security module registered with the kernel,
    * an error will be returned. Otherwise 0 is returned on success.
    diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
    index afbaa07..44741ac 100644
    --- a/security/selinux/hooks.c
    +++ b/security/selinux/hooks.c
    @@ -5252,6 +5252,8 @@ static int selinux_key_permission(key_ref_t key_ref,
    #endif

    static struct security_operations selinux_ops = {
    + .name = "selinux",
    +
    .ptrace = selinux_ptrace,
    .capget = selinux_capget,
    .capset_check = selinux_capset_check,
    @@ -5449,6 +5451,11 @@ static __init int selinux_init(void)
    {
    struct task_security_struct *tsec;

    + if (!security_module_enable(&selinux_ops)) {
    + selinux_enabled = 0;
    + return 0;
    + }
    +
    if (!selinux_enabled) {
    printk(KERN_INFO "SELinux: Disabled at boot.\n");
    return 0;
    diff --git a/security/smack/smack.h b/security/smack/smack.h
    index 62c1e98..4a4477f 100644
    --- a/security/smack/smack.h
    +++ b/security/smack/smack.h
    @@ -15,6 +15,7 @@

    #include
    #include
    +#include
    #include

    /*
    @@ -187,6 +188,7 @@ extern struct smack_known smack_known_star;
    extern struct smack_known smack_known_unset;

    extern struct smk_list_entry *smack_list;
    +extern struct security_operations smack_ops;

    /*
    * Stricly for CIPSO level manipulation.
    diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
    index 732ba27..904bdc0 100644
    --- a/security/smack/smack_lsm.c
    +++ b/security/smack/smack_lsm.c
    @@ -2424,7 +2424,9 @@ static void smack_release_secctx(char *secdata, u32 seclen)
    {
    }

    -static struct security_operations smack_ops = {
    +struct security_operations smack_ops = {
    + .name = "smack",
    +
    .ptrace = smack_ptrace,
    .capget = cap_capget,
    .capset_check = cap_capset_check,
    @@ -2557,6 +2559,9 @@ static struct security_operations smack_ops = {
    */
    static __init int smack_init(void)
    {
    + if (!security_module_enable(&smack_ops))
    + return 0;
    +
    printk(KERN_INFO "Smack: Initializing.\n");

    /*
    diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
    index cfae8af..6ba2837 100644
    --- a/security/smack/smackfs.c
    +++ b/security/smack/smackfs.c
    @@ -965,12 +965,21 @@ static struct vfsmount *smackfs_mount;
    *
    * register the smackfs
    *
    - * Returns 0 unless the registration fails.
    + * Do not register smackfs if Smack wasn't enabled
    + * on boot. We can not put this method normally under the
    + * smack_init() code path since the security subsystem get
    + * initialized before the vfs caches.
    + *
    + * Returns true if we were not chosen on boot or if
    + * we were chosen and filesystem registration succeeded.
    */
    static int __init init_smk_fs(void)
    {
    int err;

    + if (!security_module_enable(&smack_ops))
    + return 0;
    +
    err = register_filesystem(&smk_fs_type);
    if (!err) {
    smackfs_mount = kern_mount(&smk_fs_type);
    --
    1.5.4.2

    --
    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/

  11. [PATCH 07/12] Audit: internally use the new LSM audit hooks

    From: Ahmed S. Darwish

    Convert Audit to use the new LSM Audit hooks instead of
    the exported SELinux interface.

    Basically, use:
    security_audit_rule_init
    secuirty_audit_rule_free
    security_audit_rule_known
    security_audit_rule_match

    instad of (respectively) :
    selinux_audit_rule_init
    selinux_audit_rule_free
    audit_rule_has_selinux
    selinux_audit_rule_match

    Signed-off-by: Casey Schaufler
    Signed-off-by: Ahmed S. Darwish
    Acked-by: James Morris
    ---
    kernel/audit.c | 7 +-----
    kernel/auditfilter.c | 61 ++++++++++++++------------------------------------
    kernel/auditsc.c | 9 +++----
    3 files changed, 22 insertions(+), 55 deletions(-)

    diff --git a/kernel/audit.c b/kernel/audit.c
    index 784a48e..a7b1608 100644
    --- a/kernel/audit.c
    +++ b/kernel/audit.c
    @@ -21,7 +21,7 @@
    *
    * Written by Rickard E. (Rik) Faith
    *
    - * Goals: 1) Integrate fully with SELinux.
    + * Goals: 1) Integrate fully with Security Modules.
    * 2) Minimal run-time overhead:
    * a) Minimal when syscall auditing is disabled (audit_enable=0).
    * b) Small when syscall auditing is enabled and no audit record
    @@ -55,7 +55,6 @@
    #include
    #include
    #include
    -#include
    #include
    #include
    #include
    @@ -882,10 +881,6 @@ static int __init audit_init(void)
    audit_enabled = audit_default;
    audit_ever_enabled |= !!audit_default;

    - /* Register the callback with selinux. This callback will be invoked
    - * when a new policy is loaded. */
    - selinux_audit_set_callback(&selinux_audit_rule_update);
    -
    audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");

    #ifdef CONFIG_AUDITSYSCALL
    diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
    index 35e58a1..7c69cb5 100644
    --- a/kernel/auditfilter.c
    +++ b/kernel/auditfilter.c
    @@ -29,7 +29,6 @@
    #include
    #include
    #include
    -#include
    #include "audit.h"

    /*
    @@ -39,7 +38,7 @@
    * Synchronizes writes and blocking reads of audit's filterlist
    * data. Rcu is used to traverse the filterlist and access
    * contents of structs audit_entry, audit_watch and opaque
    - * selinux rules during filtering. If modified, these structures
    + * LSM rules during filtering. If modified, these structures
    * must be copied and replace their counterparts in the filterlist.
    * An audit_parent struct is not accessed during filtering, so may
    * be written directly provided audit_filter_mutex is held.
    @@ -141,7 +140,7 @@ static inline void audit_free_rule(struct audit_entry *e)
    for (i = 0; i < e->rule.field_count; i++) {
    struct audit_field *f = &e->rule.fields[i];
    kfree(f->se_str);
    - selinux_audit_rule_free(f->se_rule);
    + security_audit_rule_free(f->se_rule);
    }
    kfree(e->rule.fields);
    kfree(e->rule.filterkey);
    @@ -598,12 +597,12 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
    goto exit_free;
    entry->rule.buflen += f->val;

    - err = selinux_audit_rule_init(f->type, f->op, str,
    - &f->se_rule);
    + err = security_audit_rule_init(f->type, f->op, str,
    + (void **)&f->se_rule);
    /* Keep currently invalid fields around in case they
    * become valid after a policy reload. */
    if (err == -EINVAL) {
    - printk(KERN_WARNING "audit rule for selinux "
    + printk(KERN_WARNING "audit rule for LSM "
    "\'%s\' is invalid\n", str);
    err = 0;
    }
    @@ -863,9 +862,9 @@ out:
    return new;
    }

    -/* Duplicate selinux field information. The se_rule is opaque, so must be
    +/* Duplicate LSM field information. The se_rule is opaque, so must be
    * re-initialized. */
    -static inline int audit_dupe_selinux_field(struct audit_field *df,
    +static inline int audit_dupe_lsm_field(struct audit_field *df,
    struct audit_field *sf)
    {
    int ret = 0;
    @@ -878,12 +877,12 @@ static inline int audit_dupe_selinux_field(struct audit_field *df,
    df->se_str = se_str;

    /* our own (refreshed) copy of se_rule */
    - ret = selinux_audit_rule_init(df->type, df->op, df->se_str,
    - &df->se_rule);
    + ret = security_audit_rule_init(df->type, df->op, df->se_str,
    + (void **)&df->se_rule);
    /* Keep currently invalid fields around in case they
    * become valid after a policy reload. */
    if (ret == -EINVAL) {
    - printk(KERN_WARNING "audit rule for selinux \'%s\' is "
    + printk(KERN_WARNING "audit rule for LSM \'%s\' is "
    "invalid\n", df->se_str);
    ret = 0;
    }
    @@ -892,7 +891,7 @@ static inline int audit_dupe_selinux_field(struct audit_field *df,
    }

    /* Duplicate an audit rule. This will be a deep copy with the exception
    - * of the watch - that pointer is carried over. The selinux specific fields
    + * of the watch - that pointer is carried over. The LSM specific fields
    * will be updated in the copy. The point is to be able to replace the old
    * rule with the new rule in the filterlist, then free the old rule.
    * The rlist element is undefined; list manipulations are handled apart from
    @@ -945,7 +944,7 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old,
    case AUDIT_OBJ_TYPE:
    case AUDIT_OBJ_LEV_LOW:
    case AUDIT_OBJ_LEV_HIGH:
    - err = audit_dupe_selinux_field(&new->fields[i],
    + err = audit_dupe_lsm_field(&new->fields[i],
    &old->fields[i]);
    break;
    case AUDIT_FILTERKEY:
    @@ -1763,38 +1762,12 @@ unlock_and_return:
    return result;
    }

    -/* Check to see if the rule contains any selinux fields. Returns 1 if there
    - are selinux fields specified in the rule, 0 otherwise. */
    -static inline int audit_rule_has_selinux(struct audit_krule *rule)
    -{
    - int i;
    -
    - for (i = 0; i < rule->field_count; i++) {
    - struct audit_field *f = &rule->fields[i];
    - switch (f->type) {
    - case AUDIT_SUBJ_USER:
    - case AUDIT_SUBJ_ROLE:
    - case AUDIT_SUBJ_TYPE:
    - case AUDIT_SUBJ_SEN:
    - case AUDIT_SUBJ_CLR:
    - case AUDIT_OBJ_USER:
    - case AUDIT_OBJ_ROLE:
    - case AUDIT_OBJ_TYPE:
    - case AUDIT_OBJ_LEV_LOW:
    - case AUDIT_OBJ_LEV_HIGH:
    - return 1;
    - }
    - }
    -
    - return 0;
    -}
    -
    /* This function will re-initialize the se_rule field of all applicable rules.
    - * It will traverse the filter lists serarching for rules that contain selinux
    + * It will traverse the filter lists serarching for rules that contain LSM
    * specific filter fields. When such a rule is found, it is copied, the
    - * selinux field is re-initialized, and the old rule is replaced with the
    + * LSM field is re-initialized, and the old rule is replaced with the
    * updated rule. */
    -int selinux_audit_rule_update(void)
    +int audit_update_lsm_rules(void)
    {
    struct audit_entry *entry, *n, *nentry;
    struct audit_watch *watch;
    @@ -1806,7 +1779,7 @@ int selinux_audit_rule_update(void)

    for (i = 0; i < AUDIT_NR_FILTERS; i++) {
    list_for_each_entry_safe(entry, n, &audit_filter_list[i], list) {
    - if (!audit_rule_has_selinux(&entry->rule))
    + if (!security_audit_rule_known(&entry->rule))
    continue;

    watch = entry->rule.watch;
    @@ -1817,7 +1790,7 @@ int selinux_audit_rule_update(void)
    * return value */
    if (!err)
    err = PTR_ERR(nentry);
    - audit_panic("error updating selinux filters");
    + audit_panic("error updating LSM filters");
    if (watch)
    list_del(&entry->rule.rlist);
    list_del_rcu(&entry->list);
    diff --git a/kernel/auditsc.c b/kernel/auditsc.c
    index 6a83c70..c070053 100644
    --- a/kernel/auditsc.c
    +++ b/kernel/auditsc.c
    @@ -61,7 +61,6 @@
    #include
    #include
    #include
    -#include
    #include
    #include
    #include
    @@ -533,7 +532,7 @@ static int audit_filter_rules(struct task_struct *tsk,
    security_task_getsecid(tsk, &sid);
    need_sid = 0;
    }
    - result = selinux_audit_rule_match(sid, f->type,
    + result = security_audit_rule_match(sid, f->type,
    f->op,
    f->se_rule,
    ctx);
    @@ -549,12 +548,12 @@ static int audit_filter_rules(struct task_struct *tsk,
    if (f->se_rule) {
    /* Find files that match */
    if (name) {
    - result = selinux_audit_rule_match(
    + result = security_audit_rule_match(
    name->osid, f->type, f->op,
    f->se_rule, ctx);
    } else if (ctx) {
    for (j = 0; j < ctx->name_count; j++) {
    - if (selinux_audit_rule_match(
    + if (security_audit_rule_match(
    ctx->names[j].osid,
    f->type, f->op,
    f->se_rule, ctx)) {
    @@ -570,7 +569,7 @@ static int audit_filter_rules(struct task_struct *tsk,
    aux = aux->next) {
    if (aux->type == AUDIT_IPC) {
    struct audit_aux_data_ipcctl *axi = (void *)aux;
    - if (selinux_audit_rule_match(axi->osid, f->type, f->op, f->se_rule, ctx)) {
    + if (security_audit_rule_match(axi->osid, f->type, f->op, f->se_rule, ctx)) {
    ++result;
    break;
    }
    --
    1.5.4.2

    --
    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/

  12. [PATCH 09/12] Audit: Final renamings and cleanup

    From: Ahmed S. Darwish

    Rename the se_str and se_rule audit fields elements to
    lsm_str and lsm_rule to avoid confusion.

    Signed-off-by: Casey Schaufler
    Signed-off-by: Ahmed S. Darwish
    Acked-by: James Morris
    ---
    include/linux/audit.h | 4 ++--
    kernel/auditfilter.c | 40 ++++++++++++++++++++--------------------
    kernel/auditsc.c | 12 ++++++------
    3 files changed, 28 insertions(+), 28 deletions(-)

    diff --git a/include/linux/audit.h b/include/linux/audit.h
    index 04869c9..4ccb048 100644
    --- a/include/linux/audit.h
    +++ b/include/linux/audit.h
    @@ -377,8 +377,8 @@ struct audit_field {
    u32 type;
    u32 val;
    u32 op;
    - char *se_str;
    - void *se_rule;
    + char *lsm_str;
    + void *lsm_rule;
    };

    #define AUDITSC_INVALID 0
    diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
    index 7c69cb5..28fef6b 100644
    --- a/kernel/auditfilter.c
    +++ b/kernel/auditfilter.c
    @@ -139,8 +139,8 @@ static inline void audit_free_rule(struct audit_entry *e)
    if (e->rule.fields)
    for (i = 0; i < e->rule.field_count; i++) {
    struct audit_field *f = &e->rule.fields[i];
    - kfree(f->se_str);
    - security_audit_rule_free(f->se_rule);
    + kfree(f->lsm_str);
    + security_audit_rule_free(f->lsm_rule);
    }
    kfree(e->rule.fields);
    kfree(e->rule.filterkey);
    @@ -554,8 +554,8 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
    f->op = data->fieldflags[i] & AUDIT_OPERATORS;
    f->type = data->fields[i];
    f->val = data->values[i];
    - f->se_str = NULL;
    - f->se_rule = NULL;
    + f->lsm_str = NULL;
    + f->lsm_rule = NULL;
    switch(f->type) {
    case AUDIT_PID:
    case AUDIT_UID:
    @@ -598,7 +598,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
    entry->rule.buflen += f->val;

    err = security_audit_rule_init(f->type, f->op, str,
    - (void **)&f->se_rule);
    + (void **)&f->lsm_rule);
    /* Keep currently invalid fields around in case they
    * become valid after a policy reload. */
    if (err == -EINVAL) {
    @@ -610,7 +610,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
    kfree(str);
    goto exit_free;
    } else
    - f->se_str = str;
    + f->lsm_str = str;
    break;
    case AUDIT_WATCH:
    str = audit_unpack_string(&bufp, &remain, f->val);
    @@ -754,7 +754,7 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
    case AUDIT_OBJ_LEV_LOW:
    case AUDIT_OBJ_LEV_HIGH:
    data->buflen += data->values[i] =
    - audit_pack_string(&bufp, f->se_str);
    + audit_pack_string(&bufp, f->lsm_str);
    break;
    case AUDIT_WATCH:
    data->buflen += data->values[i] =
    @@ -806,7 +806,7 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
    case AUDIT_OBJ_TYPE:
    case AUDIT_OBJ_LEV_LOW:
    case AUDIT_OBJ_LEV_HIGH:
    - if (strcmp(a->fields[i].se_str, b->fields[i].se_str))
    + if (strcmp(a->fields[i].lsm_str, b->fields[i].lsm_str))
    return 1;
    break;
    case AUDIT_WATCH:
    @@ -862,28 +862,28 @@ out:
    return new;
    }

    -/* Duplicate LSM field information. The se_rule is opaque, so must be
    +/* Duplicate LSM field information. The lsm_rule is opaque, so must be
    * re-initialized. */
    static inline int audit_dupe_lsm_field(struct audit_field *df,
    struct audit_field *sf)
    {
    int ret = 0;
    - char *se_str;
    + char *lsm_str;

    - /* our own copy of se_str */
    - se_str = kstrdup(sf->se_str, GFP_KERNEL);
    - if (unlikely(!se_str))
    + /* our own copy of lsm_str */
    + lsm_str = kstrdup(sf->lsm_str, GFP_KERNEL);
    + if (unlikely(!lsm_str))
    return -ENOMEM;
    - df->se_str = se_str;
    + df->lsm_str = lsm_str;

    - /* our own (refreshed) copy of se_rule */
    - ret = security_audit_rule_init(df->type, df->op, df->se_str,
    - (void **)&df->se_rule);
    + /* our own (refreshed) copy of lsm_rule */
    + ret = security_audit_rule_init(df->type, df->op, df->lsm_str,
    + (void **)&df->lsm_rule);
    /* Keep currently invalid fields around in case they
    * become valid after a policy reload. */
    if (ret == -EINVAL) {
    printk(KERN_WARNING "audit rule for LSM \'%s\' is "
    - "invalid\n", df->se_str);
    + "invalid\n", df->lsm_str);
    ret = 0;
    }

    @@ -930,7 +930,7 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old,
    new->tree = old->tree;
    memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount);

    - /* deep copy this information, updating the se_rule fields, because
    + /* deep copy this information, updating the lsm_rule fields, because
    * the originals will all be freed when the old rule is freed. */
    for (i = 0; i < fcount; i++) {
    switch (new->fields[i].type) {
    @@ -1762,7 +1762,7 @@ unlock_and_return:
    return result;
    }

    -/* This function will re-initialize the se_rule field of all applicable rules.
    +/* This function will re-initialize the lsm_rule field of all applicable rules.
    * It will traverse the filter lists serarching for rules that contain LSM
    * specific filter fields. When such a rule is found, it is copied, the
    * LSM field is re-initialized, and the old rule is replaced with the
    diff --git a/kernel/auditsc.c b/kernel/auditsc.c
    index c070053..56e56ed 100644
    --- a/kernel/auditsc.c
    +++ b/kernel/auditsc.c
    @@ -527,14 +527,14 @@ static int audit_filter_rules(struct task_struct *tsk,
    match for now to avoid losing information that
    may be wanted. An error message will also be
    logged upon error */
    - if (f->se_rule) {
    + if (f->lsm_rule) {
    if (need_sid) {
    security_task_getsecid(tsk, &sid);
    need_sid = 0;
    }
    result = security_audit_rule_match(sid, f->type,
    f->op,
    - f->se_rule,
    + f->lsm_rule,
    ctx);
    }
    break;
    @@ -545,18 +545,18 @@ static int audit_filter_rules(struct task_struct *tsk,
    case AUDIT_OBJ_LEV_HIGH:
    /* The above note for AUDIT_SUBJ_USER...AUDIT_SUBJ_CLR
    also applies here */
    - if (f->se_rule) {
    + if (f->lsm_rule) {
    /* Find files that match */
    if (name) {
    result = security_audit_rule_match(
    name->osid, f->type, f->op,
    - f->se_rule, ctx);
    + f->lsm_rule, ctx);
    } else if (ctx) {
    for (j = 0; j < ctx->name_count; j++) {
    if (security_audit_rule_match(
    ctx->names[j].osid,
    f->type, f->op,
    - f->se_rule, ctx)) {
    + f->lsm_rule, ctx)) {
    ++result;
    break;
    }
    @@ -569,7 +569,7 @@ static int audit_filter_rules(struct task_struct *tsk,
    aux = aux->next) {
    if (aux->type == AUDIT_IPC) {
    struct audit_aux_data_ipcctl *axi = (void *)aux;
    - if (security_audit_rule_match(axi->osid, f->type, f->op, f->se_rule, ctx)) {
    + if (security_audit_rule_match(axi->osid, f->type, f->op, f->lsm_rule, ctx)) {
    ++result;
    break;
    }
    --
    1.5.4.2

    --
    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/

  13. Re: [PATCH 11/12] Security: Introduce security= boot parameter


    --- James Morris wrote:

    > From: Ahmed S. Darwish
    >
    > Add the security= boot parameter. This is done to avoid LSM
    > registration clashes in case of more than one bult-in module.
    >
    > User can choose a security module to enable at boot. If no
    > security= boot parameter is specified, only the first LSM
    > asking for registration will be loaded. An invalid security
    > module name will be treated as if no module has been chosen.
    >
    > LSM modules must check now if they are allowed to register
    > by calling security_module_enable(ops) first. Modify SELinux
    > and SMACK to do so.
    >
    > Do not let SMACK register smackfs if it was not chosen on
    > boot. Smackfs assumes that smack hooks are registered and
    > the initial task security setup (swapper->security) is done.
    >
    > Signed-off-by: Ahmed S. Darwish
    > Acked-by: James Morris


    Acked-by: Casey Schaufler

    > ---
    > Documentation/kernel-parameters.txt | 6 +++++
    > include/linux/security.h | 12 +++++++++++
    > security/dummy.c | 4 ++-
    > security/security.c | 38
    > ++++++++++++++++++++++++++++++++++-
    > security/selinux/hooks.c | 7 ++++++
    > security/smack/smack.h | 2 +
    > security/smack/smack_lsm.c | 7 +++++-
    > security/smack/smackfs.c | 11 +++++++++-
    > 8 files changed, 83 insertions(+), 4 deletions(-)
    >
    > diff --git a/Documentation/kernel-parameters.txt
    > b/Documentation/kernel-parameters.txt
    > index dafd001..436790f 100644
    > --- a/Documentation/kernel-parameters.txt
    > +++ b/Documentation/kernel-parameters.txt
    > @@ -366,6 +366,12 @@ and is between 256 and 4096 characters. It is defined in
    > the file
    > possible to determine what the correct size should be.
    > This option provides an override for these situations.
    >
    > + security= [SECURITY] Choose a security module to enable at boot.
    > + If this boot parameter is not specified, only the first
    > + security module asking for security registration will be
    > + loaded. An invalid security module name will be treated
    > + as if no module has been chosen.
    > +
    > capability.disable=
    > [SECURITY] Disable capabilities. This would normally
    > be used only if an alternative security model is to be
    > diff --git a/include/linux/security.h b/include/linux/security.h
    > index 697f228..f4116d6 100644
    > --- a/include/linux/security.h
    > +++ b/include/linux/security.h
    > @@ -36,6 +36,9 @@
    >
    > extern unsigned securebits;
    >
    > +/* Maximum number of letters for an LSM name string */
    > +#define SECURITY_NAME_MAX 10
    > +
    > struct ctl_table;
    > struct audit_krule;
    >
    > @@ -137,6 +140,12 @@ static inline void security_free_mnt_opts(struct
    > security_mnt_opts *opts)
    > /**
    > * struct security_operations - main security structure
    > *
    > + * Security module identifier.
    > + *
    > + * @name:
    > + * A string that acts as a unique identifeir for the LSM with max number
    > + * of characters = SECURITY_NAME_MAX.
    > + *
    > * Security hooks for program execution operations.
    > *
    > * @bprm_alloc_security:
    > @@ -1270,6 +1279,8 @@ static inline void security_free_mnt_opts(struct
    > security_mnt_opts *opts)
    > * This is the main security structure.
    > */
    > struct security_operations {
    > + char name[SECURITY_NAME_MAX + 1];
    > +
    > int (*ptrace) (struct task_struct * parent, struct task_struct * child);
    > int (*capget) (struct task_struct * target,
    > kernel_cap_t * effective,
    > @@ -1537,6 +1548,7 @@ struct security_operations {
    >
    > /* prototypes */
    > extern int security_init (void);
    > +extern int security_module_enable(struct security_operations *ops);
    > extern int register_security (struct security_operations *ops);
    > extern int mod_reg_security (const char *name, struct security_operations
    > *ops);
    > extern struct dentry *securityfs_create_file(const char *name, mode_t mode,
    > diff --git a/security/dummy.c b/security/dummy.c
    > index 1ac9f8e..374d2ae 100644
    > --- a/security/dummy.c
    > +++ b/security/dummy.c
    > @@ -1017,7 +1017,9 @@ static inline void dummy_audit_rule_free(void *lsmrule)
    >
    > #endif /* CONFIG_AUDIT */
    >
    > -struct security_operations dummy_security_ops;
    > +struct security_operations dummy_security_ops = {
    > + .name = "dummy",
    > +};
    >
    > #define set_to_dummy_if_null(ops, function) \
    > do { \
    > diff --git a/security/security.c b/security/security.c
    > index bf189d2..2ed153c 100644
    > --- a/security/security.c
    > +++ b/security/security.c
    > @@ -17,6 +17,8 @@
    > #include
    > #include
    >
    > +/* Boot-time LSM user choice */
    > +static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1];
    >
    > /* things that live in dummy.c */
    > extern struct security_operations dummy_security_ops;
    > @@ -67,13 +69,47 @@ int __init security_init(void)
    > return 0;
    > }
    >
    > +/* Save user chosen LSM */
    > +static int __init choose_lsm(char *str)
    > +{
    > + strncpy(chosen_lsm, str, SECURITY_NAME_MAX);
    > + return 1;
    > +}
    > +__setup("security=", choose_lsm);
    > +
    > +/**
    > + * security_module_enable - Load given security module on boot ?
    > + * @ops: a pointer to the struct security_operations that is to be checked.
    > + *
    > + * Each LSM must pass this method before registering its own operations
    > + * to avoid security registration races. This method may also be used
    > + * to check if your LSM is currently loaded.
    > + *
    > + * Return true if:
    > + * -The passed LSM is the one chosen by user at boot time,
    > + * -or user didsn't specify a specific LSM and we're the first to ask
    > + * for registeration permissoin,
    > + * -or the passed LSM is currently loaded.
    > + * Otherwise, return false.
    > + */
    > +int __init security_module_enable(struct security_operations *ops)
    > +{
    > + if (!*chosen_lsm)
    > + strncpy(chosen_lsm, ops->name, SECURITY_NAME_MAX);
    > + else if (strncmp(ops->name, chosen_lsm, SECURITY_NAME_MAX))
    > + return 0;
    > +
    > + return 1;
    > +}
    > +
    > /**
    > * register_security - registers a security framework with the kernel
    > * @ops: a pointer to the struct security_options that is to be registered
    > *
    > * This function is to allow a security module to register itself with the
    > * kernel security subsystem. Some rudimentary checking is done on the @ops
    > - * value passed to this function.
    > + * value passed to this function. You'll need to check first if your LSM
    > + * is allowed to register its @ops by calling security_module_enable(@ops).
    > *
    > * If there is already a security module registered with the kernel,
    > * an error will be returned. Otherwise 0 is returned on success.
    > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
    > index afbaa07..44741ac 100644
    > --- a/security/selinux/hooks.c
    > +++ b/security/selinux/hooks.c
    > @@ -5252,6 +5252,8 @@ static int selinux_key_permission(key_ref_t key_ref,
    > #endif
    >
    > static struct security_operations selinux_ops = {
    > + .name = "selinux",
    > +
    > .ptrace = selinux_ptrace,
    > .capget = selinux_capget,
    > .capset_check = selinux_capset_check,
    > @@ -5449,6 +5451,11 @@ static __init int selinux_init(void)
    > {
    > struct task_security_struct *tsec;
    >
    > + if (!security_module_enable(&selinux_ops)) {
    > + selinux_enabled = 0;
    > + return 0;
    > + }
    > +
    > if (!selinux_enabled) {
    > printk(KERN_INFO "SELinux: Disabled at boot.\n");
    > return 0;
    > diff --git a/security/smack/smack.h b/security/smack/smack.h
    > index 62c1e98..4a4477f 100644
    > --- a/security/smack/smack.h
    > +++ b/security/smack/smack.h
    > @@ -15,6 +15,7 @@
    >
    > #include
    > #include
    > +#include
    > #include
    >
    > /*
    > @@ -187,6 +188,7 @@ extern struct smack_known smack_known_star;
    > extern struct smack_known smack_known_unset;
    >
    > extern struct smk_list_entry *smack_list;
    > +extern struct security_operations smack_ops;
    >
    > /*
    > * Stricly for CIPSO level manipulation.
    > diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
    > index 732ba27..904bdc0 100644
    > --- a/security/smack/smack_lsm.c
    > +++ b/security/smack/smack_lsm.c
    > @@ -2424,7 +2424,9 @@ static void smack_release_secctx(char *secdata, u32
    > seclen)
    > {
    > }
    >
    > -static struct security_operations smack_ops = {
    > +struct security_operations smack_ops = {
    > + .name = "smack",
    > +
    > .ptrace = smack_ptrace,
    > .capget = cap_capget,
    > .capset_check = cap_capset_check,
    > @@ -2557,6 +2559,9 @@ static struct security_operations smack_ops = {
    > */
    > static __init int smack_init(void)
    > {
    > + if (!security_module_enable(&smack_ops))
    > + return 0;
    > +
    > printk(KERN_INFO "Smack: Initializing.\n");
    >
    > /*
    > diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
    > index cfae8af..6ba2837 100644
    > --- a/security/smack/smackfs.c
    > +++ b/security/smack/smackfs.c
    > @@ -965,12 +965,21 @@ static struct vfsmount *smackfs_mount;
    > *
    > * register the smackfs
    > *
    > - * Returns 0 unless the registration fails.
    > + * Do not register smackfs if Smack wasn't enabled
    > + * on boot. We can not put this method normally under the
    > + * smack_init() code path since the security subsystem get
    > + * initialized before the vfs caches.
    > + *
    > + * Returns true if we were not chosen on boot or if
    > + * we were chosen and filesystem registration succeeded.
    > */
    > static int __init init_smk_fs(void)
    > {
    > int err;
    >
    > + if (!security_module_enable(&smack_ops))
    > + return 0;
    > +
    > err = register_filesystem(&smk_fs_type);
    > if (!err) {
    > smackfs_mount = kern_mount(&smk_fs_type);
    > --
    > 1.5.4.2
    >
    > --
    > To unsubscribe from this list: send the line "unsubscribe
    > linux-security-module" in
    > the body of a message to majordomo@vger.kernel.org
    > More majordomo info at http://vger.kernel.org/majordomo-info.html
    >
    >
    >



    Casey Schaufler
    casey@schaufler-ca.com
    --
    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/

  14. Re: [PATCH 10/12] Tell git about security/selinux/include/audit.h

    On Thu, Apr 17, 2008 at 11:06:07AM +0000, James Morris wrote:
    > Signed-off-by: James Morris
    > ---
    > security/selinux/include/audit.h | 65 ++++++++++++++++++++++++++++++++++++++


    Shouldn't this be merged with the previous patch that needed this?

    That way no one gets hit with a build error doing a 'git bisect'.

    thanks,

    greg k-h
    --
    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/

  15. Re: [PATCH 10/12] Tell git about security/selinux/include/audit.h

    On Thu, 17 Apr 2008, Greg KH wrote:

    > On Thu, Apr 17, 2008 at 11:06:07AM +0000, James Morris wrote:
    > > Signed-off-by: James Morris
    > > ---
    > > security/selinux/include/audit.h | 65 ++++++++++++++++++++++++++++++++++++++

    >
    > Shouldn't this be merged with the previous patch that needed this?


    Good thinking.


    --
    James Morris

    --
    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/

  16. [PATCH 2.6.26 #repost] Smack: Integrate with Audit

    Hi James/all,

    On Thu, Apr 17, 2008 at 11:05:57AM +0000, James Morris wrote:
    >
    > Please review the following security patches for 2.6.26, which have
    > been undergoing testing in the "next" tree and affect multiple LSMs.
    >
    >


    As a clarification, those new changes was added to the security tree
    to modularly integrate Smack with Audit. The final step is the
    reposted below patch which setups the new Audit hooks for Smack.

    The main concern against below patch was the reuse of SELinux Audit
    fields. For such reuse, Stephen asked for an explicit ACK from the
    Audit devs. I've CCed Steve and Al as a kind request for the ACK.

    Patch is re-based and re-tested over James's security/for-linus
    branch.

    Thanks all.

    -->

    Setup the new Audit hooks for Smack. SELinux Audit rule fields
    are recycled to avoid `auditd' userspace modifications.
    Currently only equality testing is supported on labels acting
    as a subject (AUDIT_SUBJ_USER) or as an object (AUDIT_OBJ_USER).

    Signed-off-by: Ahmed S. Darwish
    ---

    diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
    index 904bdc0..70e4abc 100644
    --- a/security/smack/smack_lsm.c
    +++ b/security/smack/smack_lsm.c
    @@ -26,6 +26,7 @@
    #include
    #include
    #include
    +#include

    #include "smack.h"

    @@ -752,6 +753,18 @@ static int smack_inode_listsecurity(struct inode *inode, char *buffer,
    return -EINVAL;
    }

    +/**
    + * smack_inode_getsecid - Extract inode's security id
    + * @inode: inode to extract the info from
    + * @secid: where result will be saved
    + */
    +static void smack_inode_getsecid(const struct inode *inode, u32 *secid)
    +{
    + struct inode_smack *isp = inode->i_security;
    +
    + *secid = smack_to_secid(isp->smk_inode);
    +}
    +
    /*
    * File Hooks
    */
    @@ -1805,6 +1818,18 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
    return smk_curacc(isp, may);
    }

    +/**
    + * smack_ipc_getsecid - Extract smack security id
    + * @ipcp: the object permissions
    + * @secid: where result will be saved
    + */
    +static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid)
    +{
    + char *smack = ipp->security;
    +
    + *secid = smack_to_secid(smack);
    +}
    +
    /* module stacking operations */

    /**
    @@ -2382,6 +2407,124 @@ static int smack_key_permission(key_ref_t key_ref,
    #endif /* CONFIG_KEYS */

    /*
    + * Smack Audit hooks
    + *
    + * Audit requires a unique representation of each Smack specific
    + * rule. This unique representation is used to distinguish the
    + * object to be audited from remaining kernel objects and also
    + * works as a glue between the audit hooks.
    + *
    + * Since repository entries are added but never deleted, we'll use
    + * the smack_known label address related to the given audit rule as
    + * the needed unique representation. This also better fits the smack
    + * model where nearly everything is a label.
    + */
    +#ifdef CONFIG_AUDIT
    +
    +/**
    + * smack_audit_rule_init - Initialize a smack audit rule
    + * @field: audit rule fields given from user-space (audit.h)
    + * @op: required testing operator (=, !=, >, <, ...)
    + * @rulestr: smack label to be audited
    + * @vrule: pointer to save our own audit rule representation
    + *
    + * Prepare to audit cases where (@field @op @rulestr) is true.
    + * The label to be audited is created if necessay.
    + */
    +static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
    +{
    + char **rule = (char **)vrule;
    + *rule = NULL;
    +
    + if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
    + return -EINVAL;
    +
    + if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL)
    + return -EINVAL;
    +
    + *rule = smk_import(rulestr, 0);
    +
    + return 0;
    +}
    +
    +/**
    + * smack_audit_rule_known - Distinguish Smack audit rules
    + * @krule: rule of interest, in Audit kernel representation format
    + *
    + * This is used to filter Smack rules from remaining Audit ones.
    + * If it's proved that this rule belongs to us, the
    + * audit_rule_match hook will be called to do the final judgement.
    + */
    +static int smack_audit_rule_known(struct audit_krule *krule)
    +{
    + struct audit_field *f;
    + int i;
    +
    + for (i = 0; i < krule->field_count; i++) {
    + f = &krule->fields[i];
    +
    + if (f->type == AUDIT_SUBJ_USER || f->type == AUDIT_OBJ_USER)
    + return 1;
    + }
    +
    + return 0;
    +}
    +
    +/**
    + * smack_audit_rule_match - Audit given object ?
    + * @secid: security id for identifying the object to test
    + * @field: audit rule flags given from user-space
    + * @op: required testing operator
    + * @vrule: smack internal rule presentation
    + * @actx: audit context associated with the check
    + *
    + * The core Audit hook. It's used to take the decision of
    + * whether to audit or not to audit a given object.
    + */
    +static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
    + struct audit_context *actx)
    +{
    + char *smack;
    + char *rule = vrule;
    +
    + if (!rule) {
    + audit_log(actx, GFP_KERNEL, AUDIT_SELINUX_ERR,
    + "Smack: missing rule\n");
    + return -ENOENT;
    + }
    +
    + if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
    + return 0;
    +
    + smack = smack_from_secid(secid);
    +
    + /*
    + * No need to do string comparisons. If a match occurs,
    + * both pointers will point to the same smack_known
    + * label.
    + */
    + if (op == AUDIT_EQUAL)
    + return (rule == smack);
    + if (op == AUDIT_NOT_EQUAL)
    + return (rule != smack);
    +
    + return 0;
    +}
    +
    +/**
    + * smack_audit_rule_free - free smack rule representation
    + * @vrule: rule to be freed.
    + *
    + * No memory was allocated.
    + */
    +static void smack_audit_rule_free(void *vrule)
    +{
    + /* No-op */
    +}
    +
    +#endif /* CONFIG_AUDIT */
    +
    +/*
    * smack_secid_to_secctx - return the smack label for a secid
    * @secid: incoming integer
    * @secdata: destination
    @@ -2467,6 +2610,7 @@ struct security_operations smack_ops = {
    .inode_getsecurity = smack_inode_getsecurity,
    .inode_setsecurity = smack_inode_setsecurity,
    .inode_listsecurity = smack_inode_listsecurity,
    + .inode_getsecid = smack_inode_getsecid,

    .file_permission = smack_file_permission,
    .file_alloc_security = smack_file_alloc_security,
    @@ -2497,6 +2641,7 @@ struct security_operations smack_ops = {
    .task_to_inode = smack_task_to_inode,

    .ipc_permission = smack_ipc_permission,
    + .ipc_getsecid = smack_ipc_getsecid,

    .msg_msg_alloc_security = smack_msg_msg_alloc_security,
    .msg_msg_free_security = smack_msg_msg_free_security,
    @@ -2541,12 +2686,22 @@ struct security_operations smack_ops = {
    .sk_free_security = smack_sk_free_security,
    .sock_graft = smack_sock_graft,
    .inet_conn_request = smack_inet_conn_request,
    +
    /* key management security hooks */
    #ifdef CONFIG_KEYS
    .key_alloc = smack_key_alloc,
    .key_free = smack_key_free,
    .key_permission = smack_key_permission,
    #endif /* CONFIG_KEYS */
    +
    + /* Audit hooks */
    +#ifdef CONFIG_AUDIT
    + .audit_rule_init = smack_audit_rule_init,
    + .audit_rule_known = smack_audit_rule_known,
    + .audit_rule_match = smack_audit_rule_match,
    + .audit_rule_free = smack_audit_rule_free,
    +#endif /* CONFIG_AUDIT */
    +
    .secid_to_secctx = smack_secid_to_secctx,
    .secctx_to_secid = smack_secctx_to_secid,
    .release_secctx = smack_release_secctx,

    --

    "Better to light a candle, than curse the darkness"

    Ahmed S. Darwish
    Homepage: http://darwish.07.googlepages.com
    Blog: http://darwish-07.blogspot.com

    --
    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/

  17. Re: Security testing tree patch review for 2.6.26


    --- James Morris wrote:

    >
    > Please review the following security patches for 2.6.26, which have
    > been undergoing testing in the "next" tree and affect multiple LSMs.


    I have done basic testing on this patchset and have not
    encountered any problems from the Smack side. I have not
    tested without Smack nor by implication with SELinux.


    >
    > The following changes since commit 4b119e21d0c66c22e8ca03df05d9de623d0eb50f:
    > Linus Torvalds (1):
    > Linux 2.6.25
    >
    > are available in the git repository at:
    >
    >
    >

    git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
    > for-linus
    >
    > Ahmed S. Darwish (10):
    > LSM: Introduce inode_getsecid and ipc_getsecid hooks
    > SELinux: setup new inode/ipc getsecid hooks
    > Audit: use new LSM hooks instead of SELinux exports
    > Netlink: Use generic LSM hook
    > SELinux: remove redundant exports
    > LSM/Audit: Introduce generic Audit LSM hooks
    > Audit: internally use the new LSM audit hooks
    > SELinux: use new audit hooks, remove redundant exports
    > Audit: Final renamings and cleanup
    > Security: Introduce security= boot parameter
    >
    > James Morris (2):
    > Tell git about security/selinux/include/audit.h
    > security: fix up documentation for security_module_enable
    >
    > Documentation/kernel-parameters.txt | 6 ++
    > include/linux/audit.h | 29 ++++++++
    > include/linux/security.h | 114 +++++++++++++++++++++++++++++-
    > include/linux/selinux.h | 134
    > -----------------------------------
    > kernel/audit.c | 24 +++----
    > kernel/audit.h | 25 -------
    > kernel/auditfilter.c | 99 ++++++++++----------------
    > kernel/auditsc.c | 74 ++++++++++---------
    > net/netlink/af_netlink.c | 3 +-
    > security/dummy.c | 51 +++++++++++++-
    > security/security.c | 73 +++++++++++++++++++-
    > security/selinux/exports.c | 42 -----------
    > security/selinux/hooks.c | 34 ++++++++-
    > security/selinux/include/audit.h | 65 +++++++++++++++++
    > security/selinux/ss/services.c | 45 +++++++++---
    > security/smack/smack.h | 2 +
    > security/smack/smack_lsm.c | 7 ++-
    > security/smack/smackfs.c | 11 +++-
    > 18 files changed, 503 insertions(+), 335 deletions(-)
    > create mode 100644 security/selinux/include/audit.h
    > --
    > To unsubscribe from this list: send the line "unsubscribe
    > linux-security-module" in
    > the body of a message to majordomo@vger.kernel.org
    > More majordomo info at http://vger.kernel.org/majordomo-info.html
    >
    >
    >



    Casey Schaufler
    casey@schaufler-ca.com
    --
    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/

  18. Re: [PATCH 2.6.26 #repost] Smack: Integrate with Audit


    --- "Ahmed S. Darwish" wrote:

    > Hi James/all,
    >
    > On Thu, Apr 17, 2008 at 11:05:57AM +0000, James Morris wrote:
    > >
    > > Please review the following security patches for 2.6.26, which have
    > > been undergoing testing in the "next" tree and affect multiple LSMs.
    > >
    > >

    >
    > As a clarification, those new changes was added to the security tree
    > to modularly integrate Smack with Audit. The final step is the
    > reposted below patch which setups the new Audit hooks for Smack.
    >
    > The main concern against below patch was the reuse of SELinux Audit
    > fields. For such reuse, Stephen asked for an explicit ACK from the
    > Audit devs. I've CCed Steve and Al as a kind request for the ACK.
    >
    > Patch is re-based and re-tested over James's security/for-linus
    > branch.
    >
    > Thanks all.
    >
    > -->
    >
    > Setup the new Audit hooks for Smack. SELinux Audit rule fields
    > are recycled to avoid `auditd' userspace modifications.
    > Currently only equality testing is supported on labels acting
    > as a subject (AUDIT_SUBJ_USER) or as an object (AUDIT_OBJ_USER).
    >
    > Signed-off-by: Ahmed S. Darwish


    Acked-by: Casey Schaufler

    Had to test it before acking. It's running fine for me.

    > ---
    >
    > diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
    > index 904bdc0..70e4abc 100644
    > --- a/security/smack/smack_lsm.c
    > +++ b/security/smack/smack_lsm.c
    > @@ -26,6 +26,7 @@
    > #include
    > #include
    > #include
    > +#include
    >
    > #include "smack.h"
    >
    > @@ -752,6 +753,18 @@ static int smack_inode_listsecurity(struct inode *inode,
    > char *buffer,
    > return -EINVAL;
    > }
    >
    > +/**
    > + * smack_inode_getsecid - Extract inode's security id
    > + * @inode: inode to extract the info from
    > + * @secid: where result will be saved
    > + */
    > +static void smack_inode_getsecid(const struct inode *inode, u32 *secid)
    > +{
    > + struct inode_smack *isp = inode->i_security;
    > +
    > + *secid = smack_to_secid(isp->smk_inode);
    > +}
    > +
    > /*
    > * File Hooks
    > */
    > @@ -1805,6 +1818,18 @@ static int smack_ipc_permission(struct kern_ipc_perm
    > *ipp, short flag)
    > return smk_curacc(isp, may);
    > }
    >
    > +/**
    > + * smack_ipc_getsecid - Extract smack security id
    > + * @ipcp: the object permissions
    > + * @secid: where result will be saved
    > + */
    > +static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid)
    > +{
    > + char *smack = ipp->security;
    > +
    > + *secid = smack_to_secid(smack);
    > +}
    > +
    > /* module stacking operations */
    >
    > /**
    > @@ -2382,6 +2407,124 @@ static int smack_key_permission(key_ref_t key_ref,
    > #endif /* CONFIG_KEYS */
    >
    > /*
    > + * Smack Audit hooks
    > + *
    > + * Audit requires a unique representation of each Smack specific
    > + * rule. This unique representation is used to distinguish the
    > + * object to be audited from remaining kernel objects and also
    > + * works as a glue between the audit hooks.
    > + *
    > + * Since repository entries are added but never deleted, we'll use
    > + * the smack_known label address related to the given audit rule as
    > + * the needed unique representation. This also better fits the smack
    > + * model where nearly everything is a label.
    > + */
    > +#ifdef CONFIG_AUDIT
    > +
    > +/**
    > + * smack_audit_rule_init - Initialize a smack audit rule
    > + * @field: audit rule fields given from user-space (audit.h)
    > + * @op: required testing operator (=, !=, >, <, ...)
    > + * @rulestr: smack label to be audited
    > + * @vrule: pointer to save our own audit rule representation
    > + *
    > + * Prepare to audit cases where (@field @op @rulestr) is true.
    > + * The label to be audited is created if necessay.
    > + */
    > +static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void
    > **vrule)
    > +{
    > + char **rule = (char **)vrule;
    > + *rule = NULL;
    > +
    > + if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
    > + return -EINVAL;
    > +
    > + if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL)
    > + return -EINVAL;
    > +
    > + *rule = smk_import(rulestr, 0);
    > +
    > + return 0;
    > +}
    > +
    > +/**
    > + * smack_audit_rule_known - Distinguish Smack audit rules
    > + * @krule: rule of interest, in Audit kernel representation format
    > + *
    > + * This is used to filter Smack rules from remaining Audit ones.
    > + * If it's proved that this rule belongs to us, the
    > + * audit_rule_match hook will be called to do the final judgement.
    > + */
    > +static int smack_audit_rule_known(struct audit_krule *krule)
    > +{
    > + struct audit_field *f;
    > + int i;
    > +
    > + for (i = 0; i < krule->field_count; i++) {
    > + f = &krule->fields[i];
    > +
    > + if (f->type == AUDIT_SUBJ_USER || f->type == AUDIT_OBJ_USER)
    > + return 1;
    > + }
    > +
    > + return 0;
    > +}
    > +
    > +/**
    > + * smack_audit_rule_match - Audit given object ?
    > + * @secid: security id for identifying the object to test
    > + * @field: audit rule flags given from user-space
    > + * @op: required testing operator
    > + * @vrule: smack internal rule presentation
    > + * @actx: audit context associated with the check
    > + *
    > + * The core Audit hook. It's used to take the decision of
    > + * whether to audit or not to audit a given object.
    > + */
    > +static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
    > + struct audit_context *actx)
    > +{
    > + char *smack;
    > + char *rule = vrule;
    > +
    > + if (!rule) {
    > + audit_log(actx, GFP_KERNEL, AUDIT_SELINUX_ERR,
    > + "Smack: missing rule\n");
    > + return -ENOENT;
    > + }
    > +
    > + if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
    > + return 0;
    > +
    > + smack = smack_from_secid(secid);
    > +
    > + /*
    > + * No need to do string comparisons. If a match occurs,
    > + * both pointers will point to the same smack_known
    > + * label.
    > + */
    > + if (op == AUDIT_EQUAL)
    > + return (rule == smack);
    > + if (op == AUDIT_NOT_EQUAL)
    > + return (rule != smack);
    > +
    > + return 0;
    > +}
    > +
    > +/**
    > + * smack_audit_rule_free - free smack rule representation
    > + * @vrule: rule to be freed.
    > + *
    > + * No memory was allocated.
    > + */
    > +static void smack_audit_rule_free(void *vrule)
    > +{
    > + /* No-op */
    > +}
    > +
    > +#endif /* CONFIG_AUDIT */
    > +
    > +/*
    > * smack_secid_to_secctx - return the smack label for a secid
    > * @secid: incoming integer
    > * @secdata: destination
    > @@ -2467,6 +2610,7 @@ struct security_operations smack_ops = {
    > .inode_getsecurity = smack_inode_getsecurity,
    > .inode_setsecurity = smack_inode_setsecurity,
    > .inode_listsecurity = smack_inode_listsecurity,
    > + .inode_getsecid = smack_inode_getsecid,
    >
    > .file_permission = smack_file_permission,
    > .file_alloc_security = smack_file_alloc_security,
    > @@ -2497,6 +2641,7 @@ struct security_operations smack_ops = {
    > .task_to_inode = smack_task_to_inode,
    >
    > .ipc_permission = smack_ipc_permission,
    > + .ipc_getsecid = smack_ipc_getsecid,
    >
    > .msg_msg_alloc_security = smack_msg_msg_alloc_security,
    > .msg_msg_free_security = smack_msg_msg_free_security,
    > @@ -2541,12 +2686,22 @@ struct security_operations smack_ops = {
    > .sk_free_security = smack_sk_free_security,
    > .sock_graft = smack_sock_graft,
    > .inet_conn_request = smack_inet_conn_request,
    > +
    > /* key management security hooks */
    > #ifdef CONFIG_KEYS
    > .key_alloc = smack_key_alloc,
    > .key_free = smack_key_free,
    > .key_permission = smack_key_permission,
    > #endif /* CONFIG_KEYS */
    > +
    > + /* Audit hooks */
    > +#ifdef CONFIG_AUDIT
    > + .audit_rule_init = smack_audit_rule_init,
    > + .audit_rule_known = smack_audit_rule_known,
    > + .audit_rule_match = smack_audit_rule_match,
    > + .audit_rule_free = smack_audit_rule_free,
    > +#endif /* CONFIG_AUDIT */
    > +
    > .secid_to_secctx = smack_secid_to_secctx,
    > .secctx_to_secid = smack_secctx_to_secid,
    > .release_secctx = smack_release_secctx,
    >
    > --
    >
    > "Better to light a candle, than curse the darkness"
    >
    > Ahmed S. Darwish
    > Homepage: http://darwish.07.googlepages.com
    > Blog: http://darwish-07.blogspot.com
    >
    >
    >



    Casey Schaufler
    casey@schaufler-ca.com
    --
    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/

  19. Re: Security testing tree patch review for 2.6.26

    On Thu, Apr 17, 2008 at 11:05:57AM +0000, James Morris wrote:
    >
    > Please review the following security patches for 2.6.26, which have
    > been undergoing testing in the "next" tree and affect multiple LSMs.


    Looks sane...
    --
    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/

+ Reply to Thread