4.系統呼叫如何安全地獲取引數

INnoVation-V2發表於2024-04-21

5.系統呼叫如何安全地獲取引數

直接傳遞給kernel資料的地址(指標)?,

  1. 核心和使用者的頁表不同,不能直接訪問使用者地址
  2. 可能會傳遞核心記憶體地址,直接訪問就是安全漏洞

因此核心不能使用普通指令從使用者提供的地址載入或儲存。 核心實現了一些函式,可以安全地在使用者提供的地址之間傳輸資料。

fetchstr是一個例子(kernel/syscall.c:25)。檔案系統呼叫,如exec,就使用fetchstr從使用者空間檢索字串檔名引數。

方法就是利用使用者頁表對地址進行訪問,將資料複製到一個臨時建立的陣列中使用,這樣如果地址不合法,使用者頁表是無法解析的

5.1 fetchstr()

int fetchstr(uint64 addr, char *buf, int max)
{
  struct proc *p = myproc();
  //將user pagetable傳遞過去
  if(copyinstr(p->pagetable, buf, addr, max) < 0)
    return -1;
  return strlen(buf);
}

5.2 copyinstr()

int copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max)
{
  uint64 n, va0, pa0;
  int got_null = 0;

  while(got_null == 0 && max > 0){
    va0 = PGROUNDDOWN(srcva);
    pa0 = walkaddr(pagetable, va0);
    if(pa0 == 0)
      return -1;
    n = PGSIZE - (srcva - va0);
    if(n > max)
      n = max;

    char *p = (char *) (pa0 + (srcva - va0));
    while(n > 0){
      if(*p == '\0'){
        *dst = '\0';
        got_null = 1;
        break;
      } else {
        *dst = *p;
      }
      --n;
      --max;
      p++;
      dst++;
    }

    srcva = va0 + PGSIZE;
  }
  if(got_null){
    return 0;
  } else {
    return -1;
  }
}

相關文章