After class_register failure, the wrong function class_unregister was
used. The correct cleanup function should be unregister_chrdev, as
register_chrdev was used before class_register.
The function pointer type of myvariable_store was incompatible with the
store member of struct kobj_attribute, leading to a compilation error
when the type conversion (void *) was omitted. This patch corrects the
function declaration and eliminates the need for type conversion.
As myvariable is declared as an integer, it is meaningless that putting
u after %d in the format specifier of sscanf for scanning an integer.
This patch removes the u in the format specifier for avoiding
misleading.
The procfile_write prints the content what user writes into. However,
when the content size is greater than or equal to PROCFS_MAX_SIZE,
procfile_write will print nothing, because the index for appending the
tail NULL character will be modulo to 0, which is an off-by-one error.
This fixes the problem by changing the upper bound of procfs_buffer_size
to (PROCFS_MAX_SIZE - 1), leaving one byte for NULL character. After
the change, we can discard the modulo because the range of
procfs_buffer_size is already between 0 and (PROCFS_MAX_SIZE - 1).
There is a subtle bug that if the atomic flag changes
between the time it was checked and the second time
it was checked, sleep.c would potentially block a
process that had specified O_NONBLOCK. This fixes
the bug by using atomic_cmpxchg instead of atomic_read.
For x86 architecture, the system call table cannot be used to invoke
a system call after commit 1e3ad78 since v6.9. This commit has been
backported to long term stable kernels, like v5.15.154+, v6.1.85+,
v6.6.26+ and v6.8.5+[1]. In this case, thanks to Kprobes, a hook can be
used instead on the system call entry to intercept the system call.
[1] https://stackoverflow.com/a/78607015
Co-authored-by: Hao Dong <hao.dong.work@outlook.com>
Add sudo to commands in Chapter 8 for example module interaction.
The "myvariables" in the module are set with 0660 permissions
via __ATTR(), preventing direct user access.
Options to fix this:
1. Instruct users to use 'sudo' to read/write files.
2. Relax the permission settings to 0666.
This commit adopts the sudo method to maintain security constraints.
7.4 The seq_file is missing the behavior that occurs when it
directly returns NULL after the start step.
Also, in the flowchart, the first decision where `return is NULL`
is `Yes` points to nothing, which is not defined in ISO 5807.
ISO 5807 section 10.3.1.2 states logic path of a decision,
"Each exit from a symbol be accompanied by the appropriate
condition values to show the logic path which it represents,
so that the conditions and the associated references are identified."
The behavior of pointing to nothing does not have associated
references and does not indicate the relation of this logic path.
Refs:
1. The Liunx Kernel Module Programming Guide
7.4 Manage /proc file with seq_file
2. ISO-5807-1985
When raw_copy_to_user() failed in vinput_read(), the function would set
'count' to -EFAULT and then subtract EFAULT from '*offset'. However,
modifying '*offset' on raw_copy_to_user() failure was incorrect. Fix
this behavior by changing count = -EFAULT to return -EFAULT.
When kzalloc fails to allocate memory and returns NULL, it leads to a
NULL pointer dereference error later on. Add a check for the return
value of kzalloc. When kzalloc fails to allocate memory, it prints an
error message and returns ERR_PTR(-ENOMEM).
The last parameter of request_threaded_irq must be a globally unique
cookie[1]. Usually this would be the device struct received by probe().
Since we are not using driver model, pass the gpio structs instead.
[1] https://docs.kernel.org/core-api/genericirq.html
Aquiring a spinlock makes the holder enter atomic context. Extra
attention is needed in atomic context. In particular, functions
that may sleep must not be used. Add this detail to the spinlock
section.
The past content in the crypto section lacks informative descriptions,
and there should be a proper procedure to demonstrate how Linux
cryptography works. Due to poor maintenance, let's drop the section.