Skip to content

pjha2908-ad/Linux_System_Programming

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 

Repository files navigation

System Programming

Useful Links:

Command:

Command Description
Objdump --source binary_name
    OR
    objdump -S binary_name
Display source code mixed with assembly output.
objdump -f binary_name Display file header.
objdump -x binary_name Show all headers.
objdump -d binary_name Shows assembly code of the executable.
objdump -h binary_name Displays sections like .text, .data, .bss.
objdump -t binary_name Shows functions, variables, symbols.
objdump -s binary_name Displays raw contents (hex + ASCII).
ulimit -f To query the maximum possible size of files written to by the shell process.
ulimit -a All resource limit. (It's per process not system-wide).
ulimit -aS Display all Soft resource limit values.
ulimit-aH Display all hard resource limit values.
meld The meld command is used to compare and merge files or directories visually. It’s extremely handy for system programming, code reviews, config diffs, and resolving conflicts.
grep -irl i : case insensitive
r :recursive
l :list of file (instead of matching line)
e.g:grep -irl sys_read include ---> search sys_read in include dir (recursive, case insensitive, list of files).
strace ./binary_name Provide details what all system calls a user space program is calling e.g strace ./a.out.
strace -c ./binary_name Count time, calls, and errors for each system call and report a summary on program exit.
strace -f -o strace.out bash silence_date.sh
  • -f(follow):Track child processes. Since bash will fork a new process to run the date command, this is essential to see what date is doing.
  • -o strace.out: Save the massive amount of technical data to a file instead of flooding your terminal.
readelf -d binary_name Display list of all .so files on which the given binary is dependent.
grep ^b ^b is a regular expression meaning:
  • ^ → start of the lineg.
  • b → the line must begin with the letter b.
echo $$ prints the Process ID (PID) of the current shell.
  • $ is a special shell variable that always contains the PID of the shell instance you're running.
  • echo $ simply outputs that number.
!! Repeat last executed cmd.
!$ Take argument of the last cmd.
!sudo Prepends sudo to your last command (e.g., sudo !!)
!abc Re-runs the most recent command that started with "abc".
!?abc? Re-runs the most recent command containing "abc" anywhere in the line.
!n Re-runs a specific command line number n from your history list.
!-n Last back nth executed cmd.
$? Termination status of the last executed program!
dd The dd command in Linux is used for low-level copying and conversion of data. It is powerful and often used for disk operations.
dd is dangerous if used incorrectly:
  • It can overwrite disks and delete data permanently.
  • Double-check if= and of= before running.
e.g: dd if=/dev/zero of=file.bin bs=1M count=10 It creates a file filled with zeros.
  • if=/dev/zero: Input source = infinite stream of zero bytes
  • of=file.bin: Output file = file.bin (will be created)
  • bs=1MBlock size = 1 MB
  • count=10 Number of blocks = 10
Result: Creates a file named file.bin of size 10 MB
date -d @timestamp It would convert the time stamp in human readable format. e.g if from log file timastap you want to convert.
/lib/aarch64-linux-gnu/libc.so.6
      OR
      /lib/x86_64-linux-gnu/libc.so.6
When we run the library as an executable, it displays various text, including its version number.
pstree Display all running processes in a hierarchical tree format.
size binary_name Displays the size of the text, initialized data, and uninitialized data(bss) segments of a binary executable.
printenv Displays the current environment variable list.
mtrace mtrace is a GNU C Library (glibc) tool used to detect memory leaks in C programs. It tracks every malloc and free call to ensure they match up.
  1. Modify your C code:
    Include and call mtrace() at the start of main().
  2. Set the envrinment variable:
    LD_PRELOAD=/lib/aarch64-linux-gnu/libc_malloc_debug.so.0 MALLOC_TRACE=./mtrace.log ./mtrace_test
  3. Run the program with mtrace tool and log file.
    mtrace ./mtrace_test ./mtrace.log(show the memleak in the process )
ls /proc/PID/task | wc -l Count the threads in your process.
top -H -p [PID] Find which thread is consuming the most CPU. (The -H flag instructs top to show individual threads).
cat /proc/[PID]/task/[TID]/status Check the status of a specific thread.
lsblk see all available block devices and identify your drive.
head /proc/meminfo Running head /proc/meminfo gives you a raw, real-time snapshot of how your system is juggling memory.
Unlike the free command, which simplifies things, this file pulls data directly from the kernel's data structures. Breaking Down the Top 5 Lines:
  1. MemTotal: The total usable RAM (physical RAM minus a few reserved bits for the kernel).
  2. MemFree: RAM that is completely untouched. Note: In Linux, a low number here is usually fine!
  3. MemAvailable: This is the most important number.
    It estimates how much memory is actually available for starting new applications without swapping.
    It includes MemFree plus reclaimable caches.
  4. Buffers: Temporary storage for raw disk blocks (waiting to be written to the drive).
  5. Cached: The "Page Cache." Linux uses "empty" RAM to store files you've recently read, making the system feel much faster.
systemctl enable --now process_name It will start the process immediately.
systemctl restart process_name Restart the process.
curl [option] URL curl (short for "Client URL") is a powerful command-line tool used to transfer data to or from a server using various network protocols,
such as HTTP, HTTPS, FTP, and more. It is widely used by developers for testing APIs, downloading files, and automating web tasks
directly from the terminal.
id Gives user details. If you see uid=0(root), you are logged in with root.
ls -d list directories themselves, rather than listing the files inside those directories.
ctrl+A, press Esc Copy Mode. you can use arrow to move up/down then press Esc again to exit.
ps Displays information about active processes.
  • -L: Displays information about active processes.
  • -A: Displays all processes.
  • a: Shows processes for all users (not just the current user).
  • u: Displays the process's user/owner and additional details in a user-oriented format.
  • x: Includes processes that are not attached to a terminal (like daemons).
  • Z: display SELinux security context

Gdb commands:

Command Use
info registers lr Return Address isn't always on the stack immediately; it's often stored in the Link Register (lr or x30).
x/3i $pc Show the next 3 instructions.
x/i $pc You can see the exact assembly instruction at that spot by running this command.
info registers pc Program Counter (PC) register info.

Files:

File Use/Description
/etc/security/limits.conf Config file for resource limit. Set limits on system resources for users or groups.
/dev/zero
  • /dev/zero is a pseudo‑device that produces an infinite stream of null bytes (\0) when read.
  • Reading from /dev/zero returns:
    00000000 00000000 00000000 00000000 ...
/proc/sys/kernel/pid_max Process id max limit.
/proc/[PID]/status It is a virtual file that provides a human-readable summary of the current status for the process with PID.
/proc/<PID>/maps The Linux kernel generates a text-based representation of the Virtual Memory Areas (VMAs).
/proc/<PID>/cmdline The command-line arguments of any process can be read via this file.
/proc/<PID>/environ Environment list of the process.
/etc/fstab The /etc/fstab (file systems table) file is a system configuration file that contains information about all available disks and partitions and indicates how they should be automatically initialized or mounted into the system.
/proc/<PID>/mounts Mount points for this process.
/proc/PID/fd/ The directory /proc/[PID]/fd/ contains symbolic links to every file descriptor (FD) currently held open by that process.

FD 0: Standard Input (stdin)
FD 1: Standard Output (stdout)
FD 2: Standard Error (stderr)
/proc/PID/task The /proc/[PID]/task directory contains a subdirectory for every thread currently belonging to that process.

Structure
Inside /proc/[PID]/task, you will see folders named with TIDs (Thread IDs).
  • For a single-threaded program, there is only one folder, and its TID will match the PID.
  • For multi-threaded programs (e.g., using pthread_create), you will see multiple folders.
include/uapi/asm-generic/unistd.h Information about system calls.

Flags:

Flag Use
O_SYNC O_SYNC is a file status flag used with the open() system call to request synchronous I/O.

When you open a file with the O_SYNC flag, every write() operation becomes blocking. The system call returns only after:
  1. The data has been physically written to the storage device (SSD/HDD).
  2. The file metadata (inode information such as modification time and file size) has also been updated on disk.
O_DSYNC O_DSYNC (Data Synchronous) is a performance-optimized version of O_SYNC.

While O_SYNC waits for both the data and the metadata to be written to disk, O_DSYNC waits only for the data itself.

  • O_SYNC: "Don't return until the data and inode details are safe."
  • O_DSYNC: "Don't return until the data is safe. Metadata updates can wait."
O_RSYNC O_RSYNC (Read Synchronous) provides synchronization guarantees for read() operations.

When used with O_SYNC or O_DSYNC, a read() call blocks until pending writes affecting that data are synchronized.

  • With O_DSYNC: Read blocks until data and required metadata are synchronized.
  • With O_SYNC: Read blocks until data and all metadata are synchronized.
O_DIRECT O_DIRECT is a Linux-specific open() flag used to bypass the kernel's page cache.

Data is transferred directly between the user-space buffer and the storage device using DMA (Direct Memory Access), without intermediate kernel buffering.

Data structure:

Data structure / Macro / Function Type Header File Use
vm_area_struct Structure include/linux/mm_types.h vm_area_struct is the fundamental structure used to manage a process's virtual memory.

Key Components
  • vm_start and vm_end → Memory boundaries
  • vm_page_prot → Memory permissions
  • vm_flags → Region attributes
  • vm_next and vm_prev → Linked-list navigation
  • vm_rb → Red-Black tree node for fast lookup
Address belongs to VMA only if:
vm_start <= addr < vm_end
mm_struct Structure - Describes the complete virtual address space of a process.

Contains
  • mmap → Linked list of VMAs
  • mm_rb → Red-Black tree root
  • pgd → Page Global Directory
  • start_code, end_code
  • start_data, end_data
  • start_brk, brk
  • start_stack
  • mm_users → Shared-user counter
char *getenv(const char *name) Function stdlib.h Returns a pointer to the value of an environment variable.
int putenv(char *string) Function stdlib.h Adds or modifies an environment variable.
int setenv(const char *name, const char *value, int overwrite) Function stdlib.h Creates or updates an environment variable.
int unsetenv(const char *name) Function stdlib.h Removes an environment variable.
mtrace Function mcheck.h Tracks memory allocation calls to detect memory leaks and invalid frees.
LD_PRELOAD Environment Variable - Forces the dynamic linker to load a specific shared library before others. Used for function interposition or hooking.
alloca Function alloca.h Allocates memory directly on the stack frame instead of the heap.
Utsname Structure sys/utsname.h Stores operating system identity information like hostname, kernel version, architecture, etc.
getpwnam() Function <pwd.h> Retrieves user account information using username.
struct dirent Structure <dirent.h> Represents a directory entry inside a directory stream.
stat() Function / System Call <sys/stat.h>
<sys/types.h>
<unistd.h>
Retrieves metadata information about a file.
struct stat Structure <sys/types.h>
<sys/stat.h>
<unistd.h>
Contains file metadata such as owner, size, inode, permissions, and timestamps.
size_t strcspn(const char *s, const char *reject) Function <string.h> Returns the number of characters before the first matching rejected character.
fsync(int fd) Function <unistd.h> Flushes file data and metadata to disk.
fdatasync(int fd) Function <unistd.h> Flushes only file data and required metadata to disk.
sync() Function <unistd.h> Flushes all pending filesystem buffers to disk.
int setvbuf(FILE *stream, char *buf, int mode, size_t size) Function <stdio.h> Changes buffering mode of a file stream.
void setbuf(FILE *stream, char *buf) Function <stdio.h> Simplified interface for controlling stream buffering.
void setbuffer(FILE *stream, char *buf, size_t size) Function <stdio.h> Similar to setbuf() but allows custom buffer size.
STDOUT_FILENO Constant <unistd.h> File descriptor constant for standard output.
fileno(FILE *stream) Function <stdio.h> Returns the file descriptor associated with a FILE stream.
fdopen(int fd, const char *mode) Function <stdio.h> Creates a FILE stream from an existing file descriptor.

Abbreviation:

Abbreviation Description
ISA Instruction Set Architecture
OEM Original Equipment Manufacturers
CPL Current Privilege Level
ISR Interrupt service routine
PTE Page Table Entry
COW Copy-On-Write
KSM Kernel Samepage Merging
TM Transcendent Memory
ASLR Address Space Layout Randomization
BSS Block Started by Symbol
LIFO Last-In-First-Out
IP Instruction Pointer
(D)DoS (Distributed) denial-of-service
USB Universal Serial Bus
HDMI High Definition Multimedia Interface
API Application Programming Interface
IDT Interrupt Descriptor Table
LDD List Dynamic Dependency
fcntl File Control
O_CLOEXEC Close-on-Exec

It is a flag used when opening a file or setting its properties to ensure the file descriptor is automatically closed when the process performs an exec() call.
NOCTTY No Controlling TTY
a.out Assembler Output
ELF Executable and Linking Format
COFF Common Object File Format
etext End of Text
The first address after the program code (text segment).
edata End of Data

The first address after the initialized global/static variables (data segment).
end End of BSS

The first address after the uninitialized variables (bss segment). This is also the start of the Heap.
PMMU Paged Memory Management Unit

The PMMU translated each virtual memory address reference and advises the kernel of a page fault when a particular virtual memory address corresponds to a page that is not resident in RAM.
PLT Procedure Linkage Table

The PLT handles finding the real address of C library functions in RAM at runtime.
lr Link Register
NIS Network Information Services
MBR Master Boot Record

MBR is a legacy partitioning scheme located in the first sector (512 bytes) of a hard drive. It contains bootloader code and the partition table.
GPT GUID Partition Table

GPT is the modern partitioning standard that replaced MBR.

Why GPT is better than MBR
  • Supports disks larger than 2 TB.
  • Allows many primary partitions.
  • Stores backup partition tables for recovery.
  • Uses CRC32 for integrity checking.
Example
gdisk -l /dev/nvme0n1
UEFI Unified Extensible Firmware Interface

UEFI is modern firmware software that connects hardware to the OS and replaced BIOS.

Advantages
  • Fast booting
  • Large drive support
  • Secure Boot support
  • Modern graphical interface
Check UEFI Mode
ls /sys/firmware/efi
BIOS Basic Input/Output System

Legacy BIOS Boot Process
  • BIOS searches for the MBR.
  • The MBR contains bootloader code and partition table.
  • BIOS loads the first sector into RAM and executes it.
TOCTOU Time Of Check To Time Of Use

TOCTOU is a race condition vulnerability where:
  1. A program checks a condition (e.g., file permissions).
  2. Then later uses the result of that check.
  3. But in between, something changes.

Questions:

Q: What's a core dump?

Ans: A core dump is a snapshot of certain dynamic regions (segments) of the process at the time it crashed (technically, it's a snapshot of minimally the data and stack segments). The core dump can be analyzed postmortem using debuggers such as GDB.

Q: How does the system know that this region is protected and what kind of protection it has?

Ans:These details are encoded into the Paging Table Entry (PTEs) for the process, and are checked by the MMU on every access!

Q: How dynamic library works?

Ans:

  1. Program Startup.
  2. When you run a dynamically linked executable:
    • The kernel loads the executable's ELF header.
    • It sees that the program is dynamically linked and hands control to the dynamic loader.
  3. Reading the ELF Headers
  4. The dynamic loader:
    • Parses the ELF (Executable and Linkable Format) headers.
    • Identifies all required shared libraries listed in the .dynamic section
    • readelf -d executable_name --> with this cmd you can see your elf is dependent on which all .so files.
      OR
      ldd binary_name
  5. Locating Libraries
  6. It searches for each required library using:
    • /etc/ld.so.cache: A fast lookup cache.
    • LD_LIBRARY_PATH: Environment variable for custom paths.
    • /etc/ld.so.conf: Config file listing library directories.
    • Default paths: Like /lib, /usr/lib.
  7. Mapping Libraries into Memory
  8. Once found, each library is:
    • Mapped into the process’s address space using mmap.
    • The loader ensures that dependencies of libraries are also loaded.
    • e.g cat /proc/3393/maps | grep '.so' --> 3393 is process pid. 7f807a9000-7f807c8000 r-xp 00000000 103:23 2521 /usr/lib/libmnl.so.0.2.0
    • 7f807a9000-7f807c8000: Start and end addresses of the memory region.
    • r-xp: Permissions:
    • r: readable
    • w:writable
    • x:executable
    • p:private (copy-on-write)
    • 00000000:Offset into the file.
    • 103:23:Device ID (major:minor).
    • 2521:Inode number.
    • /usr/lib/libmnl.so.0.2.0:Path to the shared library.
  9. Relocation and Symbol Resolution
  10. The loader:
    • Resolves symbol references (e.g., function names) using the Global Offset Table (GOT) and Procedure Linkage Table (PLT).
    • Applies relocations so that function calls and variable accesses point to the correct memory addresses.
  11. Calling Initialization Functions
  12. Before handing control to main():
    • The loader calls any initialization routines in the libraries (like __init functions or constructors in C++).
  13. Execution Begins
    • Finally, control is passed to the program’s main() function, and execution begins with all libraries loaded and ready.

Q: What is diff between cmd > /dev/null and cmd > /dev/null 2>&1 ?

Ans:

  • /dev/null hides only stdout.
  • /dev/null 2>&1 hides both stdout and stderr

Q: How cmd > /dev/null 2>&1 works?

Ans:

  • /dev/null: Redirects stdout (file descriptor 1) of cmd to /dev/null (the “black hole”).
  • 2>&1: Redirects stderr (file descriptor 2) to where stdout is currently going. Since you already sent stdout to /dev/null, both stdout and stderr are suppressed.

Q: What is sysret?

Ans:sysret: The sysret instruction is the high-speed hardware mechanism used in x86-64 systems to return from a system call (CPL 0) to user space (CPL 3). Key Operations of sysret:
When the kernel executes sysret, the CPU performs the following actions in a single atomic step:

  • Restores Instruction Pointer: It loads the next instruction address to execute (RIP) directly from the RCX register.
  • Restores Processor Flags: It restores the system flags (RFLAGS) from the R11 register.
  • Switches Privilege Level: It changes the CPU's current privilege level from Ring 0 (Kernel) back to Ring 3 (User).
  • Updates Segment Selectors: It loads the Code Segment (CS) and Stack Segment (SS) registers with fixed values derived from the IA32_STAR Model-Specific Register(MSR).

Q: How kernel checks the page access belongs to a memory region the process is allowed to use?

Ans:When a Page Fault occurs (because the PTE is missing or invalid), the kernel doesn't immediately crash the program with a SIGSEGV.
Instead, it consults a secondary, higher-level map called the Virtual Memory Areas (VMAs).
While the Page Table is used by the Hardware (CPU), the VMA list is used by the Software (Kernel) to know what the memory should look like.
When a process tries to access memory, the kernel validates it using two layers:
the Page Table (Hardware level) and the VMA (Software level). Here is the summary of how it checks for a "legal" access:

  • The Trigger: The CPU tries to translate a virtual address using the Page Table Entry (PTE).
    If the PTE is missing or has incorrect permissions, a Page Fault is triggered, handing control to the kernel. The Linux Kernel - Memory Management.
  • The VMA Lookup: The kernel searches the process’s Virtual Memory Areas (VMAs)
    (a list of "allowed" memory regions like text, data, and stack) to see if the address falls within any valid range. The proc(5) man page -/proc/[pid]/maps
  • Permission Verification: If a VMA is found, the kernel compares the requested action (Read, Write, or Execute)
    against the VMA's permissions (e.g., trying to write to a read-only text segment).
  • The SIGSEGV Decision:
    1. Invalid: If the address is not in any VMA, or if the action violates VMA permissions, the kernel sends a SIGSEGV.
    2. Valid: If the address is in a VMA and the action is allowed, the kernel fixes the PTE
      (by loading data from disk or allocating RAM) and lets the program continue. GNU C Library - Signal Handling
  • We can see VMA detail in /proc/[PID]/maps file.

Releases

No releases published

Packages

 
 
 

Contributors