• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

twilight0966

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

2025-2026-1 20231301 《信息安全设计》第九周学习总结

2025-2026-1 20231301 《信息安全设计》第九周学习总结

目录
  • 作业信息
  • 学习内容总结
    • 1. 进程的本质
    • 2. 系统调用层次结构
    • 3. 进程创建与执行完整流程
    • exec() 函数家族对比表
      • 实用示例:安全的命令执行
    • 安全编程实践
      • system() 的安全风险与防护
    • 思维导图

作业信息

作业 链接
作业课程 <班级>(2025-2026-1 信息安全设计)
作业要求 <作业>(2025-2026-1 信息安全设计 预习作业要求)
作业目标 《Head First C 嗨翻C语⾔》> 预习第九章
作业正文 <博客>(第九周学习总结)

学习内容总结

第九章:进程与系统调用

1. 进程的本质

进程是正在执行的程序实例,每个进程都有独立的:

  • 内存空间
  • 文件描述符表
  • 环境变量
  • 进程状态(运行、睡眠、停止等)

2. 系统调用层次结构

应用程序 → C标准库 → 系统调用接口 → 操作系统内核 → 硬件资源

3. 进程创建与执行完整流程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>

void demonstrate_fork_exec() {
    pid_t pid = fork();
    
    if (pid == -1) {
        perror("fork failed");
        exit(1);
    }
    else if (pid == 0) {
        // 子进程
        printf("Child process: PID = %d, Parent PID = %d\n", 
               getpid(), getppid());
        
        // 执行 ls 命令
        execl("/bin/ls", "ls", "-l", "-a", NULL);
        
        // 如果 execl 成功,不会执行到这里
        perror("execl failed");
        exit(1);
    }
    else {
        // 父进程
        printf("Parent process: PID = %d, Child PID = %d\n", 
               getpid(), pid);
        
        int status;
        waitpid(pid, &status, 0);  // 等待子进程结束
        
        if (WIFEXITED(status)) {
            printf("Child exited with status: %d\n", WEXITSTATUS(status));
        }
    }
}

exec() 函数家族对比表

函数名 参数类型 搜索PATH 环境变量
execl() 参数列表 否 继承
execle() 参数列表 否 自定义
execlp() 参数列表 是 继承
execv() 参数数组 否 继承
execvp() 参数数组 是 继承
execve() 参数数组 否 自定义

实用示例:安全的命令执行

#include <errno.h>

int safe_system_call(const char* command) {
    pid_t pid = fork();
    
    if (pid == 0) {
        // 子进程 - 使用 shell 执行命令
        execl("/bin/sh", "sh", "-c", command, NULL);
        _exit(127); // 如果 exec 失败
    }
    else if (pid > 0) {
        // 父进程 - 等待子进程
        int status;
        while (waitpid(pid, &status, 0) == -1) {
            if (errno != EINTR) {
                return -1; // 等待失败
            }
        }
        return status;
    }
    else {
        return -1; // fork 失败
    }
}

安全编程实践

system() 的安全风险与防护

危险示例:

// UNSAFE! 容易受到命令注入攻击
char user_input[100];
scanf("%99s", user_input);
char command[200];
sprintf(command, "echo '%s' >> log.txt", user_input);
system(command);

安全改进:

// 安全的替代方案
void safe_log_entry(const char* entry) {
    FILE* log_file = fopen("log.txt", "a");
    if (log_file) {
        fprintf(log_file, "%s\n", entry);
        fclose(log_file);
    }
}

// 或者使用 exec 系列函数
void safe_system_log(const char* entry) {
    pid_t pid = fork();
    if (pid == 0) {
        // 在子进程中直接调用 echo
        execl("/bin/echo", "echo", entry, NULL);
        _exit(1);
    }
    wait(NULL);
}

思维导图

第9章:进程与系统调用
├── 进程基础
│   ├── 进程概念
│   ├── PID/PPID
│   └── 进程状态
├── 系统调用
│   ├── system()
│   ├── exec()家族
│   ├── fork()
│   └── wait()/waitpid()
├── 错误处理
│   ├── errno变量
│   ├── perror()
│   └── strerror()
└── 安全实践
    ├── 命令注入防护
    └── 权限控制

posted on 2025-09-30 21:54  20231301周子昂  阅读(11)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3