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#include "libbb.h"
40#include "common_bufsiz.h"
41
42#if ENABLE_SELINUX
43static void mkswap_selinux_setcontext(int fd, const char *path)
44{
45 struct stat stbuf;
46
47 if (!is_selinux_enabled())
48 return;
49
50 xfstat(fd, &stbuf, path);
51 if (S_ISREG(stbuf.st_mode)) {
52 security_context_t newcon;
53 security_context_t oldcon = NULL;
54 context_t context;
55
56 if (fgetfilecon(fd, &oldcon) < 0) {
57 if (errno != ENODATA)
58 goto error;
59 if (matchpathcon(path, stbuf.st_mode, &oldcon) < 0)
60 goto error;
61 }
62 context = context_new(oldcon);
63 if (!context || context_type_set(context, "swapfile_t"))
64 goto error;
65 newcon = context_str(context);
66 if (!newcon)
67 goto error;
68
69 if (strcmp(oldcon, newcon) != 0 && fsetfilecon(fd, newcon) < 0)
70 goto error;
71 if (ENABLE_FEATURE_CLEAN_UP) {
72 context_free(context);
73 freecon(oldcon);
74 }
75 }
76 return;
77 error:
78 bb_perror_msg_and_die("SELinux relabeling failed");
79}
80#else
81# define mkswap_selinux_setcontext(fd, path) ((void)0)
82#endif
83
84
85
86
87
88
89struct swap_header_v1 {
90
91 uint32_t version;
92 uint32_t last_page;
93 uint32_t nr_badpages;
94 char sws_uuid[16];
95 char sws_volume[16];
96 uint32_t padding[117];
97 uint32_t badpages[1];
98
99} FIX_ALIASING;
100
101#define NWORDS 129
102#define hdr ((struct swap_header_v1*)bb_common_bufsiz1)
103#define INIT_G() do { setup_common_bufsiz(); } while (0)
104
105struct BUG_sizes {
106 char swap_header_v1_wrong[sizeof(*hdr) != (NWORDS * 4) ? -1 : 1];
107 char bufsiz1_is_too_small[COMMON_BUFSIZE < (NWORDS * 4) ? -1 : 1];
108};
109
110
111static const char SWAPSPACE2[sizeof("SWAPSPACE2")-1] ALIGN1 = "SWAPSPACE2";
112
113int mkswap_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
114int mkswap_main(int argc UNUSED_PARAM, char **argv)
115{
116 int fd;
117 unsigned pagesize;
118 off_t len;
119 const char *label = "";
120
121 INIT_G();
122
123
124 getopt32(argv, "^" "L:" "\0" "-1", &label);
125 argv += optind;
126
127 fd = xopen(argv[0], O_WRONLY);
128
129
130 len = get_volume_size_in_bytes(fd, argv[1], 1024, 1);
131 pagesize = getpagesize();
132 len -= pagesize;
133
134
135 printf("Setting up swapspace version 1, size = %"OFF_FMT"u bytes\n", len);
136 mkswap_selinux_setcontext(fd, argv[0]);
137
138
139
140
141
142
143
144 xwrite(fd, hdr, 1024);
145
146
147 hdr->version = 1;
148 hdr->last_page = (uoff_t)len / pagesize;
149
150 if (ENABLE_FEATURE_MKSWAP_UUID) {
151 char uuid_string[32];
152 generate_uuid((void*)hdr->sws_uuid);
153 bin2hex(uuid_string, hdr->sws_uuid, 16);
154
155 printf("UUID=%.8s" "-%.4s-%.4s-%.4s-%.12s\n",
156 uuid_string,
157 uuid_string+8,
158 uuid_string+8+4,
159 uuid_string+8+4+4,
160 uuid_string+8+4+4+4
161 );
162 }
163 safe_strncpy(hdr->sws_volume, label, 16);
164
165
166
167 xwrite(fd, hdr, NWORDS * 4);
168 xlseek(fd, pagesize - 10, SEEK_SET);
169 xwrite(fd, SWAPSPACE2, 10);
170 fsync(fd);
171
172 if (ENABLE_FEATURE_CLEAN_UP)
173 close(fd);
174
175 return 0;
176}
177