[PATCH] audit: allow audit_reusename to check kernel path
Richard Guy Briggs
rgb at redhat.com
Wed Apr 22 13:22:51 UTC 2020
On 2020-04-22 14:28, Yiwen Gu wrote:
> Currently, audit_reusename check file path only by comparing
> userspace pointer "uptr", without checking the situation where
> the file name is different with the same uptr.
Has this been found to actually be a problem? If so, is there a
reproducer to demonstrate this?
The reason it was originally set up like this was to make the check as
efficient as possible, comparing only a pointer, rather than needing to
compare the entire string.
> Add kname into audit_reusename function to check file names
> from the audit_names list.
>
> Signed-off-by: Yiwen Gu <guyiwen at huawei.com>
> ---
> fs/namei.c | 9 +++++----
> include/linux/audit.h | 11 +++++++----
> kernel/auditsc.c | 7 ++++---
> 3 files changed, 16 insertions(+), 11 deletions(-)
>
> diff --git a/fs/namei.c b/fs/namei.c
> index db6565c99825..d5fb4bd12aec 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -128,13 +128,10 @@ struct filename *
> getname_flags(const char __user *filename, int flags, int *empty)
> {
> struct filename *result;
> + struct filename *result_audit;
> char *kname;
> int len;
>
> - result = audit_reusename(filename);
> - if (result)
> - return result;
> -
> result = __getname();
> if (unlikely(!result))
> return ERR_PTR(-ENOMEM);
> @@ -197,6 +194,10 @@ getname_flags(const char __user *filename, int flags, int *empty)
> }
> }
>
> + result_audit = audit_reusename(filename, kname);
> + if (result_audit)
> + return result_audit;
> +
> result->uptr = filename;
> result->aname = NULL;
> audit_getname(result);
> diff --git a/include/linux/audit.h b/include/linux/audit.h
> index f9ceae57ca8d..71fb783f14c4 100644
> --- a/include/linux/audit.h
> +++ b/include/linux/audit.h
> @@ -266,7 +266,8 @@ extern void __audit_free(struct task_struct *task);
> 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);
> -extern struct filename *__audit_reusename(const __user char *uptr);
> +extern struct filename *__audit_reusename(const __user char *uptr,
> + const char *kname);
> extern void __audit_getname(struct filename *name);
>
> extern void __audit_inode(struct filename *name, const struct dentry *dentry,
> @@ -316,10 +317,11 @@ static inline void audit_syscall_exit(void *pt_regs)
> __audit_syscall_exit(success, return_code);
> }
> }
> -static inline struct filename *audit_reusename(const __user char *name)
> +static inline struct filename *audit_reusename(const __user char *name,
> + const char *kname)
> {
> if (unlikely(!audit_dummy_context()))
> - return __audit_reusename(name);
> + return __audit_reusename(name, kname);
> return NULL;
> }
> static inline void audit_getname(struct filename *name)
> @@ -539,7 +541,8 @@ static inline struct audit_context *audit_context(void)
> {
> return NULL;
> }
> -static inline struct filename *audit_reusename(const __user char *name)
> +static inline struct filename *audit_reusename(const __user char *name,
> + const char *kname)
> {
> return NULL;
> }
> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> index 4effe01ebbe2..62ffc02abb98 100644
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -1843,13 +1843,14 @@ static struct audit_names *audit_alloc_name(struct audit_context *context,
> /**
> * __audit_reusename - fill out filename with info from existing entry
> * @uptr: userland ptr to pathname
> + * @kname: kernel pathname string
> *
> * Search the audit_names list for the current audit context. If there is an
> - * existing entry with a matching "uptr" then return the filename
> + * existing entry with matching "uptr" and "kname" then return the filename
> * associated with that audit_name. If not, return NULL.
> */
> struct filename *
> -__audit_reusename(const __user char *uptr)
> +__audit_reusename(const __user char *uptr, const char *kname)
> {
> struct audit_context *context = audit_context();
> struct audit_names *n;
> @@ -1857,7 +1858,7 @@ __audit_reusename(const __user char *uptr)
> list_for_each_entry(n, &context->names_list, list) {
> if (!n->name)
> continue;
> - if (n->name->uptr == uptr) {
> + if (n->name->uptr == uptr && !strcmp(kname, n->name->name)) {
> n->name->refcnt++;
> return n->name;
> }
> --
> 2.17.1
>
>
>
> --
> Linux-audit mailing list
> Linux-audit at redhat.com
> https://www.redhat.com/mailman/listinfo/linux-audit
- RGB
--
Richard Guy Briggs <rgb at redhat.com>
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635
More information about the Linux-audit
mailing list