forked from yrp604/rappel
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexedir.c
More file actions
145 lines (109 loc) · 2.34 KB
/
Copy pathexedir.c
File metadata and controls
145 lines (109 loc) · 2.34 KB
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include "common.h"
#include "exedir.h"
#define TMPDIR ".rappel"
static
void _cd_exedir()
{
const char *const home = getenv("HOME");
if (!home) {
fprintf(stderr, "HOME not set");
exit(EXIT_FAILURE);
}
REQUIRE (chdir(home) == 0);
if (mkdir(TMPDIR, 0755) == -1) {
if (errno != EEXIST) {
perror("mkdir");
exit(EXIT_FAILURE);
}
}
REQUIRE (chdir(TMPDIR) == 0);
}
static const
int _reopen_ro(
const int h,
const char *const path)
{
REQUIRE (close(h) == 0);
const int ro_h = open(path, O_RDONLY | O_CLOEXEC);
if (ro_h < 0) {
perror("open");
exit(EXIT_FAILURE);
}
return ro_h;
}
void clean_exedir()
{
char initial_cwd[PATH_MAX];
REQUIRE (getcwd(initial_cwd, PATH_MAX) != NULL);
_cd_exedir();
DIR *exedir = opendir(".");
if (!exedir) {
perror("opendir");
exit(EXIT_FAILURE);
}
struct dirent *f;
while ((f = readdir(exedir))) {
if (!strcmp(f->d_name, ".") || !strcmp(f->d_name, ".."))
continue;
if (unlink(f->d_name) == -1)
fprintf(stderr, "Cannot unlink: %s", f->d_name);
}
REQUIRE (closedir(exedir) == 0);
REQUIRE (chdir(initial_cwd) == 0);
}
const
int write_exe(
const uint8_t *data,
const size_t data_sz,
const char *name)
{
if (name)
return write_named_file(data, data_sz, name);
else
return write_tmp_file(data, data_sz);
}
const
int write_named_file(
const uint8_t *data,
const size_t data_sz,
const char *name)
{
const int h = open(name, O_WRONLY | O_CREAT,
S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
if (h < 0) {
perror("open");
exit(EXIT_FAILURE);
}
write_data(h, data, data_sz);
return _reopen_ro(h, name);
}
const
int write_tmp_file(
const uint8_t *data,
const size_t data_sz)
{
char path[PATH_MAX], initial_cwd[PATH_MAX];
REQUIRE (getcwd(initial_cwd, PATH_MAX) != NULL);
_cd_exedir();
snprintf(path, sizeof(path), "rappel-exec.XXXXXX");
const int h = mkstemp(path);
if (h < 0) {
perror("mkstemp");
exit(EXIT_FAILURE);
}
write_data(h, data, data_sz);
REQUIRE (fchmod(h, S_IXUSR | S_IRUSR | S_IWUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0);
const int h_ro = _reopen_ro(h, path);
REQUIRE (chdir(initial_cwd) == 0);
return h_ro;
}