2014-02-22 8 views

답변

0

FAN_DENY에 대한 연구, 발견 필요한 문서 후.

예 :

/* 
    Technical details: 

    Fanotify is a system for handle file system actions, default in Linux kernel since 2.6. 
*/ 

#define _GNU_SOURCE 
#define _ATFILE_SOURCE 
#include <linux/fanotify.h> 
#include <errno.h> 
#include <inttypes.h> 
#include <fcntl.h> 
#include <linux/limits.h> 
#include <signal.h> 
#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

//#define FANOTIFY_ARGUMENTS "cdfhmnp" 
int fan_fd; 

/* Mark a object */ 
int mark_object(int fan_fd, const char *path, int fd, uint64_t mask, unsigned int flags) 
{ 
    return fanotify_mark(fan_fd, flags, mask, fd, path); 
} 

/* Usage */ 
int usage(char** file[]) 
{ 
    fprintf(stdout, "Application for deny acess to your files.\nUsage: %s [file]\n", file[0]); 
} 

/* Main */ 
int main(int argc, char** argv[]) 
{ 
    /* Check for arguments.. */ 
    if(argc != 2) // if user not give file argument 
    { 
    usage(argv); 
    return 1; 
    } 
    /* Fanotify options */ 
    uint64_t fan_mask = FAN_OPEN | FAN_CLOSE | FAN_ACCESS | FAN_MODIFY | FAN_EVENT_ON_CHILD | FAN_ALL_PERM_EVENTS; 
    unsigned int mark_flags = FAN_MARK_ADD, init_flags = 0; 
    /* Other declarations */ 
    ssize_t len; 
    char buf[4096]; 
    fd_set rfds; 
    /* Initalize Fanotify */ 
    if(fan_mask & FAN_ALL_PERM_EVENTS) 
    init_flags |= FAN_CLASS_CONTENT; 
    else 
    init_flags |= FAN_CLASS_NOTIF; 
    fan_fd = fanotify_init(init_flags, O_RDONLY | O_LARGEFILE); 
    if(fan_fd < 0) 
    { 
    goto fail; 
    } 
    /* Mark object/Initalize object control with Fanotify */ 
    for(; optind < argc; optind++) 
    { 
     if(mark_object(fan_fd, argv[optind], AT_FDCWD, fan_mask, mark_flags) != 0) 
     { 
     //fprintf(stderr, "Can`t set Fanotify on this file '%s'!", argv[optind]); 
     goto fail; 
     //return 1; 
     } 
    } 
    /* Restore fan_fd variable */ 
    FD_ZERO(&rfds); 
    FD_SET(fan_fd, &rfds); 
    /* Loop for start another loop for check fanotify events */ 
    while((len = read(fan_fd, buf, sizeof(buf))) > 0) 
    { 
     /* Declarations */ 
     struct fanotify_event_metadata *metadata; 
     struct fanotify_response response; 
     char path[PATH_MAX]; 
     int path_len; 
     metadata = (void *)buf; 

     /* New loop for check fanotify events */ 
     while(FAN_EVENT_OK(metadata, len)) 
     { 
      /* Check if fanotify version are too old */ 
      if(metadata->vers < 2) 
      { 
      fprintf(stderr, "Kernel fanotify version too old\n"); 
      return 1; 
      } 
      /* Get path that acesser trys */ 
      if(metadata->fd >= 0) 
      { 
      sprintf(path, "/proc/self/fd/%d", metadata->fd); 
      path_len = readlink(path, path, sizeof(path)-1); 
      if(path_len < 0) 
       goto fail; 
      path[path_len] = '\0'; 
      fprintf(stdout, "%s:", path); 
     } 
      /* Can`t get path */ 
      else 
      { 
       fprintf(stdout, "?:"); 
      } 
      if(!strcmp(path, argv[1])) 
      { 
      response.fd = metadata->fd; 
      response.response = FAN_DENY; 
      write(fan_fd, &response, sizeof(struct fanotify_response)); 
      } 
      /* Pid of acesser */ 
      fprintf(stdout, " pid=%ld", (long)metadata->pid); 
      /* Check actions by acesser and kill acesser */ 
      if(metadata->mask & FAN_ACCESS) 
      { 
     fprintf(stdout, " access"); 
      if(!strcmp(path, argv[1])) 
      { 
       response.fd = metadata->fd; 
       response.response = FAN_DENY; 
       write(fan_fd, &response, sizeof(struct fanotify_response)); 
      } 
      } 
     if(metadata->mask & FAN_OPEN) 
      { 
     fprintf(stdout, " open"); 
      if(!strcmp(path, argv[1])) 
      { 
       response.fd = metadata->fd; 
       response.response = FAN_DENY; 
       write(fan_fd, &response, sizeof(struct fanotify_response)); 
      } 
      } 
     if(metadata->mask & FAN_MODIFY) 
      { 
     fprintf(stdout, " modify"); 
      if(!strcmp(path, argv[1])) 
      { 
       response.fd = metadata->fd; 
       response.response = FAN_DENY; 
       write(fan_fd, &response, sizeof(struct fanotify_response)); 
      } 
      } 
     if(metadata->mask & FAN_CLOSE) 
      { 
       if(metadata->mask & FAN_CLOSE_WRITE) 
      fprintf(stdout, " close(writable)"); 
      } 
      /* Setup the output */ 
      fprintf(stdout, "\n"); 
      fflush(stdout); 
      /* Check for internal error */ 
      if(metadata->fd >= 0 && close(metadata->fd) != 0) 
      { 
     goto fail; 
      } 
      /* Next fanotify event.. */ 
      metadata = FAN_EVENT_NEXT(metadata, len); 
     } // end of loop 2 
    } // end of loop 1 

    /* Check for len error */ 
    if(len < 0) 
    { 
    goto fail; 
    } 
    /* Declare fail */ 
fail: 
    fprintf(stderr, "%s\n", strerror(errno)); 
    return 1; 
    /* Quit */ 
    return 0; 
}