아무것도 몰라요

실험실 (커널 오류)

[NOVA] system call argument 추가 오류(2)

telomere37 2021. 7. 19. 16:42

지난 7/17에 마지막 시도를 해보다가 서버가 죽어버렸다. 월요일이 돼서야 학교에 와서 서버를 복구할 수 있었다. 오늘 약 6시간의 시도 끝에 드디어 해결을 하였다. 

File Descriptor는 File Pointer가 아니다!!!

// Test.c
#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>

int main() {
    FILE *fp;
    fp = fopen("/mnt/nova/file.txt","w");
    long int temp =0; 
    unsigned int fd = fileno(fp);
    temp = syscall(335,fd);
    if(!temp){
        printf("System Call well Implemented! Returned: % ld\n", temp);
    }   
    else {
        printf("Fail...\n");
    }   
    
    fclose(fp);
    return 0;
}

문제는 fp를 system call의 인자로 넣었다는 것이다. 지난번에 살펴본 것처럼 오류의 내용은 NULL pointer를 역참조한다는 것이었다. 따라서 f.file등에서 못읽고 있는 것이 아닐까라는 생각이 들었다. 그러고 자세히 생각해보니까... FILE *fp를 인자로 넘기는데 unsigned int로 받는다고..? 뭔가 이상했다. 

// dedup/dedup.c
#include<linux/kernel.h>
#include<linux/syscalls.h>
#include<linux/file.h>
#include<linux/fs.h>

int real_dedup(struct file *file){
  if(file->f_op->dedup)
    return file->f_op->dedup(1);
  return 0;
}

int ksys_dedup(unsigned int fd){
  struct fd f = fdget_pos(fd);
  if(f.file){
    return real_dedup(f.file);
  }
  return 0;
}


SYSCALL_DEFINE1(dedup, unsigned int, fd){
  return ksys_dedup(fd);
}

결국 fileno라는 함수를 사용하여 file descriptor를 읽어와서 system call을 호출하니 제대로 찾을 수 있었다. 

결국 제대로 실행된다!