On 8/14/20 7:46 PM, Steven Rostedt wrote: > On Fri, 14 Aug 2020 19:22:13 +0200 > peter enderborg <peter.enderborg@xxxxxxxx> wrote: > >> On 8/14/20 7:08 PM, Stephen Smalley wrote: >>> On Fri, Aug 14, 2020 at 1:07 PM peter enderborg >>> <peter.enderborg@xxxxxxxx> wrote: >>>> On 8/14/20 6:51 PM, Stephen Smalley wrote: >>>>> On Fri, Aug 14, 2020 at 9:05 AM Thiébaud Weksteen <tweek@xxxxxxxxxx> wrote: >>>>>> On Thu, Aug 13, 2020 at 5:41 PM Stephen Smalley >>>>>> <stephen.smalley.work@xxxxxxxxx> wrote: >>>>>>> An explanation here of how one might go about decoding audited and >>>>>>> tclass would be helpful to users (even better would be a script to do it >>>>>>> for them). Again, I know how to do that but not everyone using >>>>>>> perf/ftrace will. >>>>>> What about something along those lines: >>>>>> >>>>>> The tclass value can be mapped to a class by searching >>>>>> security/selinux/flask.h. The audited value is a bit field of the >>>>>> permissions described in security/selinux/av_permissions.h for the >>>>>> corresponding class. >>>>> Sure, I guess that works. Would be nice if we just included the class >>>>> and permission name(s) in the event itself but I guess you viewed that >>>>> as too heavyweight? >>>> The class name is added in part 2. Im not sure how a proper format for permission >>>> would look like in trace terms. It is a list, right? >>> Yes. See avc_audit_pre_callback() for example code to log the permission names. >> I wrote about that on some of the previous sets. The problem is that trace format is quite fixed. So it is lists are not >> that easy to handle if you want to filter in them. You can have a trace event for each of them. You can also add >> additional trace event "selinux_audied_permission" for each permission. With that you can filter out tclass or permissions. >> >> But the basic thing we would like at the moment is a event that we can debug in user space. > We have a trace_seq p helper, that lets you create strings in > TP_printk(). I should document this more. Thus you can do: > > extern const char *audit_perm_to_name(struct trace_seq *p, u16 class, u32 audited); > #define __perm_to_name(p, class, audited) audit_perm_to_name(p, class, audited) > > TP_printk("tclass=%u audited=%x (%s)", > __entry->tclass, > __entry->audited, > __perm_to_name(__entry->tclass, __entry->audited)) > > > const char *audit_perm_to_name(struct trace_seq *p, u16 tclass, u32 av) > { > const char *ret = trace_seq_buffer_ptr(p); > int i, perm; > > ( some check for tclass integrity here) > > perms = secclass_map[tclass-1].perms; > > i = 0; > perm = 1; > while (i < (sizeof(av) * 8)) { > if ((perm & av) && perms[i]) { > trace_seq_printf(p, " %s", perms[i]); > av &= ~perm; > } > i++; > perm <<= 1; > } > > return ret; > } > > Note, this wont work for perf and trace-cmd as it wouldn't know how to > parse it, but if the tclass perms are stable, you could create a plugin > to libtraceevent that can do the above as well. > > -- Steve Something like: while (i < (sizeof(av) * 8)) { if ((perm & av) && perms[i]) { if (!(perm & avdenied)) trace_seq_printf(p, " %s", perms[i]); else trace_seq_printf(p, " !%s", perms[i]); av &= ~perm; And you get information about denied too.