forked from svarshavchik/vera
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathverac_check_hook.c
85 lines (69 loc) · 1.53 KB
/
verac_check_hook.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include "config.h"
#include "configdirs.h"
#include "verac.h"
#include <sys/un.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
const char reexec_envar[]="VERA_REEXEC_FD";
static int hooked(const char *hookfile, const char *init_path)
{
char buf[256];
struct stat pid1_stat, hookfile_stat;
FILE *fp;
if (stat(init_path, &pid1_stat) && errno == ENOENT)
return 1;
fp=fopen(hookfile, "r");
if (!fp)
return 0;
if (!fgets(buf, sizeof(buf), fp))
buf[0]=0;
fclose(fp);
strtok(buf, "\n");
if (stat("/proc/1", &pid1_stat) == 0 &&
stat(hookfile, &hookfile_stat) == 0 &&
pid1_stat.st_mtime == hookfile_stat.st_mtime)
return 0;
if (strcmp(buf, HOOKED_ON) == 0)
return 1;
if (strcmp(buf, HOOKED_ONCE) == 0)
return -1;
return 0;
}
const char *check_hookfile(const char *hookfile,
void (*run_sysinit_cb)(const char *inittab),
const char *init_path,
const char *vera_path)
{
int flag;
flag=getenv(reexec_envar) ? 1:hooked(hookfile, init_path);
if (!flag)
{
printf("vera: not hooked, running init\r\n");
fflush(stdout);
return init_path;
}
// vera is getting re-execed
if (!getenv(reexec_envar))
(*run_sysinit_cb)("/etc/inittab");
// Now that root is remounted read-write we can remove a one-time
// only hook.
if (flag < 0)
{
if (unlink(hookfile) < 0)
{
perror(hookfile);
}
else
{
printf("vera: one-time only hook removed\n");
sync();
sync();
}
}
return vera_path;
}