lkml.org 
[lkml]   [2021]   [Jun]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v27 21/25] audit: add support for non-syscall auxiliary records
    Date
    Standalone audit records have the timestamp and serial number generated
    on the fly and as such are unique, making them standalone. This new
    function audit_alloc_local() generates a local audit context that will
    be used only for a standalone record and its auxiliary record(s). The
    context is discarded immediately after the local associated records are
    produced.

    Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
    Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
    Cc: linux-audit@redhat.com
    To: Richard Guy Briggs <rgb@redhat.com>
    ---
    include/linux/audit.h | 8 ++++++++
    kernel/audit.h | 1 +
    kernel/auditsc.c | 33 ++++++++++++++++++++++++++++-----
    3 files changed, 37 insertions(+), 5 deletions(-)

    diff --git a/include/linux/audit.h b/include/linux/audit.h
    index 418a485af114..97cd7471e572 100644
    --- a/include/linux/audit.h
    +++ b/include/linux/audit.h
    @@ -289,6 +289,8 @@ static inline int audit_signal_info(int sig, struct task_struct *t)
    /* Public API */
    extern int audit_alloc(struct task_struct *task);
    extern void __audit_free(struct task_struct *task);
    +extern struct audit_context *audit_alloc_local(gfp_t gfpflags);
    +extern void audit_free_context(struct audit_context *context);
    extern void __audit_syscall_entry(int major, unsigned long a0, unsigned long a1,
    unsigned long a2, unsigned long a3);
    extern void __audit_syscall_exit(int ret_success, long ret_value);
    @@ -552,6 +554,12 @@ static inline void audit_log_nfcfg(const char *name, u8 af,
    extern int audit_n_rules;
    extern int audit_signals;
    #else /* CONFIG_AUDITSYSCALL */
    ++static inline struct audit_context *audit_alloc_local(gfp_t gfpflags)
    +{
    + return NULL;
    +}
    +static inline void audit_free_context(struct audit_context *context)
    +{ }
    static inline int audit_alloc(struct task_struct *task)
    {
    return 0;
    diff --git a/kernel/audit.h b/kernel/audit.h
    index 23a85a470121..27ef690afd30 100644
    --- a/kernel/audit.h
    +++ b/kernel/audit.h
    @@ -99,6 +99,7 @@ struct audit_proctitle {
    struct audit_context {
    int dummy; /* must be the first element */
    int in_syscall; /* 1 if task is in a syscall */
    + bool local; /* local context needed */
    enum audit_state state, current_state;
    unsigned int serial; /* serial number for record */
    int major; /* syscall number */
    diff --git a/kernel/auditsc.c b/kernel/auditsc.c
    index 67da23f6bebd..d4e061f95da8 100644
    --- a/kernel/auditsc.c
    +++ b/kernel/auditsc.c
    @@ -925,11 +925,13 @@ static inline void audit_free_aux(struct audit_context *context)
    }
    }

    -static inline struct audit_context *audit_alloc_context(enum audit_state state)
    +static inline struct audit_context *audit_alloc_context(enum audit_state state,
    + gfp_t gfpflags)
    {
    struct audit_context *context;

    - context = kzalloc(sizeof(*context), GFP_KERNEL);
    + /* We can be called in atomic context via audit_tg() */
    + context = kzalloc(sizeof(*context), gfpflags);
    if (!context)
    return NULL;
    context->state = state;
    @@ -965,7 +967,8 @@ int audit_alloc(struct task_struct *tsk)
    return 0;
    }

    - if (!(context = audit_alloc_context(state))) {
    + context = audit_alloc_context(state, GFP_KERNEL);
    + if (!context) {
    kfree(key);
    audit_log_lost("out of memory in audit_alloc");
    return -ENOMEM;
    @@ -977,8 +980,27 @@ int audit_alloc(struct task_struct *tsk)
    return 0;
    }

    -static inline void audit_free_context(struct audit_context *context)
    +struct audit_context *audit_alloc_local(gfp_t gfpflags)
    {
    + struct audit_context *context = NULL;
    +
    + context = audit_alloc_context(AUDIT_RECORD_CONTEXT, gfpflags);
    + if (!context) {
    + audit_log_lost("out of memory in audit_alloc_local");
    + goto out;
    + }
    + context->serial = audit_serial();
    + ktime_get_coarse_real_ts64(&context->ctime);
    + context->local = true;
    +out:
    + return context;
    +}
    +EXPORT_SYMBOL(audit_alloc_local);
    +
    +void audit_free_context(struct audit_context *context)
    +{
    + if (!context)
    + return;
    audit_free_module(context);
    audit_free_names(context);
    unroll_tree_refs(context, NULL, 0);
    @@ -989,6 +1011,7 @@ static inline void audit_free_context(struct audit_context *context)
    audit_proctitle_free(context);
    kfree(context);
    }
    +EXPORT_SYMBOL(audit_free_context);

    static int audit_log_pid_context(struct audit_context *context, pid_t pid,
    kuid_t auid, kuid_t uid,
    @@ -2210,7 +2233,7 @@ EXPORT_SYMBOL_GPL(__audit_inode_child);
    int auditsc_get_stamp(struct audit_context *ctx,
    struct timespec64 *t, unsigned int *serial)
    {
    - if (!ctx->in_syscall)
    + if (!ctx->in_syscall && !ctx->local)
    return 0;
    if (!ctx->serial)
    ctx->serial = audit_serial();
    --
    2.29.2
    \
     
     \ /
      Last update: 2021-06-11 02:29    [W:4.335 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site