Commit Graph

17 Commits

Author SHA1 Message Date
CKI Backport Bot 51dcd65ccb tracing: Free buffers when a used dynamic event is removed
JIRA: https://issues.redhat.com/browse/RHEL-63666
CVE: CVE-2022-49006

commit 4313e5a613049dfc1819a6dfb5f94cf2caff9452
Author: Steven Rostedt (Google) <rostedt@goodmis.org>
Date:   Wed Nov 23 17:14:34 2022 -0500

    tracing: Free buffers when a used dynamic event is removed

    After 65536 dynamic events have been added and removed, the "type" field
    of the event then uses the first type number that is available (not
    currently used by other events). A type number is the identifier of the
    binary blobs in the tracing ring buffer (known as events) to map them to
    logic that can parse the binary blob.

    The issue is that if a dynamic event (like a kprobe event) is traced and
    is in the ring buffer, and then that event is removed (because it is
    dynamic, which means it can be created and destroyed), if another dynamic
    event is created that has the same number that new event's logic on
    parsing the binary blob will be used.

    To show how this can be an issue, the following can crash the kernel:

     # cd /sys/kernel/tracing
     # for i in `seq 65536`; do
         echo 'p:kprobes/foo do_sys_openat2 $arg1:u32' > kprobe_events
     # done

    For every iteration of the above, the writing to the kprobe_events will
    remove the old event and create a new one (with the same format) and
    increase the type number to the next available on until the type number
    reaches over 65535 which is the max number for the 16 bit type. After it
    reaches that number, the logic to allocate a new number simply looks for
    the next available number. When an dynamic event is removed, that number
    is then available to be reused by the next dynamic event created. That is,
    once the above reaches the max number, the number assigned to the event in
    that loop will remain the same.

    Now that means deleting one dynamic event and created another will reuse
    the previous events type number. This is where bad things can happen.
    After the above loop finishes, the kprobes/foo event which reads the
    do_sys_openat2 function call's first parameter as an integer.

     # echo 1 > kprobes/foo/enable
     # cat /etc/passwd > /dev/null
     # cat trace
                 cat-2211    [005] ....  2007.849603: foo: (do_sys_openat2+0x0/0x130) arg1=4294967196
                 cat-2211    [005] ....  2007.849620: foo: (do_sys_openat2+0x0/0x130) arg1=4294967196
                 cat-2211    [005] ....  2007.849838: foo: (do_sys_openat2+0x0/0x130) arg1=4294967196
                 cat-2211    [005] ....  2007.849880: foo: (do_sys_openat2+0x0/0x130) arg1=4294967196
     # echo 0 > kprobes/foo/enable

    Now if we delete the kprobe and create a new one that reads a string:

     # echo 'p:kprobes/foo do_sys_openat2 +0($arg2):string' > kprobe_events

    And now we can the trace:

     # cat trace
            sendmail-1942    [002] .....   530.136320: foo: (do_sys_openat2+0x0/0x240) arg1=             cat-2046    [004] .....   530.930817: foo: (do_sys_openat2+0x0/0x240) arg1="������������������������������������������������������������������������������������������������"
                 cat-2046    [004] .....   530.930961: foo: (do_sys_openat2+0x0/0x240) arg1="������������������������������������������������������������������������������������������������"
                 cat-2046    [004] .....   530.934278: foo: (do_sys_openat2+0x0/0x240) arg1="������������������������������������������������������������������������������������������������"
                 cat-2046    [004] .....   530.934563: foo: (do_sys_openat2+0x0/0x240) arg1="������������������������������������������������������������������������������������������������"
                bash-1515    [007] .....   534.299093: foo: (do_sys_openat2+0x0/0x240) arg1="kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk���������@��4Z����;Y�����U

    And dmesg has:

    ==================================================================
    BUG: KASAN: use-after-free in string+0xd4/0x1c0
    Read of size 1 at addr ffff88805fdbbfa0 by task cat/2049

     CPU: 0 PID: 2049 Comm: cat Not tainted 6.1.0-rc6-test+ #641
     Hardware name: Hewlett-Packard HP Compaq Pro 6300 SFF/339A, BIOS K01 v03.03 07/14/2016
     Call Trace:
      <TASK>
      dump_stack_lvl+0x5b/0x77
      print_report+0x17f/0x47b
      kasan_report+0xad/0x130
      string+0xd4/0x1c0
      vsnprintf+0x500/0x840
      seq_buf_vprintf+0x62/0xc0
      trace_seq_printf+0x10e/0x1e0
      print_type_string+0x90/0xa0
      print_kprobe_event+0x16b/0x290
      print_trace_line+0x451/0x8e0
      s_show+0x72/0x1f0
      seq_read_iter+0x58e/0x750
      seq_read+0x115/0x160
      vfs_read+0x11d/0x460
      ksys_read+0xa9/0x130
      do_syscall_64+0x3a/0x90
      entry_SYSCALL_64_after_hwframe+0x63/0xcd
     RIP: 0033:0x7fc2e972ade2
     Code: c0 e9 b2 fe ff ff 50 48 8d 3d b2 3f 0a 00 e8 05 f0 01 00 0f 1f 44 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 0f 05 <48> 3d 00 f0 ff ff 77 56 c3 0f 1f 44 00 00 48 83 ec 28 48 89 54 24
     RSP: 002b:00007ffc64e687c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
     RAX: ffffffffffffffda RBX: 0000000000020000 RCX: 00007fc2e972ade2
     RDX: 0000000000020000 RSI: 00007fc2e980d000 RDI: 0000000000000003
     RBP: 00007fc2e980d000 R08: 00007fc2e980c010 R09: 0000000000000000
     R10: 0000000000000022 R11: 0000000000000246 R12: 0000000000020f00
     R13: 0000000000000003 R14: 0000000000020000 R15: 0000000000020000
      </TASK>

     The buggy address belongs to the physical page:
     page:ffffea00017f6ec0 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x5fdbb
     flags: 0xfffffc0000000(node=0|zone=1|lastcpupid=0x1fffff)
     raw: 000fffffc0000000 0000000000000000 ffffea00017f6ec8 0000000000000000
     raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
     page dumped because: kasan: bad access detected

     Memory state around the buggy address:
      ffff88805fdbbe80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
      ffff88805fdbbf00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
     >ffff88805fdbbf80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
                                    ^
      ffff88805fdbc000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
      ffff88805fdbc080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
     ==================================================================

    This was found when Zheng Yejian sent a patch to convert the event type
    number assignment to use IDA, which gives the next available number, and
    this bug showed up in the fuzz testing by Yujie Liu and the kernel test
    robot. But after further analysis, I found that this behavior is the same
    as when the event type numbers go past the 16bit max (and the above shows
    that).

    As modules have a similar issue, but is dealt with by setting a
    "WAS_ENABLED" flag when a module event is enabled, and when the module is
    freed, if any of its events were enabled, the ring buffer that holds that
    event is also cleared, to prevent reading stale events. The same can be
    done for dynamic events.

    If any dynamic event that is being removed was enabled, then make sure the
    buffers they were enabled in are now cleared.

    Link: https://lkml.kernel.org/r/20221123171434.545706e3@gandalf.local.home
    Link: https://lore.kernel.org/all/20221110020319.1259291-1-zhengyejian1@huawei.com/

    Cc: stable@vger.kernel.org
    Cc: Andrew Morton <akpm@linux-foundation.org>
    Depends-on: e18eb8783ec49 ("tracing: Add tracing_reset_all_online_cpus_unlocked() function")
    Depends-on: 5448d44c38 ("tracing: Add unified dynamic event framework")
    Depends-on: 6212dd2968 ("tracing/kprobes: Use dyn_event framework for kprobe events")
    Depends-on: 065e63f951 ("tracing: Only have rmmod clear buffers that its events were active in")
    Depends-on: 575380da8b ("tracing: Only clear trace buffer on module unload if event was traced")
    Fixes: 77b44d1b7c ("tracing/kprobes: Rename Kprobe-tracer to kprobe-event")
    Reported-by: Zheng Yejian <zhengyejian1@huawei.com>
    Reported-by: Yujie Liu <yujie.liu@intel.com>
    Reported-by: kernel test robot <yujie.liu@intel.com>
    Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
    Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
2024-10-22 11:40:13 +00:00
Jerome Marchand 1f4a51caa1 tracing: Disable "other" permission bits in the tracefs files
Bugzilla: https://bugzilla.redhat.com/2069708

commit 21ccc9cd72116289469e5519b6159c675a2fa58f
Author: Steven Rostedt (VMware) <rostedt@goodmis.org>
Date:   Wed Aug 18 11:24:51 2021 -0400

    tracing: Disable "other" permission bits in the tracefs files

    When building the files in the tracefs file system, do not by default set
    any permissions for OTH (other). This will make it easier for admins who
    want to define a group for accessing tracefs and not having to first
    disable all the permission bits for "other" in the file system.

    As tracing can leak sensitive information, it should never by default
    allowing all users access. An admin can still set the permission bits for
    others to have access, which may be useful for creating a honeypot and
    seeing who takes advantage of it and roots the machine.

    Link: https://lkml.kernel.org/r/20210818153038.864149276@goodmis.org

    Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>

Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
2022-05-16 09:14:22 +02:00
Christophe JAILLET 8db403b963 tracing/dynevent: Fix a memory leak in an error handling path
We must free 'argv' before returning, as already done in all the other
paths of this function.

Link: https://lkml.kernel.org/r/21e3594ccd7fc88c5c162c98450409190f304327.1618136448.git.christophe.jaillet@wanadoo.fr

Fixes: d262271d04 ("tracing/dynevent: Delegate parsing to create function")
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-04-13 12:29:48 -04:00
Masami Hiramatsu d262271d04 tracing/dynevent: Delegate parsing to create function
Delegate command parsing to each create function so that the
command syntax can be customized.

This requires changes to the kprobe/uprobe/synthetic event handling,
which are also included here.

Link: https://lkml.kernel.org/r/e488726f49cbdbc01568618f8680584306c4c79f.1612208610.git.zanussi@kernel.org

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
[ zanussi@kernel.org: added synthetic event modifications ]
Signed-off-by: Tom Zanussi <zanussi@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2021-02-09 12:52:15 -05:00
Qiujun Huang 2b5894cc33 tracing: Fix some typos in comments
s/detetector/detector/
s/enfoced/enforced/
s/writen/written/
s/actualy/actually/
s/bascially/basically/
s/Regarldess/Regardless/
s/zeroes/zeros/
s/followd/followed/
s/incrememented/incremented/
s/separatelly/separately/
s/accesible/accessible/
s/sythetic/synthetic/
s/enabed/enabled/
s/heurisitc/heuristic/
s/assocated/associated/
s/otherwides/otherwise/
s/specfied/specified/
s/seaching/searching/
s/hierachry/hierarchy/
s/internel/internal/
s/Thise/This/

Link: https://lkml.kernel.org/r/20201029150554.3354-1-hqjagain@gmail.com

Signed-off-by: Qiujun Huang <hqjagain@gmail.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2020-11-10 20:39:40 -05:00
Randy Dunlap 5c8c206e43 tracing: Delete repeated words in comments
Drop repeated words in kernel/trace/.
{and, the, not}

Link: https://lkml.kernel.org/r/20200807033259.13778-1-rdunlap@infradead.org

Cc: Ingo Molnar <mingo@redhat.com>
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2020-09-21 21:06:02 -04:00
Wei Yang 22c36b1826 tracing: make tracing_init_dentry() returns an integer instead of a d_entry pointer
Current tracing_init_dentry() return a d_entry pointer, while is not
necessary. This function returns NULL on success or error on failure,
which means there is no valid d_entry pointer return.

Let's return 0 on success and negative value for error.

Link: https://lkml.kernel.org/r/20200712011036.70948-5-richard.weiyang@linux.alibaba.com

Signed-off-by: Wei Yang <richard.weiyang@linux.alibaba.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2020-09-18 22:17:14 -04:00
Tom Zanussi 2b90927c77 tracing: Use seq_buf for building dynevent_cmd string
The dynevent_cmd commands that build up the command string don't need
to do that themselves - there's a seq_buf facility that does pretty
much the same thing those command are doing manually, so use it
instead.

Link: http://lkml.kernel.org/r/eb8a6e835c964d0ab8a38cbf5ffa60746b54a465.1580506712.git.zanussi@kernel.org

Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Tom Zanussi <zanussi@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2020-02-01 13:10:15 -05:00
Tom Zanussi e9260f6257 tracing: Remove useless code in dynevent_arg_pair_add()
The final addition to q is unnecessary, since q isn't ever used
afterwards.

Link: http://lkml.kernel.org/r/7880a1268217886cdba7035526650195668da856.1580506712.git.zanussi@kernel.org

Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Tom Zanussi <zanussi@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2020-02-01 13:09:42 -05:00
Tom Zanussi 74403b6c50 tracing: Remove check_arg() callbacks from dynevent args
It's kind of strange to have check_arg() callbacks as part of the arg
objects themselves; it makes more sense to just pass these in when the
args are added instead.

Remove the check_arg() callbacks from those objects which also means
removing the check_arg() args from the init functions, adding them to
the add functions and fixing up existing callers.

Link: http://lkml.kernel.org/r/c7708d6f177fcbe1a36b6e4e8e150907df0fa5d2.1580506712.git.zanussi@kernel.org

Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Tom Zanussi <zanussi@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2020-02-01 13:09:23 -05:00
Tom Zanussi 86c5426bad tracing: Add dynamic event command creation interface
Add an interface used to build up dynamic event creation commands,
such as synthetic and kprobe events.  Interfaces specific to those
particular types of events and others can be built on top of this
interface.

Command creation is started by first using the dynevent_cmd_init()
function to initialize the dynevent_cmd object.  Following that, args
are appended and optionally checked by the dynevent_arg_add() and
dynevent_arg_pair_add() functions, which use objects representing
arguments and pairs of arguments, initialized respectively by
dynevent_arg_init() and dynevent_arg_pair_init().  Finally, once all
args have been successfully added, the command is finalized and
actually created using dynevent_create().

The code here for actually printing into the dyn_event->cmd buffer
using snprintf() etc was adapted from v4 of Masami's 'tracing/boot:
Add synthetic event support' patch.

Link: http://lkml.kernel.org/r/1f65fa44390b6f238f6036777c3784ced1dcc6a0.1580323897.git.zanussi@kernel.org

Signed-off-by: Tom Zanussi <zanussi@kernel.org>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2020-01-30 09:46:28 -05:00
Steven Rostedt (VMware) 8530dec63e tracing: Add tracing_check_open_get_tr()
Currently, most files in the tracefs directory test if tracing_disabled is
set. If so, it should return -ENODEV. The tracing_disabled is called when
tracing is found to be broken. Originally it was done in case the ring
buffer was found to be corrupted, and we wanted to prevent reading it from
crashing the kernel. But it's also called if a tracing selftest fails on
boot. It's a one way switch. That is, once it is triggered, tracing is
disabled until reboot.

As most tracefs files can also be used by instances in the tracefs
directory, they need to be carefully done. Each instance has a trace_array
associated to it, and when the instance is removed, the trace_array is
freed. But if an instance is opened with a reference to the trace_array,
then it requires looking up the trace_array to get its ref counter (as there
could be a race with it being deleted and the open itself). Once it is
found, a reference is added to prevent the instance from being removed (and
the trace_array associated with it freed).

Combine the two checks (tracing_disabled and trace_array_get()) into a
single helper function. This will also make it easier to add lockdown to
tracefs later.

Link: http://lkml.kernel.org/r/20191011135458.7399da44@gandalf.local.home

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2019-10-12 20:44:07 -04:00
Masami Hiramatsu 30199137c8 tracing/dynevent: Pass extra arguments to match operation
Pass extra arguments to match operation for checking
exact match. If the event doesn't support exact match,
it will be ignored.

Link: http://lkml.kernel.org/r/156095685930.28024.10405547027475590975.stgit@devnote2

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2019-08-31 12:19:38 -04:00
Masami Hiramatsu cb8e7a8d55 tracing/dynevent: Delete all matched events
When user gives an event name to delete, delete all
matched events instead of the first one.

This means if there are several events which have same
name but different group (subsystem) name, those are
removed if user passed only the event name, e.g.

  # cat kprobe_events
  p:group1/testevent _do_fork
  p:group2/testevent fork_idle
  # echo -:testevent >> kprobe_events
  # cat kprobe_events
  #

Link: http://lkml.kernel.org/r/156095684958.28024.16597826267117453638.stgit@devnote2

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2019-08-31 12:19:38 -04:00
Frank Rowand 3dee10da2e tracing: initialize variable in create_dyn_event()
Fix compile warning in create_dyn_event(): 'ret' may be used uninitialized
in this function [-Wuninitialized].

Link: http://lkml.kernel.org/r/1553237900-8555-1-git-send-email-frowand.list@gmail.com

Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Tom Zanussi <tom.zanussi@linux.intel.com>
Cc: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Cc: stable@vger.kernel.org
Fixes: 5448d44c38 ("tracing: Add unified dynamic event framework")
Signed-off-by: Frank Rowand <frank.rowand@sony.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2019-03-26 08:35:36 -04:00
Masami Hiramatsu 1ce25e9f6f tracing: Add generic event-name based remove event method
Add a generic method to remove event from dynamic event
list. This is same as other system under ftrace. You
just need to pass the event name with '!', e.g.

  # echo p:new_grp/new_event _do_fork > dynamic_events

This creates an event, and

  # echo '!p:new_grp/new_event _do_fork' > dynamic_events

Or,

  # echo '!p:new_grp/new_event' > dynamic_events

will remove new_grp/new_event event.

Note that this doesn't check the event prefix (e.g. "p:")
strictly, because the "group/event" name must be unique.

Link: http://lkml.kernel.org/r/154140869774.17322.8887303560398645347.stgit@devbox

Reviewed-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2018-12-10 12:22:44 -05:00
Masami Hiramatsu 5448d44c38 tracing: Add unified dynamic event framework
Add unified dynamic event framework for ftrace kprobes, uprobes
and synthetic events. Those dynamic events can be co-exist on
same file because those syntax doesn't overlap.

This introduces a framework part which provides a unified tracefs
interface and operations.

Link: http://lkml.kernel.org/r/154140852824.17322.12250362185969352095.stgit@devbox

Reviewed-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
2018-12-08 20:54:09 -05:00