31

๐…๐จ๐ซ ๐ž๐ฑ๐š๐ฆ๐ฉ๐ฅ๐ž ๐ข๐ง ๐ญ๐ก๐ž ๐›๐ž๐ฅ๐จ๐ฐ ๐ฌ๐œ๐ž๐ง๐š๐ซ๐ข๐จ:
1) Suppose a process is about to return to user mode after executing a system call, and it finds that it has no outstanding signals.

2) Immediately after checking, the kernel handles an interrupt and sends the process a signal. (For instance, a user hits the “break” key.)

3) What does the process do when the kernel returns from the interrupt?

_______________________________________________________________________________

๐„๐ฑ๐ฉ๐ฅ๐š๐ง๐š๐ญ๐ข๐จ๐ง:

The key part is in the exit_to_user_mode_loop() function:

– The kernel explicitly checks for _TIF_SIGPENDING (pending signals)
– This check is part of a loop that continues processing until all work is done
– Each iteration enables interrupts while handling work (to allow new signals to arrive)
– Then it disables interrupts and rechecks the flags
– This loop structure ensures that even signals that arrive at the last moment get handled

This design effectively prevents the race condition , where a signal arrives just after checking but before returning to user mode. The kernel will see any such signals during the final check with interrupts disabled.
The complete flow through.

syscall_exit_to_user_mode()
โ†’ exit_to_user_mode_prepare()
โ†’ exit_to_user_mode_loop()

For more details check – kernel/entry/common.c
__________________________________________________________________

๐‹๐ž๐š๐ซ๐ง๐ข๐ง๐  ๐Ž๐ฉ๐ฉ๐จ๐ซ๐ญ๐ฎ๐ง๐ข๐ญ๐ข๐ž๐ฌ:
A) ๐’๐ž๐ฅ๐Ÿ-๐๐š๐œ๐ž๐ ๐‚๐จ๐ฎ๐ซ๐ฌ๐ž:
Learn at your own pace
Structured kernel programming modules
Practical examples, bug study
Hands-on debugging experience

B) ๐‚๐ฅ๐š๐ฌ๐ฌ๐ซ๐จ๐จ๐ฆ ๐“๐ซ๐š๐ข๐ง๐ข๐ง๐  ๐Ÿ๐จ๐ซ ๐…๐ซ๐ž๐ฌ๐ก๐ž๐ซ๐ฌ:
5 Months intensive program
Placement support
Real-world bug analysis
Kernel development fundamentals
Live projects & case studies

C) ๐–๐ž๐ž๐ค๐ž๐ง๐ ๐Ž๐ง๐ฅ๐ข๐ง๐ž ๐‚๐จ๐ฎ๐ซ๐ฌ๐ž ๐Ÿ๐จ๐ซ ๐–๐จ๐ซ๐ค๐ข๐ง๐  ๐๐ซ๐จ๐Ÿ๐ž๐ฌ๐ฌ๐ข๐จ๐ง๐š๐ฅ๐ฌ:
180+ Hours of training
8 Months comprehensive program
Flexible for working professionals

๐Ÿ“ฝ ๐˜๐จ๐ฎ๐“๐ฎ๐›๐ž ๐œ๐ก๐š๐ง๐ง๐ž๐ฅ
https://lnkd.in/eYyNEqp

๐Œ๐จ๐๐ฎ๐ฅ๐ž๐ฌ ๐‚๐จ๐ฏ๐ž๐ซ๐ž๐ –
1) System Programming
2) Linux kernel internals
3) Linux device driver
4) Linux socket programming
5) Linux network device driver, PCI, USB driver codeย walk through, Linux
crash analysis and Kdump
7) JTag debugging

– ๐๐ซ๐ข๐œ๐ข๐ง๐  :
https://lnkd.in/ePEK2pJh

32

struct generic_struct {
int id;
float value;
char name[20];
int m;
};

hashtag#define GENERIC_STRUCT_STAT(m)ย ย sizeof(((struct generic_struct *)0)->m)

int main() {
int x = GENERIC_STRUCT_STAT(m); <———-
return0;
}

๐–๐ก๐š๐ญ ๐ฐ๐ข๐ฅ๐ฅ ๐ก๐š๐ฉ๐ฉ๐ž๐ง ๐ฐ๐ก๐ž๐ง ๐ญ๐ก๐ž ๐ฆ๐š๐œ๐ซ๐จ ๐†๐„๐๐„๐‘๐ˆ๐‚_๐’๐“๐‘๐”๐‚๐“_๐’๐“๐€๐“(๐ฆ) ๐ข๐ฌ ๐ฎ๐ฌ๐ž๐?
______________________________________________________________

A) The program will crash due to dereferencing a null pointer.
B) Compilation error.
C) The size of the member m (int) will be calculated, which is typically 4 bytes on most systems.
D) The size of the entire structure generic_struct will be calculated.

ย 

33

#define IS_VALID (type, x) ({ \
type **z; \
typeof(x) **z2; \
(void)(&z == &z2); \ โฌ…๏ธ โž–โž–โž– ๐ฅ๐ข๐ง๐ž 4
1; \
})

int main(int argc, char* argv[])
{

char tt = ‘c’;
float f = 10.56 ;

printf(“%d\n”, IS_VALID(int, f));
printf(“%d\n”, IS_VALID(char, tt));
return 0;
}

(void)(&z == &z2); ->
1) Is it to compare memory addresses of z and z2 at runtime ๐Ž๐‘
2) to force the compiler to check type compatibility ( if z and z2 are of same type) during compilation ๐Ž๐‘
3) to allocate memory for both variables in the same memory block ๐Ž๐‘
4) to check the value of z and z2.

34

The typeof keyword emerged from fundamental limitations in the C language that became apparent as systems programs grew more complex. Here’s the story behind why it came into existence:

๐“๐ก๐ž ๐๐ซ๐จ๐›๐ฅ๐ž๐ฆ ๐ฐ๐ข๐ญ๐ก ๐‚’๐ฌ ๐“๐ฒ๐ฉ๐ž ๐’๐ฒ๐ฌ๐ญ๐ž๐ฆ :
_______________________________________

1) No Generic Programming Suppport
2) Write the same code multiple times for different types
3) Use void pointers and sacrifice type safety
4) Resort to dangerous preprocessor macros

๐”๐ง๐ฌ๐š๐Ÿ๐ž ๐Œ๐š๐œ๐ซ๐จ๐ฌ: C macros are simple text substitutions with no type awareness, leading to infamous problems:
๐“๐ฒ๐ฉ๐ž ๐ˆ๐ง๐Ÿ๐จ๐ซ๐ฆ๐š๐ญ๐ข๐จ๐ง ๐‹๐จ๐ฌ๐ฌ:ย ย Operations like alignment, bit manipulation, and atomic access required casting to and from types, losing type information
๐๐จ ๐“๐ฒ๐ฉ๐ž ๐ˆ๐ง๐Ÿ๐ž๐ซ๐ž๐ง๐œ๐ž: Every variable and expression needed explicit typing, leading to verbose, error-prone code, especially with complex pointer types.

๐“๐ก๐ž ๐†๐‚๐‚ ๐๐ž๐ฏ๐ž๐ฅ๐จ๐ฉ๐ž๐ซ๐ฌ ๐š๐ข๐ฆ๐ž๐ ๐ญ๐จ:
_________________________________________________________
๐ŸŸข Enable Type-Safe Generic Programming: Create a mechanism to write generic code that retained full type safety without sacrificing performance
๐ŸŸข Improve Macro Safety: Allow macros to preserve type information and avoid double-evaluation bugs
๐ŸŸข Support Systems Programming: Address the needs of low-level code like the kernel that manipulated types in ways standard C couldn’t handle

๐–๐ก๐š๐ญ ๐ญ๐ฒ๐ฉ๐ž๐จ๐Ÿ ๐’๐จ๐ฅ๐ฏ๐ž๐ ๐Ÿ๐จ๐ซย ๐Š๐ž๐ซ๐ง๐ž๐ฅ ๐ƒ๐ž๐ฏ๐ž๐ฅ๐จ๐ฉ๐ž๐ซ๐ฌ
______________________________________________________
1) Architecture Portability
2) Avoiding Fragile Casts
3) Safe List Traversal
4) Atomic Operation Safety

35

container_of` macro allows you to find the parent structure from a pointer to one of its members. One of the most ingenious pieces of C programming in the Linux kernel.

Here’s the definition:

hashtag#define container_of(ptr, type, member) ({ย ย ย \
const typeof(((type *)0)->member) *__mptr = (ptr); \
(type *)((char *)__mptr – offsetof(type, member)); })

Let’s break down:

1. Takes a pointer to a member (`ptr`)
2. The type of the container structure (`type`)
3. The name of the member within the structure (`member`)
4. Returns a pointer to the container structure

The most interesting part of the macro is:
const typeof(((type *)0)->member) *__mptr = (ptr);

Fascinating trick using a null pointer cast. Let’s analyze why this works:

– `(type *)0` casts the value 0 (NULL) to a pointer of type `type*`
– `((type *)0)->member` accesses the `member` field of this null pointer
– This doesn’t actually dereference memory (which would cause a crash), but instead lets the compiler determine the type of `member`
– `typeof()` extracts this type information
– `__mptr` is then declared as a pointer to this type and assigned the value of `ptr`

Why is This Implementation Valuable?

1. Enables C Object-Oriented Patterns

Consider this example:

struct device {
int id;ย ย ย ย ย ย ย // Offset 0
char name[8];ย ย ย ย // Offset 4
struct list_head list; // Offset 12
};

When a function receives a `list_head` pointer, it can find the containing `device` structure:

void some_list_function(struct list_head *list_ptr) {

struct device *dev;
dev = container_of(list_ptr, struct device, list);

printf(“Device ID: %d\n”, dev->id);
printf(“Device Name: %s\n”, dev->name);
}

2. Type Safety

The use of `typeof` ensures that `ptr` is of the correct type expected for the member. This provides compile-time type checking.

3. Zero Runtime Overhead

The entire macro resolves to simple pointer arithmetic. There’s no function call overhead, dynamic type checking, or any other runtime cost.

4. Maintains Encapsulation

Exposes only the necessary structures while keeping their containing structures private, enhancing modularity.

Understanding the Null Pointer Cast

The line `const typeof( ((๐ญ๐ฒ๐ฉ๐ž *)0)->member) *__mptr = (ptr);` often confuses developers new to kernel code. The null pointer (0) is specifically chosen because it’s a safe way to access type information without risking memory access.

Practical Applications
The `container_of` macro is used extensively throughout the kernel:

1. ๐ƒ๐ž๐ฏ๐ข๐œ๐ž ๐ƒ๐ซ๐ข๐ฏ๐ž๐ซ ๐Œ๐จ๐๐ž๐ฅ: Finding device structures from their embedded kobjects
2. ๐‹๐ข๐ง๐ค๐ž๐ ๐‹๐ข๐ฌ๐ญ๐ฌ: Retrieving the containing structure from a list entry
3. ๐‘๐‚๐”: Accessing container structures in lock-free code
4. ๐’๐ฎ๐›๐ฌ๐ฒ๐ฌ๐ญ๐ž๐ฆ ๐ˆ๐ง๐ญ๐ž๐ซ๐Ÿ๐š๐œ๐ž๐ฌ: Extending core functionality through composition

36

Two embedded engineers with identical experience sit in the same interview. Both have 2-3 years experience (applicable for freshers also), strong Linux/C skills, solid DSA knowledge.

๐ˆ๐ง๐ญ๐ž๐ซ๐ฏ๐ข๐ž๐ฐ ๐๐ฎ๐ž๐ฌ๐ญ๐ข๐จ๐ง: “๐‡๐จ๐ฐ ๐๐จ ๐ฒ๐จ๐ฎ ๐ฏ๐š๐ฅ๐ข๐๐š๐ญ๐ž ๐ž๐ฆ๐›๐ž๐๐๐ž๐ ๐Ÿ๐ข๐ซ๐ฆ๐ฐ๐š๐ซ๐ž ๐ช๐ฎ๐š๐ฅ๐ข๐ญ๐ฒ?”

โŒ Candidate A: “I do thorough testing and code reviews.”
โœ”๏ธ Candidate B: “I use GCOV for coverage analysis. gcc –coverage revealed
untested error paths in our SPI driver that could have caused field failures. I target 80%+ coverage for production code.”
Result: Candidate B gets the offer.

๐–๐ก๐ฒ ๐“๐จ๐จ๐ฅ ๐Š๐ง๐จ๐ฐ๐ฅ๐ž๐๐ ๐ž ๐–๐ข๐ง๐ฌ
๐“๐จ๐จ๐ฅ-๐’๐š๐ฏ๐ฏ๐ฒ ๐‘๐ž๐ฌ๐ฉ๐จ๐ง๐ฌ๐ž ๐ฌ๐ข๐ ๐ง๐š๐ฅ๐ฌ:
โœ… Production quality experience
โœ… Industry-standard practices
โœ… Systematic development approach
โœ… Can prevent costly field failures

๐“๐ก๐ž ๐„๐š๐ฌ๐ฒ ๐–๐ข๐ง
Complex Skills: 6+ months each (kernel internals, advanced DSA) Professional Tools: 2-3 weeks to master โšก
Impact: Same resume + tool knowledge = 15-25% higher salary

๐˜๐จ๐ฎ๐ซ ๐€๐๐ฏ๐š๐ง๐ญ๐š๐ ๐ž ๐๐ฅ๐š๐ง

# Learn GCOV basics (1 weekend): ->
gcc –coverage -o program source.c
gcov source.c

๐‚๐ฅ๐ข๐œ๐ค ๐›๐ž๐ฅ๐จ๐ฐ ๐Ÿ๐จ๐ซ ๐๐ž๐ญ๐š๐ข๐ฅ๐ฌ :
https://lnkd.in/g4T_RcMq

๐“๐š๐›๐ฅ๐ž ๐จ๐Ÿ ๐‚๐จ๐ง๐ญ๐ž๐ง๐ญ๐ฌ-
[What is GCOV?]
[Why Use GCOV?]
[When to Use GCOV?]
[Understanding GCOV Output]
[Expert vs Novice Analysis]
[Advanced Techniques]
[Industry Best Practices]
[Practical Implementation]
๐‹๐ž๐š๐ซ๐ง ๐ฆ๐จ๐ซ๐ž -> https://lnkd.in/g4T_RcMq

# Build portfolio examples
# Prepare tool-focused interview talking points

๐๐จ๐ญ๐ญ๐จ๐ฆ ๐‹๐ข๐ง๐ž
While others study algorithms for months, you can master professional tools in weeks and immediately stand out in interviews.
Tool knowledge shows professional maturity that hiring managers need.

๐Ÿ“ข Coming Next:
More embedded development tools that create interview advantagesโ€”static analysis, debugging utilities, profiling tools. Follow for weekly insights!

37

A production server hang completely because of one “atomic” operation? Here’s a real Linux kernel bug that brought down enterprise systems worldwide – A Perfect case study for understanding multi-CPU concurrency challenges!

The Linux block layer had this code in the blk-mq (multi-queue block I/O) subsystem:

// ๐‚๐จ๐ฎ๐ง๐ญ ๐ง๐ž๐ฌ๐ญ๐ž๐ ๐Ÿ๐ซ๐ž๐ž๐ณ๐ž ๐จ๐ฉ๐ž๐ซ๐š๐ญ๐ข๐จ๐ง๐ฌ
freeze_depth = atomic_inc_return(&q->mq_freeze_depth);
if (freeze_depth == 1) {
percpu_ref_kill(&q->q_usage_counter); // Stop I/O
}

๐–๐ก๐š๐ญ ๐œ๐จ๐ฎ๐ฅ๐ ๐ ๐จ ๐ฐ๐ซ๐จ๐ง๐ ?
This bug affected ALL multi-core systems running Linux 4.19+ with blk-mq enabled, including:
Intel Xeon servers with NVMe storage
AMD EPYC systems with SATA SSDs in RAID
ARM64 servers with shared storage controllers
Enterprise systems with multipath storage configurations

what happened when two CPUs tried to freeze the same I/O queue is shown in images attached.

The solution was elegantly simple but required mainline kernel changes:

// ๐๐„๐…๐Ž๐‘๐„: ๐‘๐š๐œ๐ž-๐ฉ๐ซ๐จ๐ง๐ž ๐š๐ญ๐จ๐ฆ๐ข๐œ ๐จ๐ฉ๐ž๐ซ๐š๐ญ๐ข๐จ๐ง๐ฌ
freeze_depth = atomic_inc_return(&q->mq_freeze_depth);
if (freeze_depth == 1) percpu_ref_kill();

// AFTER: Mutex-protected critical section
mutex_lock(&q->mq_freeze_lock);
if (++q->mq_freeze_depth == 1) {
percpu_ref_kill(&q->q_usage_counter);
}
mutex_unlock(&q->mq_freeze_lock);

๐“๐ก๐ข๐ฌ ๐ซ๐š๐œ๐ž ๐œ๐จ๐ง๐๐ข๐ญ๐ข๐จ๐ง ๐œ๐š๐ฎ๐ฌ๐ž๐ ๐ฐ๐ข๐๐ž๐ฌ๐ฉ๐ซ๐ž๐š๐ ๐ฉ๐ซ๐จ๐๐ฎ๐œ๐ญ๐ข๐จ๐ง ๐Ÿ๐š๐ข๐ฅ๐ฎ๐ซ๐ž๐ฌ:
RAID arrays stuck in recovery
Journal threads unable to commit
Applications frozen during file writes
System requiring reboot

Key Lessons for System Design
1. Per-CPU Data Isn’t Always the Answer
2. Atomic Operations Have Limits
3. Critical Sections Must Be Identified

Questions for Discussion
1) How do you handle race conditions in your multi-threaded applications?
2) What debugging tools do you use for concurrency issues?
3) Have you encountered similar production issues with “atomic” operations?

๐ŸŽ“ ๐‹๐ž๐š๐ซ๐ง๐ข๐ง๐  ๐Ž๐ฉ๐ฉ๐จ๐ซ๐ญ๐ฎ๐ง๐ข๐ญ๐ข๐ž๐ฌ:
A) ๐’๐ž๐ฅ๐Ÿ-๐๐š๐œ๐ž๐ ๐‚๐จ๐ฎ๐ซ๐ฌ๐ž:
๐๐ฅ๐š๐œ๐ž๐ฆ๐ž๐ง๐ญ ๐ฌ๐ฎ๐ฉ๐ฉ๐จ๐ซ๐ญ
Learn at your own pace
Structured kernel programming modules
Practical examples, bug studies like this one
Hands-on debugging experience

B) ๐–๐ž๐ž๐ค๐ž๐ง๐ ๐Ž๐ง๐ฅ๐ข๐ง๐ž ๐‚๐จ๐ฎ๐ซ๐ฌ๐ž ๐Ÿ๐จ๐ซ ๐–๐จ๐ซ๐ค๐ข๐ง๐  ๐๐ซ๐จ๐Ÿ๐ž๐ฌ๐ฌ๐ข๐จ๐ง๐š๐ฅ๐ฌ:
180+ Hours of comprehensive training
8 Months structured program
Flexible scheduling for working professionals

๐Œ๐จ๐๐ฎ๐ฅ๐ž๐ฌ ๐‚๐จ๐ฏ๐ž๐ซ๐ž๐:
System Programming
Linux kernel internals
Linux device driver development
Linux socket programming
Network device drivers, PCI, USB driver walkthrough
Linux crash analysis and Kdump
JTAG debugging

38

Ftrace is a powerful tracing utility built directly into the Linux kernel that allows developers to trace kernel function calls with minimal overhead. It lives in the kernel’s debugfs, typically mounted at
/๐ฌ๐ฒ๐ฌ/๐ค๐ž๐ซ๐ง๐ž๐ฅ/๐๐ž๐›๐ฎ๐ /๐ญ๐ซ๐š๐œ๐ข๐ง๐ /

๐’๐ž๐ญ๐ญ๐ข๐ง๐  ๐”๐ฉ ๐…๐ญ๐ซ๐š๐œ๐ž
The provided example shows how to configure Ftrace:

mount -t debugfs nodev /sys/kernel/debug
cd /sys/kernel/debug/tracing

# Set function graph tracer
echo function_graph > current_tracer

# Filter for specific functions
echo ‘__x64_sys_brk’ >> set_ftrace_filter
echo ‘do_brk_flags’ >> set_ftrace_filter
echo ‘__x64_sys_mmap’ >> set_ftrace_filter
echo ‘__x64_sys_mmap_pgoff’ >> set_ftrace_filter
echo ‘do_mmap’ >> set_ftrace_filter
echo ‘vm_mmap’ >> set_ftrace_filter
echo ‘vm_mmap_pgoff’ >> set_ftrace_filter
echo ‘get_unmapped_area’ >> set_ftrace_filter
echo ‘vm_unmapped_area’ >> set_ftrace_filter

# Enable tracing
echo 1 > tracing_on

๐…๐ญ๐ซ๐š๐œ๐ž ๐ข๐ง ๐€๐œ๐ญ๐ข๐จ๐ง: ๐Œ๐ž๐ฆ๐จ๐ซ๐ฒ ๐Œ๐š๐ง๐š๐ ๐ž๐ฆ๐ž๐ง๐ญ ๐„๐ฑ๐š๐ฆ๐ฉ๐ฅ๐ž
Let’s analyze the output from a memory test program calling brk, mmap etc:

— Testing brk() syscall —
Initial program break: 0x425000
Program break increased by 1MB: 0x525000
Successfully wrote to the allocated memory
Program break restored: 0x425000

— Testing mmap() syscall —
Anonymous mapping at: 0x7f95fc9f2000
Wrote to anonymous mapping: Testing anonymous mapping
Anonymous mapping unmapped
File mapping at: 0x7f95fc9f2000
First 20 bytes of /etc/passwd: root:x:0:0:root:/roo
File mapping unmapped
Fixed mapping at requested address 0x600000000000

Map with – linux/v6.14.5/source/mm/mmap.c

๐…๐ญ๐ซ๐š๐œ๐ž ๐ซ๐ž๐ฏ๐ž๐š๐ฅ๐ฌ ๐ญ๐ก๐ž ๐ž๐ฑ๐ž๐œ๐ฎ๐ญ๐ข๐จ๐ง ๐ฉ๐š๐ญ๐ก ๐ฐ๐ข๐ญ๐ก ๐ญ๐ข๐ฆ๐ข๐ง๐  ๐๐ž๐ญ๐š๐ข๐ฅ๐ฌ:
4) __x64_sys_mmap() {
4) vm_mmap_pgoff() {
4) do_mmap() {
4) get_unmapped_area() {
4) vm_unmapped_area();
4) }
4) }
4) }
4) }

๐๐ž๐ซ๐Ÿ๐จ๐ซ๐ฆ๐š๐ง๐œ๐ž ๐ข๐ง๐ฌ๐ข๐ ๐ก๐ญ๐ฌ:
14) __x64_sys_mmap() {
14) 4.440 us | do_mmap();
14) 4.881 us | }

๐…๐จ๐ซ ๐Ÿ๐ข๐ฑ๐ž๐ ๐ฆ๐š๐ฉ๐ฉ๐ข๐ง๐ ๐ฌ:
6) __x64_sys_mmap() {
6) 1.794 us | do_mmap();
6) ! 409.690 us | } <— exclamation mark indicates a long execution time

๐๐ž๐ง๐ž๐Ÿ๐ข๐ญ๐ฌ ๐Ÿ๐จ๐ซ ๐ƒ๐ž๐›๐ฎ๐ ๐ ๐ข๐ง๐ 

– Function call hierarchy: Seeing what functions are called in what order
– Performance measurement: Precise timing of each function
– Bottleneck identification: Finding unexpectedly slow operations
– System understanding: Revealing implementation details of system calls

๐‹๐ข๐ฆ๐ข๐ญ๐š๐ญ๐ข๐จ๐ง๐ฌ ๐š๐ง๐ ๐‚๐ก๐š๐ฅ๐ฅ๐ž๐ง๐ ๐ž๐ฌ
– Kernel-only visibility: Limited to kernel space, doesn’t show userspace activities
– Buffer constraints: Trace buffers can overflow during extended tracing
– Security implications: May expose sensitive kernel information

39

Linux does not immediately recycle process identifiers (PIDs) for new processes after a process exits. Instead, PIDs are allocated sequentially up to a maximum and only reused after the range wraps around.

๐Š๐ž๐ฒ ๐‘๐ž๐š๐ฌ๐จ๐ง๐ฌ ๐Ÿ๐จ๐ซ ๐€๐ฏ๐จ๐ข๐๐ข๐ง๐  ๐ˆ๐ฆ๐ฆ๐ž๐๐ข๐š๐ญ๐ž ๐๐ˆ๐ƒ ๐‘๐ž๐ฎ๐ฌ๐ž:

๐“๐ก๐ฐ๐š๐ซ๐ญ๐ข๐ง๐  ๐“๐ข๐ฆ๐ข๐ง๐ -๐๐š๐ฌ๐ž๐ ๐€๐ญ๐ญ๐š๐œ๐ค๐ฌ:
Prevents attackers from predicting when a PID will be free and immediately acquiring it. This blocks attackers from spawning malicious processes with the same PID as just-terminated privileged processes.

๐๐ซ๐ž๐ฏ๐ž๐ง๐ญ๐ข๐ง๐  ๐‚๐ซ๐ž๐๐ž๐ง๐ญ๐ข๐š๐ฅ/๐‘๐ž๐ฌ๐จ๐ฎ๐ซ๐œ๐ž ๐‡๐ข๐ฃ๐š๐œ๐ค๐ข๐ง๐ :
Blocks impersonation attacks where a new process might inherit security tokens or permissions from a recently terminated process with the same PID.

๐Œ๐š๐ข๐ง๐ญ๐š๐ข๐ง๐ข๐ง๐  ๐€๐œ๐œ๐ฎ๐ซ๐š๐ญ๐ž ๐Œ๐จ๐ง๐ข๐ญ๐จ๐ซ๐ข๐ง๐  & ๐€๐ฎ๐๐ข๐ญ๐ข๐ง๐ :
Ensures that system monitors, loggers, and auditing tools can accurately track processes without confusion. At any given moment, each PID refers to only one specific process.

๐€๐ฏ๐จ๐ข๐๐ข๐ง๐  ๐‘๐š๐œ๐ž ๐‚๐จ๐ง๐๐ข๐ญ๐ข๐จ๐ง๐ฌ:
Eliminates dangerous race conditions where system operations (signals, /proc access, etc.) might accidentally target a new process that inherited a PID instead of the intended original process.

๐‚๐ก๐ž๐œ๐ค ๐๐ž๐ฌ๐ข๐ ๐ง ๐œ๐ก๐š๐ง๐ ๐ž๐ฌ-
linux.git/commit/?id=5fdee8c4a5e1800489ce61963208f8cc55e42ea1
linux/v4.14.336/source/kernel/pid.c
linux/v6.15-rc4/source/kernel/pid.c

1) ๐‚๐จ๐ซ๐ž ๐€๐ฅ๐ฅ๐จ๐œ๐š๐ญ๐ข๐จ๐ง ๐Œ๐ž๐œ๐ก๐š๐ง๐ข๐ฌ๐ฆ
nr = idr_alloc_cyclic(&tmp->idr, NULL, pid_min, pid_max, GFP_ATOMIC);

2) ๐๐ˆ๐ƒ ๐‘๐š๐ง๐ ๐ž ๐Œ๐š๐ง๐š๐ ๐ž๐ฆ๐ž๐ง๐ญ
// Determine minimum PID value for allocation
int pid_min =1;
if(idr_get_cursor(&tmp->idr)> RESERVED_PIDS)
pid_min = RESERVED_PIDS;

3) ๐‹๐š๐ซ๐ ๐ž ๐๐ˆ๐ƒ ๐’๐ฉ๐š๐œ๐ž ๐‚๐จ๐ง๐Ÿ๐ข๐ ๐ฎ๐ซ๐š๐ญ๐ข๐จ๐ง
init_pid_ns.pid_max =min(pid_max_max,max_t(int, init_pid_ns.pid_max, PIDS_PER_CPU_DEFAULT *num_possible_cpus()));

pid_max_min =max_t(int, pid_max_min, PIDS_PER_CPU_MIN *num_possible_cpus());

4) ๐๐š๐ฆ๐ž๐ฌ๐ฉ๐š๐œ๐ž ๐ˆ๐ฌ๐จ๐ฅ๐š๐ญ๐ข๐จ๐ง
struct pid_namespace init_pid_ns = {
.ns.count =REFCOUNT_INIT(2),
.idr =IDR_INIT(init_pid_ns.idr),
// …
};

๐“๐ก๐ž ๐ฌ๐ฒ๐ฌ๐ญ๐ž๐ฆ ๐ฉ๐ซ๐ž๐ฏ๐ž๐ง๐ญ๐ฌ ๐ข๐ฆ๐ฆ๐ž๐๐ข๐š๐ญ๐ž ๐๐ˆ๐ƒ ๐ซ๐ž๐ฎ๐ฌ๐ž ๐›๐ฒ:
– Using cursor-based sequential, cyclic PID allocation
– Maintaining a large PID space.
– Ensuring PIDs are not reused until the entire PID space is exhausted
– Providing namespace isolation for container environments

๐’๐จ๐ฎ๐ซ๐œ๐ž๐ฌ:
Stack Overflow โ€“ Linux PID recycling behavior
GitHub Issue โ€“ Kernel avoids quick PID reassignments to prevent issues
Exploit-DB (Polkit) โ€“ Timing attack & auth hijack via PID reuse
Security StackExchange โ€“ PID uniquely identifies an active process
Superuser โ€“ Quick PID reuse seen as a security hazard

40

Walking through a real-world Linux kernel bug resolution process. The case study focused on a regression where Silicon Motion NVMe controllers stopped being detected after a kernel update.

๐Ÿ“ฝ https://lnkd.in/gwmCnNZq

The complete lifecycle of kernel bug handling through bugzilla.kernel.org
How NVMe’s architecture provides superior performance over traditional SATA (64K command queues vs. just a mere 32 commands!)

The intricate relationship between PCIe subsystems and storage drivers
Source code analysis of the NVMe driver’s device detection and initialization process

The actual bug fix was elegantly simple but required deep understanding:
The issue was in how the driver handled the DNR (Do Not Retry) status bit.

The original code had the logic backward – it was:
if (status > 0 && !(status & NVME_SC_DNR))

But it should have been:

if (status > 0 && (status & NVME_SC_DNR))

This seemingly small change fixed critical detection issues with Silicon Motion controllers, ensuring that non-retryable errors are properly ignored while retryable errors are correctly propagated.

Are you interested in developing these advanced Linux kernel debugging skills? Our next Linux Kernel and Device Driver Development course starts soon!

๐†๐ž๐ญ ๐ก๐š๐ง๐๐ฌ-๐จ๐ง ๐ž๐ฑ๐ฉ๐ž๐ซ๐ข๐ž๐ง๐œ๐ž ๐ฐ๐ข๐ญ๐ก:
Linux kernel module structure and initialization
PCIe device enumeration and driver binding
Storage subsystem architecture
Reading technical specifications and applying them to code
Understanding kernel patch submission workflow

๐”๐ฌ๐ž๐Ÿ๐ฎ๐ฅ ๐ซ๐ž๐ฌ๐จ๐ฎ๐ซ๐œ๐ž๐ฌ:
Kernel.org Bugzilla: https://lnkd.in/gBvyD_f4
Bug 208583 – Regression – nvme not detected

_____________________________

๐Ÿ“ฝ ๐˜๐จ๐ฎ๐“๐ฎ๐›๐ž ๐œ๐ก๐š๐ง๐ง๐ž๐ฅ
https://lnkd.in/eYyNEqp

๐Œ๐จ๐๐ฎ๐ฅ๐ž๐ฌ ๐‚๐จ๐ฏ๐ž๐ซ๐ž๐ –
1) System Programming
2) Linux kernel internals
3) Linux device driver
4) Linux socket programming
5) Linux network device driver, PCI, USB driver codeย walk through, Linux
crash analysis and Kdump
7) JTag debugging

– ๐๐ซ๐ข๐œ๐ข๐ง๐  :
https://lnkd.in/ePEK2pJh

๐‹๐ž๐š๐ซ๐ง๐ข๐ง๐  ๐Ž๐ฉ๐ฉ๐จ๐ซ๐ญ๐ฎ๐ง๐ข๐ญ๐ข๐ž๐ฌ:

A) ๐’๐ž๐ฅ๐Ÿ-๐๐š๐œ๐ž๐ ๐‚๐จ๐ฎ๐ซ๐ฌ๐ž:
Learn at your own pace
Structured kernel programming modules
Practical examples, bug study
Hands-on debugging experience

B) ๐‚๐ฅ๐š๐ฌ๐ฌ๐ซ๐จ๐จ๐ฆ ๐“๐ซ๐š๐ข๐ง๐ข๐ง๐  ๐Ÿ๐จ๐ซ ๐…๐ซ๐ž๐ฌ๐ก๐ž๐ซ๐ฌ:
5 Months intensive program
Placement support
Real-world bug analysis
Kernel development fundamentals
Live projects & case studies

C) ๐–๐ž๐ž๐ค๐ž๐ง๐ ๐Ž๐ง๐ฅ๐ข๐ง๐ž ๐‚๐จ๐ฎ๐ซ๐ฌ๐ž ๐Ÿ๐จ๐ซ ๐–๐จ๐ซ๐ค๐ข๐ง๐  ๐๐ซ๐จ๐Ÿ๐ž๐ฌ๐ฌ๐ข๐จ๐ง๐š๐ฅ๐ฌ:
180+ Hours of training
8 Months comprehensive program
Flexible for working professionals