Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Introduce Ftrace in the syscall section #180

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

nickchen120235
Copy link

@nickchen120235 nickchen120235 commented Nov 21, 2022

Closes #175

  • Write the syscall stealing example using Ftrace
  • Add contents into the book

Copy link
Collaborator

@linD026 linD026 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest we should also provide a user script to work with this example.
It can be located at /lkmpg/example/other directory.

examples/syscall-ftrace.c Outdated Show resolved Hide resolved
@jserv jserv changed the title Draft: Introduce Ftrace in the syscall chapter WIP: Introduce Ftrace in the syscall section Nov 22, 2022
-  uid should be initialized
- update comments
- add uid check in our_sys_openat
- format
@nickchen120235 nickchen120235 marked this pull request as ready for review November 22, 2022 07:37
@jserv jserv requested a review from linD026 December 1, 2022 16:16
examples/syscall-ftrace.c Outdated Show resolved Hide resolved
examples/syscall-ftrace.c Outdated Show resolved Hide resolved

\begin{figure}[h]
\centering
\includegraphics[width=\textwidth]{assets/syscall/flow.jpg}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Utilize TikZ for drawing. See https://texample.net/tikz/examples/pgf-umlsd/
Avoid putting bitmap files.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

This is the best I got so far. Unfortunately pgf-umlsd doesn't support returning to functions other than the caller, so the hooking part isn't accurately represented.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I have to rotate the figure by 90 degrees to minimize the overflow although it overflows anyway. Will it affect the output of the website or should I rotate it back and let it overflow?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, you can just render the partial sequences.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I can rework this diagram in latex because it lacks features I need, like returning to functions other than caller (this is the most important one), annotation. (I'm not the creator of this sequence diagram so obtaining the "original" file is not possible either.)

I think the resolution of that jpeg is good enough for even printing, so I think I may left it as is.

The latex code I've written and the result
\begin{sequencediagram}
  \newthread{do_syscall_64}{do\_syscall\_64}
  \newinst[1.5]{sys_execve}{sys\_execve}
  \newinst[1.5]{ftrace}{[ftrace]}
  \newinst[1]{fh_ftrace_thunk}{fh\_ftrace\_thunk}
  \newinst[1]{fh_sys_execve}{fh\_sys\_execve}

      \postlevel \postlevel \postlevel
      \begin{call}{do_syscall_64}{\shortstack{
        \cpp|regs-ax=|\\
        \cpp|sys_call_table[nr]|\\
        \cpp|(regs->di,regs->si|\\
        \cpp|regs->dx,regs->r10|\\
        \cpp|regs->r8,regs->r9)|
      }}{sys_execve}{}
        \begin{call}{sys_execve}{call \cpp|__fentry__|}{ftrace}{}
          \begin{call}{ftrace}{}{fh_ftrace_thunk}{}
            \postlevel
          \end{call}
        \end{call}
        \begin{call}{sys_execve}{hooking}{fh_sys_execve}{\cpp|real_sys_execve()|}
          \postlevel
        \end{call}
        \postlevel
        \begin{call}{sys_execve}{call \cpp|__fentry__|}{ftrace}{}
          \begin{call}{ftrace}{}{fh_ftrace_thunk}{}
            \postlevel
          \end{call}
        \end{call}
        \begin{call}{sys_execve}{}{fh_sys_execve}{}
        \end{call}
      \end{call}
\end{sequencediagram}

image

lkmpg.tex Outdated Show resolved Hide resolved
lkmpg.tex Outdated Show resolved Hide resolved
lkmpg.tex Outdated Show resolved Hide resolved
examples/syscall-ftrace.c Outdated Show resolved Hide resolved
examples/syscall-ftrace.c Outdated Show resolved Hide resolved
examples/syscall-ftrace.c Outdated Show resolved Hide resolved
examples/syscall-ftrace.c Outdated Show resolved Hide resolved
examples/syscall-ftrace.c Outdated Show resolved Hide resolved
Copy link
Collaborator

@linD026 linD026 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the warning, please fix it too.

/home/runner/work/lkmpg/lkmpg/examples/syscall-ftrace.c:190:9: warning: ignoring return value of ‘copy_from_user’, declared with attribute warn_unused_result [-Wunused-result]
  190 |     if (copy_from_user(kfilename, (char __user *)regs->si, MAX_FILENAME_SIZE) < 0) {
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

@nickchen120235
Copy link
Author

syscall-ftrace.c should be good to go.

- remove obsolete comments
- use `pr_fmt` to clean kprintf
- remove clang-format comments
- `static` declarations
- fix ignored return value warning
correct the comment

`nr` refers to syscall "number", not "name"
lkmpg.tex Outdated Show resolved Hide resolved
examples/syscall-ftrace.c Outdated Show resolved Hide resolved
examples/syscall-ftrace.c Outdated Show resolved Hide resolved
lkmpg.tex Show resolved Hide resolved
@jserv jserv requested a review from linD026 December 5, 2022 09:31
examples/syscall-ftrace.c Outdated Show resolved Hide resolved
examples/syscall-ftrace.c Show resolved Hide resolved
examples/syscall-ftrace.c Show resolved Hide resolved
- fix comment style
- new line after declaration
- fix incorrect parameter order of kmalloc
char *kfilename;
int errcode = 0;

if (current->cred->uid.val != uid)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still have the warning.

/home/runner/work/lkmpg/lkmpg/examples/syscall-ftrace.c:180:16: warning: dereference of noderef expression

We need both \cpp|FTRACE_OPS_FL_SAVE_REGS| and \cpp|FTRACE_OPS_FL_IPMODIFY| because we're modifying \cpp|ip|.
Inside \cpp|ftrace_thunk| is what the magic happens.
We check if it is called from within the module,
if not then it modifies the instruction pointer to our ``spying'' function.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.
Don't separate the line with comma.

Alright let's write some code.
Below is the source code of the example from above, but rewritten using \verb|ftrace|.
The main difference is the \cpp|install_hook| function,
which prepares our tracee function (\cpp|sys_openat|),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't separate the line with comma.

if not then it modifies the instruction pointer to our ``spying'' function.
The check is performed by checking whether \cpp|parent_ip| is within this module.
During the first call, \cpp|parent_ip| points to somewhere within the kernel,
while during the second call it points to somewhere in our ``spying'' function, which is within the module.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto, the comma.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't point out all of the cases. Please check again.

and we have access to CPU registers,
maybe we can ``hijack'' the traced function by modifying the instruction pointer?
Yes, this is possible by enabling \cpp|FTRACE_OPS_FL_IPMODIFY| flag when registering a trace.
It will allow us to modify the instruction pointer register, which will become an unconditional jump after the \verb|ftrace| function.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The clause introduced by which is restrictive. So, omit the comma.

Do notice that in kernel version later than v5.11, this is replaced with \cpp|struct ftrace_regs *fregs|, with the original \cpp|pt_regs| accessible by \cpp|fregs->regs|.
\end{itemize}

Internally, there's a 5-byte \cpp|call| to \cpp|__fentry__| at the beginning (BEFORE function prologue) of a traceable kernel function, which is converted to \cpp|nop| during boot to prevent overhead. When a trace is registered, it is changed back to \cpp|__fentry__| and the registered callback will be executed accordingly.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separate the line with sentences.

@nickchen120235 nickchen120235 marked this pull request as draft December 8, 2022 05:58
@nickchen120235
Copy link
Author

nickchen120235 commented Dec 8, 2022

Changing this back to draft since I won't be able to work on this for a while. Reviews are still welcomed, though they won't be resolved until I come back.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Any chance to introduce Ftrace in the syscall chapter (or elsewhere) in this book?
3 participants