lkml.org 
[lkml]   [2023]   [Feb]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v6 09/11] AppArmor: Add selfattr hooks
    Date
    Add hooks for setselfattr and getselfattr. These hooks are not very
    different from their setprocattr and getprocattr equivalents, and
    much of the code is shared.

    Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
    ---
    security/apparmor/include/procattr.h | 2 +-
    security/apparmor/lsm.c | 91 ++++++++++++++++++++++++++--
    security/apparmor/procattr.c | 11 +++-
    3 files changed, 94 insertions(+), 10 deletions(-)

    diff --git a/security/apparmor/include/procattr.h b/security/apparmor/include/procattr.h
    index 31689437e0e1..03dbfdb2f2c0 100644
    --- a/security/apparmor/include/procattr.h
    +++ b/security/apparmor/include/procattr.h
    @@ -11,7 +11,7 @@
    #ifndef __AA_PROCATTR_H
    #define __AA_PROCATTR_H

    -int aa_getprocattr(struct aa_label *label, char **string);
    +int aa_getprocattr(struct aa_label *label, char **string, bool newline);
    int aa_setprocattr_changehat(char *args, size_t size, int flags);

    #endif /* __AA_PROCATTR_H */
    diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
    index 0c2f4d47af42..165fffff095a 100644
    --- a/security/apparmor/lsm.c
    +++ b/security/apparmor/lsm.c
    @@ -632,6 +632,44 @@ static int apparmor_sb_pivotroot(const struct path *old_path,
    return error;
    }

    +static int apparmor_getselfattr(u64 __user attr, struct lsm_ctx __user *lx,
    + size_t *size)
    +{
    + int error = -ENOENT;
    + struct aa_task_ctx *ctx = task_ctx(current);
    + struct aa_label *label = NULL;
    + size_t total_len;
    + char *value;
    +
    + if (attr == LSM_ATTR_CURRENT)
    + label = aa_get_newest_label(cred_label(current_cred()));
    + else if (attr == LSM_ATTR_PREV && ctx->previous)
    + label = aa_get_newest_label(ctx->previous);
    + else if (attr == LSM_ATTR_EXEC && ctx->onexec)
    + label = aa_get_newest_label(ctx->onexec);
    + else
    + error = -EOPNOTSUPP;
    +
    + if (label) {
    + error = aa_getprocattr(label, &value, false);
    + if (error > 0) {
    + total_len = error + sizeof(*ctx);
    + if (total_len > *size)
    + error = -E2BIG;
    + else
    + lsm_fill_user_ctx(lx, value, error,
    + LSM_ID_APPARMOR, 0);
    + }
    + }
    +
    + aa_put_label(label);
    +
    + *size = total_len;
    + if (error > 0)
    + return 0;
    + return error;
    +}
    +
    static int apparmor_getprocattr(struct task_struct *task, const char *name,
    char **value)
    {
    @@ -651,7 +689,7 @@ static int apparmor_getprocattr(struct task_struct *task, const char *name,
    error = -EINVAL;

    if (label)
    - error = aa_getprocattr(label, value);
    + error = aa_getprocattr(label, value, true);

    aa_put_label(label);
    put_cred(cred);
    @@ -659,8 +697,7 @@ static int apparmor_getprocattr(struct task_struct *task, const char *name,
    return error;
    }

    -static int apparmor_setprocattr(const char *name, void *value,
    - size_t size)
    +static int do_setattr(u64 attr, void *value, size_t size)
    {
    char *command, *largs = NULL, *args = value;
    size_t arg_size;
    @@ -691,7 +728,7 @@ static int apparmor_setprocattr(const char *name, void *value,
    goto out;

    arg_size = size - (args - (largs ? largs : (char *) value));
    - if (strcmp(name, "current") == 0) {
    + if (attr == LSM_ATTR_CURRENT) {
    if (strcmp(command, "changehat") == 0) {
    error = aa_setprocattr_changehat(args, arg_size,
    AA_CHANGE_NOFLAGS);
    @@ -706,7 +743,7 @@ static int apparmor_setprocattr(const char *name, void *value,
    error = aa_change_profile(args, AA_CHANGE_STACK);
    } else
    goto fail;
    - } else if (strcmp(name, "exec") == 0) {
    + } else if (attr == LSM_ATTR_EXEC) {
    if (strcmp(command, "exec") == 0)
    error = aa_change_profile(args, AA_CHANGE_ONEXEC);
    else if (strcmp(command, "stack") == 0)
    @@ -726,13 +763,53 @@ static int apparmor_setprocattr(const char *name, void *value,

    fail:
    aad(&sa)->label = begin_current_label_crit_section();
    - aad(&sa)->info = name;
    + if (attr == LSM_ATTR_CURRENT)
    + aad(&sa)->info = "current";
    + else if (attr == LSM_ATTR_EXEC)
    + aad(&sa)->info = "exec";
    + else
    + aad(&sa)->info = "invalid";
    aad(&sa)->error = error = -EINVAL;
    aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
    end_current_label_crit_section(aad(&sa)->label);
    goto out;
    }

    +static int apparmor_setselfattr(u64 __user attr, struct lsm_ctx __user *ctx,
    + size_t __user size)
    +{
    + struct lsm_ctx *lctx;
    + void *context;
    + int rc;
    +
    + context = kmalloc(size, GFP_KERNEL);
    + if (context == NULL)
    + return -ENOMEM;
    +
    + lctx = (struct lsm_ctx *)context;
    + if (copy_from_user(context, ctx, size))
    + rc = -EFAULT;
    + else if (lctx->ctx_len > size)
    + rc = -EINVAL;
    + else
    + rc = do_setattr(attr, lctx + 1, lctx->ctx_len);
    +
    + kfree(context);
    + if (rc > 0)
    + return 0;
    + return rc;
    +}
    +
    +static int apparmor_setprocattr(const char *name, void *value,
    + size_t size)
    +{
    + int attr = lsm_name_to_attr(name);
    +
    + if (attr)
    + return do_setattr(attr, value, size);
    + return -EINVAL;
    +}
    +
    /**
    * apparmor_bprm_committing_creds - do task cleanup on committing new creds
    * @bprm: binprm for the exec (NOT NULL)
    @@ -1256,6 +1333,8 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
    LSM_HOOK_INIT(file_lock, apparmor_file_lock),
    LSM_HOOK_INIT(file_truncate, apparmor_file_truncate),

    + LSM_HOOK_INIT(getselfattr, apparmor_getselfattr),
    + LSM_HOOK_INIT(setselfattr, apparmor_setselfattr),
    LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),
    LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),

    diff --git a/security/apparmor/procattr.c b/security/apparmor/procattr.c
    index 197d41f9c32b..196f319aa3b2 100644
    --- a/security/apparmor/procattr.c
    +++ b/security/apparmor/procattr.c
    @@ -20,6 +20,7 @@
    * aa_getprocattr - Return the label information for @label
    * @label: the label to print label info about (NOT NULL)
    * @string: Returns - string containing the label info (NOT NULL)
    + * @newline: indicates that a newline should be added
    *
    * Requires: label != NULL && string != NULL
    *
    @@ -27,7 +28,7 @@
    *
    * Returns: size of string placed in @string else error code on failure
    */
    -int aa_getprocattr(struct aa_label *label, char **string)
    +int aa_getprocattr(struct aa_label *label, char **string, bool newline)
    {
    struct aa_ns *ns = labels_ns(label);
    struct aa_ns *current_ns = aa_get_current_ns();
    @@ -57,10 +58,14 @@ int aa_getprocattr(struct aa_label *label, char **string)
    return len;
    }

    - (*string)[len] = '\n';
    - (*string)[len + 1] = 0;
    + if (newline)
    + (*string)[len++] = '\n';
    + (*string)[len] = 0;

    aa_put_ns(current_ns);
    +
    + if (newline)
    + return len;
    return len + 1;
    }

    --
    2.39.0
    \
     
     \ /
      Last update: 2023-03-27 00:32    [W:3.813 / U:0.140 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site