Message ID | 1723465.15OHkZpn6L@x2 (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Steve, [auto build test ERROR on linus/master] [also build test ERROR on v4.14-rc2 next-20170929] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Steve-Grubb/audit-Record-fanotify-access-control-decisions/20170930-005627 config: i386-randconfig-x0-09300058 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All error/warnings (new ones prefixed by >>): In file included from fs/exec.c:56:0: >> include/linux/audit.h:215:23: error: expected identifier or '(' before numeric constant #define audit_enabled 0 ^ >> include/linux/fsnotify_backend.h:193:9: note: in expansion of macro 'audit_enabled' bool audit_enabled; ^~~~~~~~~~~~~ In file included from include/linux/fsnotify.h:14:0, from fs/exec.c:59: >> include/linux/fsnotify_backend.h:194:3: warning: no semicolon at end of struct or union } fanotify_data; ^ vim +215 include/linux/audit.h 96368701 Paul Moore 2016-01-13 168 96368701 Paul Moore 2016-01-13 169 extern u32 audit_enabled; 96368701 Paul Moore 2016-01-13 170 #else /* CONFIG_AUDIT */ 96368701 Paul Moore 2016-01-13 171 static inline __printf(4, 5) 96368701 Paul Moore 2016-01-13 172 void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, 96368701 Paul Moore 2016-01-13 173 const char *fmt, ...) 96368701 Paul Moore 2016-01-13 174 { } 96368701 Paul Moore 2016-01-13 175 static inline struct audit_buffer *audit_log_start(struct audit_context *ctx, 96368701 Paul Moore 2016-01-13 176 gfp_t gfp_mask, int type) 96368701 Paul Moore 2016-01-13 177 { 96368701 Paul Moore 2016-01-13 178 return NULL; 96368701 Paul Moore 2016-01-13 179 } 96368701 Paul Moore 2016-01-13 180 static inline __printf(2, 3) 96368701 Paul Moore 2016-01-13 181 void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) 96368701 Paul Moore 2016-01-13 182 { } 96368701 Paul Moore 2016-01-13 183 static inline void audit_log_end(struct audit_buffer *ab) 96368701 Paul Moore 2016-01-13 184 { } 96368701 Paul Moore 2016-01-13 185 static inline void audit_log_n_hex(struct audit_buffer *ab, 96368701 Paul Moore 2016-01-13 186 const unsigned char *buf, size_t len) 96368701 Paul Moore 2016-01-13 187 { } 96368701 Paul Moore 2016-01-13 188 static inline void audit_log_n_string(struct audit_buffer *ab, 96368701 Paul Moore 2016-01-13 189 const char *buf, size_t n) 96368701 Paul Moore 2016-01-13 190 { } 96368701 Paul Moore 2016-01-13 191 static inline void audit_log_n_untrustedstring(struct audit_buffer *ab, 96368701 Paul Moore 2016-01-13 192 const char *string, size_t n) 96368701 Paul Moore 2016-01-13 193 { } 96368701 Paul Moore 2016-01-13 194 static inline void audit_log_untrustedstring(struct audit_buffer *ab, 96368701 Paul Moore 2016-01-13 195 const char *string) 96368701 Paul Moore 2016-01-13 196 { } 96368701 Paul Moore 2016-01-13 197 static inline void audit_log_d_path(struct audit_buffer *ab, 96368701 Paul Moore 2016-01-13 198 const char *prefix, 96368701 Paul Moore 2016-01-13 199 const struct path *path) 96368701 Paul Moore 2016-01-13 200 { } 96368701 Paul Moore 2016-01-13 201 static inline void audit_log_key(struct audit_buffer *ab, char *key) 96368701 Paul Moore 2016-01-13 202 { } 96368701 Paul Moore 2016-01-13 203 static inline void audit_log_link_denied(const char *string, 96368701 Paul Moore 2016-01-13 204 const struct path *link) 96368701 Paul Moore 2016-01-13 205 { } 96368701 Paul Moore 2016-01-13 206 static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid) 96368701 Paul Moore 2016-01-13 207 { } 96368701 Paul Moore 2016-01-13 208 static inline int audit_log_task_context(struct audit_buffer *ab) 96368701 Paul Moore 2016-01-13 209 { 96368701 Paul Moore 2016-01-13 210 return 0; 96368701 Paul Moore 2016-01-13 211 } 96368701 Paul Moore 2016-01-13 212 static inline void audit_log_task_info(struct audit_buffer *ab, 96368701 Paul Moore 2016-01-13 213 struct task_struct *tsk) 96368701 Paul Moore 2016-01-13 214 { } 96368701 Paul Moore 2016-01-13 @215 #define audit_enabled 0 96368701 Paul Moore 2016-01-13 216 #endif /* CONFIG_AUDIT */ 96368701 Paul Moore 2016-01-13 217 :::::: The code at line 215 was first introduced by commit :::::: 96368701e1c89057bbf39222e965161c68a85b4b audit: force seccomp event logging to honor the audit_enabled flag :::::: TO: Paul Moore <pmoore@redhat.com> :::::: CC: Paul Moore <paul@paul-moore.com> --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi Steve, [auto build test ERROR on linus/master] [also build test ERROR on v4.14-rc2 next-20170929] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Steve-Grubb/audit-Record-fanotify-access-control-decisions/20170930-005627 config: x86_64-randconfig-b0-09300453 (attached as .config) compiler: gcc-4.4 (Debian 4.4.7-8) 4.4.7 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): In file included from include/linux/fsnotify.h:14, from fs/exec.c:59: >> include/linux/fsnotify_backend.h:193: error: expected identifier or '(' before numeric constant include/linux/fsnotify_backend.h:194: warning: no semicolon at end of struct or union vim +193 include/linux/fsnotify_backend.h 122 123 /* 124 * A group is a "thing" that wants to receive notification about filesystem 125 * events. The mask holds the subset of event types this group cares about. 126 * refcnt on a group is up to the implementor and at any moment if it goes 0 127 * everything will be cleaned up. 128 */ 129 struct fsnotify_group { 130 /* 131 * How the refcnt is used is up to each group. When the refcnt hits 0 132 * fsnotify will clean up all of the resources associated with this group. 133 * As an example, the dnotify group will always have a refcnt=1 and that 134 * will never change. Inotify, on the other hand, has a group per 135 * inotify_init() and the refcnt will hit 0 only when that fd has been 136 * closed. 137 */ 138 atomic_t refcnt; /* things with interest in this group */ 139 140 const struct fsnotify_ops *ops; /* how this group handles things */ 141 142 /* needed to send notification to userspace */ 143 spinlock_t notification_lock; /* protect the notification_list */ 144 struct list_head notification_list; /* list of event_holder this group needs to send to userspace */ 145 wait_queue_head_t notification_waitq; /* read() on the notification file blocks on this waitq */ 146 unsigned int q_len; /* events on the queue */ 147 unsigned int max_events; /* maximum events allowed on the list */ 148 /* 149 * Valid fsnotify group priorities. Events are send in order from highest 150 * priority to lowest priority. We default to the lowest priority. 151 */ 152 #define FS_PRIO_0 0 /* normal notifiers, no permissions */ 153 #define FS_PRIO_1 1 /* fanotify content based access control */ 154 #define FS_PRIO_2 2 /* fanotify pre-content access */ 155 unsigned int priority; 156 bool shutdown; /* group is being shut down, don't queue more events */ 157 158 /* stores all fastpath marks assoc with this group so they can be cleaned on unregister */ 159 struct mutex mark_mutex; /* protect marks_list */ 160 atomic_t num_marks; /* 1 for each mark and 1 for not being 161 * past the point of no return when freeing 162 * a group */ 163 struct list_head marks_list; /* all inode marks for this group */ 164 165 struct fasync_struct *fsn_fa; /* async notification */ 166 167 struct fsnotify_event *overflow_event; /* Event we queue when the 168 * notification list is too 169 * full */ 170 atomic_t user_waits; /* Number of tasks waiting for user 171 * response */ 172 173 /* groups can define private fields here or use the void *private */ 174 union { 175 void *private; 176 #ifdef CONFIG_INOTIFY_USER 177 struct inotify_group_private_data { 178 spinlock_t idr_lock; 179 struct idr idr; 180 struct ucounts *ucounts; 181 } inotify_data; 182 #endif 183 #ifdef CONFIG_FANOTIFY 184 struct fanotify_group_private_data { 185 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS 186 /* allows a group to block waiting for a userspace response */ 187 struct list_head access_list; 188 wait_queue_head_t access_waitq; 189 #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */ 190 int f_flags; 191 unsigned int max_marks; 192 struct user_struct *user; > 193 bool audit_enabled; 194 } fanotify_data; 195 #endif /* CONFIG_FANOTIFY */ 196 }; 197 }; 198 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 2fa99ae..1968d21 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -9,6 +9,7 @@ #include <linux/sched/user.h> #include <linux/types.h> #include <linux/wait.h> +#include <linux/audit.h> #include "fanotify.h" @@ -78,7 +79,7 @@ static int fanotify_get_response(struct fsnotify_group *group, fsnotify_finish_user_wait(iter_info); out: /* userspace responded, convert to something usable */ - switch (event->response) { + switch (event->response & ~FAN_AUDIT) { case FAN_ALLOW: ret = 0; break; @@ -86,6 +87,11 @@ static int fanotify_get_response(struct fsnotify_group *group, default: ret = -EPERM; } + + /* Check if the response should be audited */ + if (event->response & FAN_AUDIT) + audit_fanotify(event->response & ~FAN_AUDIT); + event->response = 0; pr_debug("%s: group=%p event=%p about to return ret=%d\n", __func__, diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 907a481..ea3c458 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -179,7 +179,7 @@ static int process_access_response(struct fsnotify_group *group, * userspace can send a valid response or we will clean it up after the * timeout */ - switch (response) { + switch (response & ~FAN_AUDIT) { case FAN_ALLOW: case FAN_DENY: break; @@ -190,6 +190,9 @@ static int process_access_response(struct fsnotify_group *group, if (fd < 0) return -EINVAL; + if ((response & FAN_AUDIT) && !group->fanotify_data.audit_enabled) + return -EINVAL; + event = dequeue_event(group, fd); if (!event) return -ENOENT; @@ -721,7 +724,11 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) if (!capable(CAP_SYS_ADMIN)) return -EPERM; +#ifdef CONFIG_AUDITSYSCALL + if (flags & ~(FAN_ALL_INIT_FLAGS | FAN_ENABLE_AUDIT)) +#else if (flags & ~FAN_ALL_INIT_FLAGS) +#endif return -EINVAL; if (event_f_flags & ~FANOTIFY_INIT_ALL_EVENT_F_BITS) @@ -805,6 +812,13 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) group->fanotify_data.max_marks = FANOTIFY_DEFAULT_MAX_MARKS; } + if (flags & FAN_ENABLE_AUDIT) { + fd = -EPERM; + if (!capable(CAP_AUDIT_WRITE)) + goto out_destroy_group; + group->fanotify_data.audit_enabled = true; + } + fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags); if (fd < 0) goto out_destroy_group; diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c index dd63aa9..ed311e3 100644 --- a/fs/notify/fdinfo.c +++ b/fs/notify/fdinfo.c @@ -156,6 +156,9 @@ void fanotify_show_fdinfo(struct seq_file *m, struct file *f) if (group->fanotify_data.max_marks == UINT_MAX) flags |= FAN_UNLIMITED_MARKS; + if (group->fanotify_data.audit_enabled) + flags |= FAN_ENABLE_AUDIT; + seq_printf(m, "fanotify flags:%x event-flags:%x\n", flags, group->fanotify_data.f_flags); diff --git a/include/linux/audit.h b/include/linux/audit.h index 2150bdc..9095617 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -360,6 +360,7 @@ extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm, 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_log_kern_module(char *name); +extern void __audit_fanotify(unsigned int response); static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp) { @@ -456,6 +457,12 @@ static inline void audit_log_kern_module(char *name) __audit_log_kern_module(name); } +static inline void audit_fanotify(unsigned int response) +{ + if (!audit_dummy_context()) + __audit_fanotify(response); +} + extern int audit_n_rules; extern int audit_signals; #else /* CONFIG_AUDITSYSCALL */ @@ -572,6 +579,9 @@ static inline void audit_log_kern_module(char *name) { } +static inline void audit_fanotify(unsigned int response) +{ } + static inline void audit_ptrace(struct task_struct *t) { } #define audit_n_rules 0 diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index c6c6931..f4131f2 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -190,6 +190,7 @@ struct fsnotify_group { int f_flags; unsigned int max_marks; struct user_struct *user; + bool audit_enabled; } fanotify_data; #endif /* CONFIG_FANOTIFY */ }; diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h index 0714a66..221f8b7 100644 --- a/include/uapi/linux/audit.h +++ b/include/uapi/linux/audit.h @@ -112,6 +112,7 @@ #define AUDIT_FEATURE_CHANGE 1328 /* audit log listing feature changes */ #define AUDIT_REPLACE 1329 /* Replace auditd if this packet unanswerd */ #define AUDIT_KERN_MODULE 1330 /* Kernel Module events */ +#define AUDIT_FANOTIFY 1331 /* Fanotify access decision */ #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h index 030508d..5dda19a 100644 --- a/include/uapi/linux/fanotify.h +++ b/include/uapi/linux/fanotify.h @@ -35,6 +35,7 @@ #define FAN_UNLIMITED_QUEUE 0x00000010 #define FAN_UNLIMITED_MARKS 0x00000020 +#define FAN_ENABLE_AUDIT 0x00000040 #define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | \ FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE |\ @@ -99,6 +100,8 @@ struct fanotify_response { /* 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 */ + /* No fd set in event */ #define FAN_NOFD -1 diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 3260ba2..e046de8 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -2390,6 +2390,12 @@ void __audit_log_kern_module(char *name) context->type = AUDIT_KERN_MODULE; } +void __audit_fanotify(unsigned int response) +{ + audit_log(current->audit_context, GFP_KERNEL, + AUDIT_FANOTIFY, "resp=%u", response); +} + static void audit_log_task(struct audit_buffer *ab) { kuid_t auid, uid;