From nobody Mon Apr 13 10:19:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8AD2FC19F2D for ; Tue, 9 Aug 2022 17:23:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245206AbiHIRX2 (ORCPT ); Tue, 9 Aug 2022 13:23:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60182 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242624AbiHIRXV (ORCPT ); Tue, 9 Aug 2022 13:23:21 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 636182529E for ; Tue, 9 Aug 2022 10:23:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1660065796; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=u1KS97z9xRvQFlp9o7uta5H/iq3B/8fcs7J3SYSbtRw=; b=XZcrKbPbrZEcIQ87w99fDjcRdp3tgwwmPfz6mNelozvgUdJdYcJ11xfWE1xd5kPSukDrqw PNM7JqlAvG1wDVYMCmT9n6Z+Kfszo3ENAGRIQjRu8tRo1PlY33iKY+q5950NDhaVgslEys DR8TN5jHZ8bNjhyse3MBAjyRDFmCaeQ= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-246-1LJF1l9JOOaMAnlCsoxtVw-1; Tue, 09 Aug 2022 13:23:13 -0400 X-MC-Unique: 1LJF1l9JOOaMAnlCsoxtVw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 85BFD976065; Tue, 9 Aug 2022 17:23:12 +0000 (UTC) Received: from madcap2.tricolour.com (unknown [10.22.48.5]) by smtp.corp.redhat.com (Postfix) with ESMTP id 46CBF94585; Tue, 9 Aug 2022 17:23:11 +0000 (UTC) From: Richard Guy Briggs To: Linux-Audit Mailing List , LKML , linux-fsdevel@vger.kernel.org Cc: Paul Moore , Eric Paris , Steve Grubb , Richard Guy Briggs , Jan Kara , Amir Goldstein Subject: [PATCH v4 1/4] fanotify: Ensure consistent variable type for response Date: Tue, 9 Aug 2022 13:22:52 -0400 Message-Id: <42afb21b7b6adeee70293116e603bd4bc4a8f9a3.1659996830.git.rgb@redhat.com> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The user space API for the response variable is __u32. This patch makes sure that the whole path through the kernel uses u32 so that there is no sign extension or truncation of the user space response. Suggested-by: Steve Grubb Link: https://lore.kernel.org/r/12617626.uLZWGnKmhe@x2 Signed-off-by: Richard Guy Briggs --- fs/notify/fanotify/fanotify.h | 2 +- fs/notify/fanotify/fanotify_user.c | 6 +++--- include/linux/audit.h | 6 +++--- kernel/auditsc.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index 80e0ec95b113..abfa3712c185 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h @@ -425,7 +425,7 @@ FANOTIFY_PE(struct fanotify_event *event) struct fanotify_perm_event { struct fanotify_event fae; struct path path; - unsigned short response; /* userspace answer to the event */ + u32 response; /* userspace answer to the event */ unsigned short state; /* state of the event */ int fd; /* fd we passed to userspace for this event */ }; diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanoti= fy_user.c index c2255b440df9..ff67ca0d25cc 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -289,7 +289,7 @@ static int create_fd(struct fsnotify_group *group, stru= ct path *path, */ static void finish_permission_event(struct fsnotify_group *group, struct fanotify_perm_event *event, - unsigned int response) + u32 response) __releases(&group->notification_lock) { bool destroy =3D false; @@ -310,9 +310,9 @@ static int process_access_response(struct fsnotify_grou= p *group, { struct fanotify_perm_event *event; int fd =3D response_struct->fd; - int response =3D response_struct->response; + u32 response =3D response_struct->response; =20 - pr_debug("%s: group=3D%p fd=3D%d response=3D%d\n", __func__, group, + pr_debug("%s: group=3D%p fd=3D%d response=3D%u\n", __func__, group, fd, response); /* * make sure the response is valid, if invalid we do nothing and either diff --git a/include/linux/audit.h b/include/linux/audit.h index 00f7a80f1a3e..3ea198a2cd59 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -417,7 +417,7 @@ extern void __audit_log_capset(const struct cred *new, = const struct cred *old); extern void __audit_mmap_fd(int fd, int flags); extern void __audit_openat2_how(struct open_how *how); extern void __audit_log_kern_module(char *name); -extern void __audit_fanotify(unsigned int response); +extern void __audit_fanotify(u32 response); extern void __audit_tk_injoffset(struct timespec64 offset); extern void __audit_ntp_log(const struct audit_ntp_data *ad); extern void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentri= es, @@ -524,7 +524,7 @@ static inline void audit_log_kern_module(char *name) __audit_log_kern_module(name); } =20 -static inline void audit_fanotify(unsigned int response) +static inline void audit_fanotify(u32 response) { if (!audit_dummy_context()) __audit_fanotify(response); @@ -684,7 +684,7 @@ static inline void audit_log_kern_module(char *name) { } =20 -static inline void audit_fanotify(unsigned int response) +static inline void audit_fanotify(u32 response) { } =20 static inline void audit_tk_injoffset(struct timespec64 offset) diff --git a/kernel/auditsc.c b/kernel/auditsc.c index f3a2abd6d1a1..433418d73584 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -2899,7 +2899,7 @@ void __audit_log_kern_module(char *name) context->type =3D AUDIT_KERN_MODULE; } =20 -void __audit_fanotify(unsigned int response) +void __audit_fanotify(u32 response) { audit_log(audit_context(), GFP_KERNEL, AUDIT_FANOTIFY, "resp=3D%u", response); --=20 2.27.0 From nobody Mon Apr 13 10:19:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5ADA7C19F2D for ; Tue, 9 Aug 2022 17:23:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245271AbiHIRXi (ORCPT ); Tue, 9 Aug 2022 13:23:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60230 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245180AbiHIRXV (ORCPT ); Tue, 9 Aug 2022 13:23:21 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 58165252A1 for ; Tue, 9 Aug 2022 10:23:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1660065797; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1eNVlNSl7mS7dQb4vrymRAcWuVHCTVFJMbOs2Jsc4cw=; b=VJn0YyPr+y0iDoEG8bLF6/47GapuILu0A2Vtc4Ia0NnD9LO4qD+LO9wVdKCbV0PQEXqKyg ESiEfRGgpRcn28k05uuE1Myc2sG/Yigf2xSYPjOjaDPZ+tKYsbbB5S0e4bKPJRALbNbHSX S0PP3nsdaEfsTQrpL5AG9o9MsXDRUWc= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-387-lXf5mROQOgyRUSJBijv-aA-1; Tue, 09 Aug 2022 13:23:14 -0400 X-MC-Unique: lXf5mROQOgyRUSJBijv-aA-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 16A7519705A9; Tue, 9 Aug 2022 17:23:14 +0000 (UTC) Received: from madcap2.tricolour.com (unknown [10.22.48.5]) by smtp.corp.redhat.com (Postfix) with ESMTP id B9F3B9458A; Tue, 9 Aug 2022 17:23:12 +0000 (UTC) From: Richard Guy Briggs To: Linux-Audit Mailing List , LKML , linux-fsdevel@vger.kernel.org Cc: Paul Moore , Eric Paris , Steve Grubb , Richard Guy Briggs , Jan Kara , Amir Goldstein Subject: [PATCH v4 2/4] fanotify: define struct members to hold response decision context Date: Tue, 9 Aug 2022 13:22:53 -0400 Message-Id: <8767f3a0d43d6a994584b86c03eb659a662cc416.1659996830.git.rgb@redhat.com> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This patch adds a flag, FAN_INFO and an extensible buffer to provide additional information about response decisions. The buffer contains one or more headers defining the information type and the length of the following information. The patch defines one additional information type, FAN_RESPONSE_INFO_AUDIT_RULE, an audit rule number. This will allow for the creation of other information types in the future if other users of the API identify different needs. Suggested-by: Steve Grubb Link: https://lore.kernel.org/r/2745105.e9J7NaK4W3@x2 Suggested-by: Jan Kara Link: https://lore.kernel.org/r/20201001101219.GE17860@quack2.suse.cz Signed-off-by: Richard Guy Briggs Reported-by: kernel test robot --- fs/notify/fanotify/fanotify.c | 10 ++- fs/notify/fanotify/fanotify.h | 2 + fs/notify/fanotify/fanotify_user.c | 104 +++++++++++++++++++++++------ include/linux/fanotify.h | 5 ++ include/uapi/linux/fanotify.h | 27 +++++++- 5 files changed, 123 insertions(+), 25 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 4f897e109547..0f36062521f4 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -262,13 +262,16 @@ static int fanotify_get_response(struct fsnotify_grou= p *group, } =20 /* userspace responded, convert to something usable */ - switch (event->response & ~FAN_AUDIT) { + switch (event->response & FANOTIFY_RESPONSE_ACCESS) { case FAN_ALLOW: ret =3D 0; break; case FAN_DENY: - default: ret =3D -EPERM; + break; + default: + ret =3D -EINVAL; + break; } =20 /* Check if the response should be audited */ @@ -560,6 +563,8 @@ static struct fanotify_event *fanotify_alloc_perm_event= (const struct path *path, =20 pevent->fae.type =3D FANOTIFY_EVENT_TYPE_PATH_PERM; pevent->response =3D 0; + pevent->info_len =3D 0; + pevent->info_buf =3D NULL; pevent->state =3D FAN_EVENT_INIT; pevent->path =3D *path; path_get(path); @@ -996,6 +1001,7 @@ static void fanotify_free_path_event(struct fanotify_e= vent *event) static void fanotify_free_perm_event(struct fanotify_event *event) { path_put(fanotify_event_path(event)); + kfree(FANOTIFY_PERM(event)->info_buf); kmem_cache_free(fanotify_perm_event_cachep, FANOTIFY_PERM(event)); } =20 diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index abfa3712c185..14c30e173632 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h @@ -428,6 +428,8 @@ struct fanotify_perm_event { u32 response; /* userspace answer to the event */ unsigned short state; /* state of the event */ int fd; /* fd we passed to userspace for this event */ + size_t info_len; + char *info_buf; }; =20 static inline struct fanotify_perm_event * diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanoti= fy_user.c index ff67ca0d25cc..a4ae953f0e62 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -289,13 +289,18 @@ static int create_fd(struct fsnotify_group *group, st= ruct path *path, */ static void finish_permission_event(struct fsnotify_group *group, struct fanotify_perm_event *event, - u32 response) + struct fanotify_response *response, + size_t info_len, char *info_buf) __releases(&group->notification_lock) { bool destroy =3D false; =20 assert_spin_locked(&group->notification_lock); - event->response =3D response; + event->response =3D response->response & ~FAN_INFO; + if (response->response & FAN_INFO) { + event->info_len =3D info_len; + event->info_buf =3D info_buf; + } if (event->state =3D=3D FAN_EVENT_CANCELED) destroy =3D true; else @@ -306,33 +311,71 @@ static void finish_permission_event(struct fsnotify_g= roup *group, } =20 static int process_access_response(struct fsnotify_group *group, - struct fanotify_response *response_struct) + struct fanotify_response *response_struct, + const char __user *buf, + size_t count) { struct fanotify_perm_event *event; int fd =3D response_struct->fd; u32 response =3D response_struct->response; + struct fanotify_response_info_header info_hdr; + char *info_buf =3D NULL; =20 - pr_debug("%s: group=3D%p fd=3D%d response=3D%u\n", __func__, group, - fd, response); + pr_debug("%s: group=3D%p fd=3D%d response=3D%u buf=3D%p size=3D%lu\n", __= func__, + group, fd, response, info_buf, count); /* * make sure the response is valid, if invalid we do nothing and either * userspace can send a valid response or we will clean it up after the * timeout */ - switch (response & ~FAN_AUDIT) { + if (response & ~FANOTIFY_RESPONSE_VALID_MASK) + return -EINVAL; + switch (response & FANOTIFY_RESPONSE_ACCESS) { case FAN_ALLOW: case FAN_DENY: break; default: return -EINVAL; } - - if (fd < 0) - return -EINVAL; - if ((response & FAN_AUDIT) && !FAN_GROUP_FLAG(group, FAN_ENABLE_AUDIT)) return -EINVAL; + if (fd < 0) + return -EINVAL; + if (response & FAN_INFO) { + size_t c =3D count; + const char __user *ib =3D buf; =20 + if (c <=3D 0) + return -EINVAL; + while (c >=3D sizeof(info_hdr)) { + if (copy_from_user(&info_hdr, ib, sizeof(info_hdr))) + return -EFAULT; + if (info_hdr.pad !=3D 0) + return -EINVAL; + if (c < info_hdr.len) + return -EINVAL; + switch (info_hdr.type) { + case FAN_RESPONSE_INFO_AUDIT_RULE: + break; + case FAN_RESPONSE_INFO_NONE: + default: + return -EINVAL; + } + c -=3D info_hdr.len; + ib +=3D info_hdr.len; + } + if (c !=3D 0) + return -EINVAL; + /* Simplistic check for now */ + if (count !=3D sizeof(struct fanotify_response_info_audit_rule)) + return -EINVAL; + info_buf =3D kmalloc(sizeof(struct fanotify_response_info_audit_rule), + GFP_KERNEL); + if (!info_buf) + return -ENOMEM; + if (copy_from_user(info_buf, buf, count)) + return -EFAULT; + } spin_lock(&group->notification_lock); list_for_each_entry(event, &group->fanotify_data.access_list, fae.fse.list) { @@ -340,7 +383,9 @@ static int process_access_response(struct fsnotify_grou= p *group, continue; =20 list_del_init(&event->fae.fse.list); - finish_permission_event(group, event, response); + /* finish_permission_event() eats info_buf */ + finish_permission_event(group, event, response_struct, + count, info_buf); wake_up(&group->fanotify_data.access_waitq); return 0; } @@ -802,9 +847,14 @@ static ssize_t fanotify_read(struct file *file, char _= _user *buf, fsnotify_destroy_event(group, &event->fse); } else { if (ret <=3D 0) { + struct fanotify_response response =3D { + .fd =3D FAN_NOFD, + .response =3D FAN_DENY }; + spin_lock(&group->notification_lock); finish_permission_event(group, - FANOTIFY_PERM(event), FAN_DENY); + FANOTIFY_PERM(event), &response, + 0, NULL); wake_up(&group->fanotify_data.access_waitq); } else { spin_lock(&group->notification_lock); @@ -827,26 +877,33 @@ static ssize_t fanotify_read(struct file *file, char = __user *buf, =20 static ssize_t fanotify_write(struct file *file, const char __user *buf, s= ize_t count, loff_t *pos) { - struct fanotify_response response =3D { .fd =3D -1, .response =3D -1 }; + struct fanotify_response response; struct fsnotify_group *group; int ret; + const char __user *info_buf =3D buf + sizeof(struct fanotify_response); + size_t c; =20 if (!IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS)) return -EINVAL; =20 group =3D file->private_data; =20 - if (count < sizeof(response)) - return -EINVAL; - - count =3D sizeof(response); - pr_debug("%s: group=3D%p count=3D%zu\n", __func__, group, count); =20 - if (copy_from_user(&response, buf, count)) + if (count < sizeof(response)) + return -EINVAL; + if (copy_from_user(&response, buf, sizeof(response))) return -EFAULT; =20 - ret =3D process_access_response(group, &response); + c =3D count - sizeof(response); + if (response.response & FAN_INFO) { + if (c < sizeof(struct fanotify_response_info_header)) + return -EINVAL; + } else { + if (c !=3D 0) + return -EINVAL; + } + ret =3D process_access_response(group, &response, info_buf, c); if (ret < 0) count =3D ret; =20 @@ -857,6 +914,9 @@ static int fanotify_release(struct inode *ignored, stru= ct file *file) { struct fsnotify_group *group =3D file->private_data; struct fsnotify_event *fsn_event; + struct fanotify_response response =3D { + .fd =3D FAN_NOFD, + .response =3D FAN_ALLOW }; =20 /* * Stop new events from arriving in the notification queue. since @@ -876,7 +936,7 @@ static int fanotify_release(struct inode *ignored, stru= ct file *file) event =3D list_first_entry(&group->fanotify_data.access_list, struct fanotify_perm_event, fae.fse.list); list_del_init(&event->fae.fse.list); - finish_permission_event(group, event, FAN_ALLOW); + finish_permission_event(group, event, &response, 0, NULL); spin_lock(&group->notification_lock); } =20 @@ -893,7 +953,7 @@ static int fanotify_release(struct inode *ignored, stru= ct file *file) fsnotify_destroy_event(group, fsn_event); } else { finish_permission_event(group, FANOTIFY_PERM(event), - FAN_ALLOW); + &response, 0, NULL); } spin_lock(&group->notification_lock); } diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h index edc28555814c..ce9f97eb69f2 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h @@ -114,6 +114,11 @@ #define ALL_FANOTIFY_EVENT_BITS (FANOTIFY_OUTGOING_EVENTS | \ FANOTIFY_EVENT_FLAGS) =20 +/* This mask is to check for invalid bits of a user space permission respo= nse */ +#define FANOTIFY_RESPONSE_ACCESS (FAN_ALLOW | FAN_DENY) +#define FANOTIFY_RESPONSE_FLAGS (FAN_AUDIT | FAN_INFO) +#define FANOTIFY_RESPONSE_VALID_MASK (FANOTIFY_RESPONSE_ACCESS | FANOTIFY_= RESPONSE_FLAGS) + /* Do not use these old uapi constants internally */ #undef FAN_ALL_CLASS_BITS #undef FAN_ALL_INIT_FLAGS diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h index f1f89132d60e..4d08823a5698 100644 --- a/include/uapi/linux/fanotify.h +++ b/include/uapi/linux/fanotify.h @@ -180,15 +180,40 @@ struct fanotify_event_info_error { __u32 error_count; }; =20 +/* + * User space may need to record additional information about its decision. + * The extra information type records what kind of information is included. + * The default is none. We also define an extra information buffer whose + * size is determined by the extra information type. + * + * If the context type is Rule, then the context following is the rule num= ber + * that triggered the user space decision. + */ + +#define FAN_RESPONSE_INFO_NONE 0 +#define FAN_RESPONSE_INFO_AUDIT_RULE 1 + struct fanotify_response { __s32 fd; __u32 response; }; =20 +struct fanotify_response_info_header { + __u8 type; + __u8 pad; + __u16 len; +}; + +struct fanotify_response_info_audit_rule { + struct fanotify_response_info_header hdr; + __u32 audit_rule; +}; + /* Legit userspace responses to a _PERM event */ #define FAN_ALLOW 0x01 #define FAN_DENY 0x02 -#define FAN_AUDIT 0x10 /* Bit mask to create audit record for result */ +#define FAN_AUDIT 0x10 /* Bitmask to create audit record for result */ +#define FAN_INFO 0x20 /* Bitmask to indicate additional information */ =20 /* No fd set in event */ #define FAN_NOFD -1 --=20 2.27.0 From nobody Mon Apr 13 10:19:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 569E3C25B0D for ; Tue, 9 Aug 2022 17:23:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245241AbiHIRXc (ORCPT ); Tue, 9 Aug 2022 13:23:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60192 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245051AbiHIRXV (ORCPT ); Tue, 9 Aug 2022 13:23:21 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 5A4B22529C for ; Tue, 9 Aug 2022 10:23:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1660065799; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6atus4XK2PeR0rSaAyXK58PrEh9v2DgHX9trvgun/Tk=; b=PsB0oD+QCTT3mUBdjc0dZCsgQxrUdyM16VNKdxAyrD7dQpWCSOlIjTI/HdpIcaugZoURyF mOoRjWEMJpTjYm5AgCi/FldZiQRk1gue3HVq7fsZKQQrcslLsdeaQOuWDuUBRkNAw5HcJF k/qpjnDV3ErecYhqxAwo2z/krilubrU= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-664-f4s3AowUNGmSsnDK0zHK5Q-1; Tue, 09 Aug 2022 13:23:16 -0400 X-MC-Unique: f4s3AowUNGmSsnDK0zHK5Q-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 912811019C8D; Tue, 9 Aug 2022 17:23:15 +0000 (UTC) Received: from madcap2.tricolour.com (unknown [10.22.48.5]) by smtp.corp.redhat.com (Postfix) with ESMTP id 49DEB9457F; Tue, 9 Aug 2022 17:23:14 +0000 (UTC) From: Richard Guy Briggs To: Linux-Audit Mailing List , LKML , linux-fsdevel@vger.kernel.org Cc: Paul Moore , Eric Paris , Steve Grubb , Richard Guy Briggs , Jan Kara , Amir Goldstein Subject: [PATCH v4 3/4] fanotify,audit: Allow audit to use the full permission event response Date: Tue, 9 Aug 2022 13:22:54 -0400 Message-Id: In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This patch passes the full value so that the audit function can use all of it. The audit function was updated to log the additional information in the AUDIT_FANOTIFY record. The following is an example of the new record format: type=3DFANOTIFY msg=3Daudit(1600385147.372:590): resp=3D2 fan_type=3D1 fan_= info=3D17 Suggested-by: Steve Grubb Link: https://lore.kernel.org/r/3075502.aeNJFYEL58@x2 Signed-off-by: Richard Guy Briggs Reported-by: kernel test robot --- fs/notify/fanotify/fanotify.c | 3 ++- include/linux/audit.h | 9 +++++---- kernel/auditsc.c | 31 ++++++++++++++++++++++++++++--- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 0f36062521f4..36c3ed1af085 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -276,7 +276,8 @@ static int fanotify_get_response(struct fsnotify_group = *group, =20 /* Check if the response should be audited */ if (event->response & FAN_AUDIT) - audit_fanotify(event->response & ~FAN_AUDIT); + audit_fanotify(event->response & ~FAN_AUDIT, + event->info_len, event->info_buf); =20 pr_debug("%s: group=3D%p event=3D%p about to return ret=3D%d\n", __func__, group, event, ret); diff --git a/include/linux/audit.h b/include/linux/audit.h index 3ea198a2cd59..c69efdba12ca 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -14,6 +14,7 @@ #include #include #include +#include =20 #define AUDIT_INO_UNSET ((unsigned long)-1) #define AUDIT_DEV_UNSET ((dev_t)-1) @@ -417,7 +418,7 @@ extern void __audit_log_capset(const struct cred *new, = const struct cred *old); extern void __audit_mmap_fd(int fd, int flags); extern void __audit_openat2_how(struct open_how *how); extern void __audit_log_kern_module(char *name); -extern void __audit_fanotify(u32 response); +extern void __audit_fanotify(u32 response, size_t len, char *buf); extern void __audit_tk_injoffset(struct timespec64 offset); extern void __audit_ntp_log(const struct audit_ntp_data *ad); extern void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentri= es, @@ -524,10 +525,10 @@ static inline void audit_log_kern_module(char *name) __audit_log_kern_module(name); } =20 -static inline void audit_fanotify(u32 response) +static inline void audit_fanotify(u32 response, size_t len, char *buf) { if (!audit_dummy_context()) - __audit_fanotify(response); + __audit_fanotify(response, len, buf); } =20 static inline void audit_tk_injoffset(struct timespec64 offset) @@ -684,7 +685,7 @@ static inline void audit_log_kern_module(char *name) { } =20 -static inline void audit_fanotify(u32 response) +static inline void audit_fanotify(u32 response, size_t len, char *buf) { } =20 static inline void audit_tk_injoffset(struct timespec64 offset) diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 433418d73584..f000fec52360 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -64,6 +64,7 @@ #include #include #include // struct open_how +#include =20 #include "audit.h" =20 @@ -2899,10 +2900,34 @@ void __audit_log_kern_module(char *name) context->type =3D AUDIT_KERN_MODULE; } =20 -void __audit_fanotify(u32 response) +void __audit_fanotify(u32 response, size_t len, char *buf) { - audit_log(audit_context(), GFP_KERNEL, - AUDIT_FANOTIFY, "resp=3D%u", response); + struct fanotify_response_info_audit_rule *friar; + size_t c =3D len; + char *ib =3D buf; + + if (!(len && buf)) { + audit_log(audit_context(), GFP_KERNEL, AUDIT_FANOTIFY, + "resp=3D%u fan_type=3D0 fan_info=3D?", response); + return; + } + while (c >=3D sizeof(struct fanotify_response_info_header)) { + friar =3D (struct fanotify_response_info_audit_rule *)buf; + switch (friar->hdr.type) { + case FAN_RESPONSE_INFO_AUDIT_RULE: + if (friar->hdr.len < sizeof(*friar)) { + audit_log(audit_context(), GFP_KERNEL, AUDIT_FANOTIFY, + "resp=3D%u fan_type=3D%u fan_info=3D(incomplete)", + response, friar->hdr.type); + return; + } + audit_log(audit_context(), GFP_KERNEL, AUDIT_FANOTIFY, + "resp=3D%u fan_type=3D%u fan_info=3D%u", + response, friar->hdr.type, friar->audit_rule); + } + c -=3D friar->hdr.len; + ib +=3D friar->hdr.len; + } } =20 void __audit_tk_injoffset(struct timespec64 offset) --=20 2.27.0 From nobody Mon Apr 13 10:19:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 642ACC25B0C for ; Tue, 9 Aug 2022 17:23:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245051AbiHIRXy (ORCPT ); Tue, 9 Aug 2022 13:23:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60228 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245223AbiHIRXa (ORCPT ); Tue, 9 Aug 2022 13:23:30 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 12BD8252A3 for ; Tue, 9 Aug 2022 10:23:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1660065801; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qPbho2+c8dAkqKWuFGRj6nlv+UYf9Vv/Uh5Ehbs5Rkg=; b=grjxGmX0AEUPfeKVhVbxpJzzxYigzNjhq4kr4amc8iN+ub1dUOU84xcaIO8/hLyvaxoR1w h+jOfqnoCjFc5BfU13m8cGyFTogApc19Mv5DdfeCeDqWv+xKaUzLtcoxXFI3qcz1K/s4KT vXpXBgLfDVl0AUtEAlMPTRiaDBFGPa8= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-319-8YK0xgFjP5S1HHOFkibRIw-1; Tue, 09 Aug 2022 13:23:17 -0400 X-MC-Unique: 8YK0xgFjP5S1HHOFkibRIw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 184C63800C44; Tue, 9 Aug 2022 17:23:17 +0000 (UTC) Received: from madcap2.tricolour.com (unknown [10.22.48.5]) by smtp.corp.redhat.com (Postfix) with ESMTP id C4523945D2; Tue, 9 Aug 2022 17:23:15 +0000 (UTC) From: Richard Guy Briggs To: Linux-Audit Mailing List , LKML , linux-fsdevel@vger.kernel.org Cc: Paul Moore , Eric Paris , Steve Grubb , Richard Guy Briggs , Jan Kara , Amir Goldstein Subject: [PATCH v4 4/4] fanotify,audit: deliver fan_info as a hex-encoded string Date: Tue, 9 Aug 2022 13:22:55 -0400 Message-Id: <2d8159cec4392029dabfc39b55ac5fbd0faa9fbd.1659996830.git.rgb@redhat.com> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Currently the only type of fanotify info that is defined is an audit rule number, but convert it to hex encoding to future-proof the field. Sample record: type=3DFANOTIFY msg=3Daudit(1659730979.839:284): resp=3D1 fan_type=3D0 fa= n_info=3D3F Suggested-by: Paul Moore Signed-off-by: Richard Guy Briggs --- kernel/auditsc.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/kernel/auditsc.c b/kernel/auditsc.c index f000fec52360..0f747015c577 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -2908,22 +2908,36 @@ void __audit_fanotify(u32 response, size_t len, cha= r *buf) =20 if (!(len && buf)) { audit_log(audit_context(), GFP_KERNEL, AUDIT_FANOTIFY, - "resp=3D%u fan_type=3D0 fan_info=3D?", response); + "resp=3D%u fan_type=3D0 fan_info=3D3F", response); /* "?" */ return; } while (c >=3D sizeof(struct fanotify_response_info_header)) { + struct audit_context *ctx =3D audit_context(); + struct audit_buffer *ab; + friar =3D (struct fanotify_response_info_audit_rule *)buf; switch (friar->hdr.type) { case FAN_RESPONSE_INFO_AUDIT_RULE: if (friar->hdr.len < sizeof(*friar)) { - audit_log(audit_context(), GFP_KERNEL, AUDIT_FANOTIFY, - "resp=3D%u fan_type=3D%u fan_info=3D(incomplete)", - response, friar->hdr.type); + ab =3D audit_log_start(ctx, GFP_KERNEL, AUDIT_FANOTIFY); + if (ab) { + audit_log_format(ab, "resp=3D%u fan_type=3D%u fan_info=3D", + response, friar->hdr.type); +#define INCOMPLETE "(incomplete)" + audit_log_n_hex(ab, INCOMPLETE, sizeof(INCOMPLETE)); + audit_log_end(ab); + } return; } - audit_log(audit_context(), GFP_KERNEL, AUDIT_FANOTIFY, - "resp=3D%u fan_type=3D%u fan_info=3D%u", - response, friar->hdr.type, friar->audit_rule); + ab =3D audit_log_start(ctx, GFP_KERNEL, AUDIT_FANOTIFY); + if (ab) { + audit_log_format(ab, "resp=3D%u fan_type=3D%u fan_info=3D", + response, friar->hdr.type); + audit_log_n_hex(ab, (char *)&friar->audit_rule, + sizeof(friar->audit_rule)); + audit_log_end(ab); + + } } c -=3D friar->hdr.len; ib +=3D friar->hdr.len; --=20 2.27.0