0

我已经阅读了我想知道的 Fanotify 和 flag FAN_DENY 的手册页。

我没有找到任何使用 FAN_DENY 的示例。

手册页:http ://www.xypron.de/projects/fanotify-manpages/man7/fanotify.7.html

4

1 回答 1

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;
}
于 2014-04-07T16:50:03.243 回答