OSDN Git Service

mksquashfsimge.sh: Support creating a sparse image
[android-x86/system-extras.git] / tests / iptables / qtaguid / socketTag.cpp
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless requied by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 /*
19  * This socket tagging test is to ensure that the
20  * netfilter/xt_qtaguid kernel module somewhat behaves as expected
21  * with respect to tagging sockets.
22  */
23 #include <assert.h>
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <inttypes.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <gtest/gtest.h>
30 #include <sys/socket.h>
31 #include <sys/types.h>
32 #include <string>
33
34 #define LOG_TAG "socketTagTest"
35 #include <utils/Log.h>
36 #include <testUtil.h>
37
38 namespace android {
39
40 class SockInfo {
41 public:
42     SockInfo() : fd(-1), addr(NULL) {};
43     int setup(uint64_t tag);
44     bool checkTag(uint64_t tag, uid_t uid);
45     int fd;
46     void *addr;
47 };
48
49
50 int openCtrl() {
51     int ctrl;
52     ctrl = open("/proc/net/xt_qtaguid/ctrl", O_RDWR);
53     if (!ctrl) {
54        testPrintE("qtaguid ctrl open failed: %s", strerror(errno));
55     }
56     return ctrl;
57 }
58
59 int doCtrlCommand(const char *fmt, ...)
60     __attribute__((__format__(__printf__, 1, 2)));
61
62 int doCtrlCommand(const char *fmt, ...) {
63     char *buff;
64     int ctrl;
65     int res;
66     va_list argp;
67
68     va_start(argp, fmt);
69     ctrl = openCtrl();
70     vasprintf(&buff, fmt, argp);
71     errno = 0;
72     res = write(ctrl, buff, strlen(buff));
73     testPrintI("cmd: '%s' res=%d %d/%s", buff, res, errno, strerror(errno));
74     close(ctrl);
75     free(buff);
76     va_end(argp);
77     return res;
78 }
79
80
81 int writeModuleParam(const char *param, const char *data) {
82     int param_fd;
83     int res;
84     std::string filename("/sys/module/xt_qtaguid/parameters/");
85
86     filename += param;
87     param_fd = open(filename.c_str(), O_WRONLY);
88     if (param_fd < 0) {
89         testPrintE("qtaguid param open failed: %s", strerror(errno));
90         return -1;
91     }
92     res = write(param_fd, data, strlen(data));
93     if (res < 0) {
94         testPrintE("qtaguid param write failed: %s", strerror(errno));
95     }
96     close(param_fd);
97     return res;
98 }
99
100 /*----------------------------------------------------------------*/
101 int SockInfo::setup(uint64_t tag) {
102     fd = socket(AF_INET, SOCK_STREAM, 0);
103     if (fd < 0) {
104         testPrintE("socket creation failed: %s", strerror(errno));
105         return -1;
106     }
107     if (doCtrlCommand("t %d %" PRIu64, fd, tag) < 0) {
108         testPrintE("socket setup: failed to tag");
109         close(fd);
110         return -1;
111     }
112     if (!checkTag(tag, getuid())) {
113         testPrintE("socket setup: Unexpected results: tag not found");
114         close(fd);
115         return -1;
116     }
117     if (doCtrlCommand("u %d", fd) < 0) {
118         testPrintE("socket setup: Unexpected results");
119         close(fd);
120         return -1;
121     }
122     return 0;
123 }
124
125 /* checkTag() also tries to lookup the socket address in the kernel and
126  * return it when *addr  == NULL.
127  * This allows for better look ups when another process is also setting the same
128  * tag + uid. But it is not fool proof.
129  * Without the kernel reporting more info on who setup the socket tag, it is
130  * not easily verifiable from user-space.
131  * Returns: true if tag found.
132  */
133 bool SockInfo::checkTag(uint64_t acct_tag, uid_t uid) {
134     int ctrl_fd;
135     ctrl_fd = openCtrl();
136     char ctrl_data[1024];
137     ssize_t read_size;
138     char *buff;
139     char *pos;
140     int res;
141     char *match_template;
142     uint64_t k_tag;
143     uint32_t k_uid;
144     uint64_t full_tag;
145     long dummy_count;
146     pid_t dummy_pid;
147
148     read_size = read(ctrl_fd, ctrl_data, sizeof(ctrl_data));
149     if (read_size < 0) {
150        testPrintE("Unable to read active tags from ctrl %d/%s",
151                   errno, strerror(errno));
152     }
153     ctrl_data[read_size] = '\0';
154     testPrintI("<ctrl_raw_data>\n%s</ctrl_raw_data>", ctrl_data);
155
156     if (addr) {
157         assert(sizeof(void*) == sizeof(long int));  // Why does %p use 0x? grrr. %lx.
158         asprintf(&match_template, "sock=%" PRIxPTR " %s", (uintptr_t)addr, "tag=0x%" PRIx64" (uid=%u)");
159     }
160     else {
161         /* Allocate for symmetry */
162         asprintf(&match_template, "%s", " tag=0x%" PRIx64 " (uid=%u)");
163     }
164
165     full_tag = acct_tag | uid;
166
167     asprintf(&buff, match_template, full_tag | uid, uid);
168     testPrintI("looking for '%s'", buff);
169     pos = strstr(ctrl_data, buff);
170
171     if (pos && !addr) {
172         assert(sizeof(void*) == sizeof(long int));  // Why does %p use 0x? grrr. %lx.
173         res = sscanf(pos - strlen("sock=1234abcd"),
174                      "sock=%" SCNxPTR " tag=0x%" SCNx64 " (uid=%" SCNu32 ") pid=%u f_count=%lu",
175                      (uintptr_t *)&addr, &k_tag, &k_uid, &dummy_pid, &dummy_count );
176         if (!(res == 5 && k_tag == full_tag && k_uid == uid)) {
177             testPrintE("Unable to read sock addr res=%d", res);
178            addr = 0;
179         }
180         else {
181             testPrintI("Got sock_addr %lx", addr);
182         }
183     }
184     free(buff);
185     free(match_template);
186     close(ctrl_fd);
187     return pos != NULL;
188 }
189
190
191 class SocketTaggingTest : public ::testing::Test {
192 protected:
193     virtual void SetUp() {
194         ctrl_fd = -1;
195         dev_fd = -1;
196         my_uid = getuid();
197         my_pid = getpid();
198         srand48(my_pid * my_uid);
199         // Adjust fake UIDs and tags so that multiple instances can run in parallel.
200         fake_uid = testRand();
201         fake_uid2 = testRand();
202         valid_tag1 = ((uint64_t)my_pid << 48) | ((uint64_t)testRand() << 32);
203         valid_tag2 = ((uint64_t)my_pid << 48) | ((uint64_t)testRand() << 32);
204         valid_tag2 &= 0xffffff00ffffffffllu;  // Leave some room to make counts visible.
205         testPrintI("* start: pid=%lu uid=%lu uid1=0x%lx/%lu uid2=0x%lx/%lu"
206                    " tag1=0x%" PRIx64 "/%" PRIu64 " tag2=0x%" PRIx64 "/% "PRIu64,
207                    (unsigned long)my_pid, (unsigned long)my_uid,
208                    (unsigned long)fake_uid, (unsigned long)fake_uid,
209                    (unsigned long)fake_uid2, (unsigned long)fake_uid2,
210                    valid_tag1, valid_tag1, valid_tag2, valid_tag2);
211         max_uint_tag = 0xffffffff00000000llu;
212         max_uint_tag = 1llu << 63 | (((uint64_t)my_pid << 48) ^ max_uint_tag);
213
214         testPrintI("kernel has qtaguid");
215         ctrl_fd = openCtrl();
216         ASSERT_GE(ctrl_fd, 0) << "qtaguid ctrl open failed";
217         close(ctrl_fd);
218         dev_fd = open("/dev/xt_qtaguid", O_RDONLY);
219         EXPECT_GE(dev_fd, 0) << "qtaguid dev open failed";
220
221         // We want to clean up any previous faulty test runs.
222         testPrintI("delete command does not fail");
223         EXPECT_GE(doCtrlCommand("d 0 %u", fake_uid), 0) << "Failed to delete fake_uid";
224         EXPECT_GE(doCtrlCommand("d 0 %u", fake_uid2), 0) << "Failed to delete fake_uid2";
225         EXPECT_GE(doCtrlCommand("d 0 %u", my_uid), 0) << "Failed to delete my_uid";
226
227         testPrintI("setup sock0 and addr via tag");
228         ASSERT_FALSE(sock0.setup(valid_tag1))  << "socket0 setup failed";
229         testPrintI("setup sock1 and addr via tag");
230         ASSERT_FALSE(sock1.setup(valid_tag1))  << "socket1 setup failed";
231     }
232
233    virtual void TearDown() {
234        if (dev_fd >= 0) {
235            close(dev_fd);
236        }
237        if (ctrl_fd >= 0) {
238            close(ctrl_fd);
239        }
240    }
241
242    SockInfo sock0;
243    SockInfo sock1;
244    int ctrl_fd;
245    int dev_fd;
246    uid_t fake_uid;
247    uid_t fake_uid2;
248    uid_t my_uid;
249    pid_t my_pid;
250    uint64_t valid_tag1;
251    uint64_t valid_tag2;
252    uint64_t max_uint_tag;
253    static const uint64_t invalid_tag1 = 0x0000000100000001llu;
254    static const int max_tags = 5;
255 };
256
257 TEST_F(SocketTaggingTest, TagData) {
258     max_uint_tag = 0xffffffff00000000llu;
259     char *max_tags_str;
260
261     testPrintI("setup tag limit");
262     asprintf(&max_tags_str, "%d", max_tags);
263     ASSERT_GE(writeModuleParam("max_sock_tags", max_tags_str), 0) << "Failed to setup tag limit";
264
265     testPrintI("tag quota reach limit");
266     for (int cnt = 0; cnt < max_tags; cnt++ ) {
267         uint64_t tag = valid_tag2 + ((uint64_t)cnt << 32);
268         EXPECT_GE(doCtrlCommand("t %d %" PRIu64 " %u", sock0.fd, tag , fake_uid2), 0)
269             << "Tagging within limit failed";
270         EXPECT_TRUE(sock0.checkTag(tag, fake_uid2))<<  "Unexpected results: tag not found";
271     }
272
273     testPrintI("tag quota go over limit");
274     uint64_t new_tag = valid_tag2 + ((uint64_t)max_tags << 32);
275     EXPECT_LT(doCtrlCommand("t %d %" PRIu64 " %u", sock0.fd, new_tag, fake_uid2), 0);
276     EXPECT_TRUE(sock0.checkTag(valid_tag2 + (((uint64_t)max_tags - 1) << 32),
277                                fake_uid2)) << "Unexpected results: tag not found";
278
279     testPrintI("valid untag");
280     EXPECT_GE(doCtrlCommand("u %d", sock0.fd), 0);
281     EXPECT_FALSE(sock0.checkTag(valid_tag2 + (((uint64_t)max_tags - 1) << 32), fake_uid2))
282         << "Untagged tag should not be there";
283
284     testPrintI("tag after untag should not free up max tags");
285     uint64_t new_tag2 = valid_tag2 + ((uint64_t)max_tags << 32);
286     EXPECT_LT(doCtrlCommand("t %d %" PRIu64 " %u", sock0.fd, new_tag2 , fake_uid2), 0);
287     EXPECT_FALSE(sock0.checkTag(valid_tag2 + ((uint64_t)max_tags << 32), fake_uid2))
288         << "Tag should not be there";
289
290     testPrintI("delete one tag");
291     uint64_t new_tag3 = valid_tag2 + (((uint64_t)max_tags / 2) << 32);
292     EXPECT_GE(doCtrlCommand("d %" PRIu64 " %u", new_tag3, fake_uid2), 0);
293
294     testPrintI("2 tags after 1 delete pass/fail");
295     uint64_t new_tag4;
296     new_tag4 = valid_tag2 + (((uint64_t)max_tags + 1 ) << 32);
297     EXPECT_GE(doCtrlCommand("t %d %" PRIu64 " %u", sock0.fd, new_tag4 , fake_uid2), 0);
298     EXPECT_TRUE(sock0.checkTag(valid_tag2 + (((uint64_t)max_tags + 1) << 32), fake_uid2))
299         << "Tag not found";
300     new_tag4 = valid_tag2 + (((uint64_t)max_tags + 2 ) << 32);
301     EXPECT_LT(doCtrlCommand("t %d %" PRIu64 " %u", sock0.fd, new_tag4 , fake_uid2), 0);
302     EXPECT_FALSE(sock0.checkTag(valid_tag2 + (((uint64_t)max_tags + 2) << 32), fake_uid2))
303         << "Tag should not be there";
304
305     /* TODO(jpa): test tagging two different sockets with same tags and
306      * check refcounts  the tag_node should be +2
307      */
308 }
309
310 TEST_F(SocketTaggingTest, InsufficientArgsFails) {
311     // Insufficient args. Expected failure
312     EXPECT_LE(doCtrlCommand("t"), 0) << "Insufficient args, should fail.";
313 }
314
315 TEST_F(SocketTaggingTest, BadCommandFails) {
316     // Bad command. Expected failure";
317     EXPECT_LE(doCtrlCommand("?"), 0) << "Bad command, should fail";
318 }
319
320 TEST_F(SocketTaggingTest, NoTagNoUid) {
321     // no tag, no uid
322     EXPECT_GE(doCtrlCommand("t %d", sock0.fd), 0);
323     ASSERT_TRUE(sock0.checkTag(0, my_uid))  << "Tag not found";
324 }
325
326 TEST_F(SocketTaggingTest, InvalidTagFail) {
327     // Invalid tag. Expected failure
328     EXPECT_LE(doCtrlCommand("t %d %" PRIu64, sock0.fd, invalid_tag1), 0);
329     ASSERT_FALSE(sock0.checkTag(invalid_tag1, my_uid)) << "Tag should not be there";
330 }
331
332 TEST_F(SocketTaggingTest, ValidTagWithNoUid) {
333     // Valid tag with no uid
334     EXPECT_GE(doCtrlCommand("t %d %" PRIu64, sock0.fd, valid_tag1), 0);
335     EXPECT_TRUE(sock0.checkTag(valid_tag1, my_uid)) << "Tag not found";
336 }
337
338 TEST_F(SocketTaggingTest, ValidUntag) {
339     // Valid untag
340     EXPECT_GE(doCtrlCommand("t %d %" PRIu64, sock0.fd, valid_tag1), 0);
341     EXPECT_TRUE(sock0.checkTag(valid_tag1, my_uid)) << "Tag not found";
342     EXPECT_GE(doCtrlCommand("u %d", sock0.fd), 0);
343     EXPECT_FALSE(sock0.checkTag(valid_tag1, my_uid)) << "Tag should be removed";
344 }
345
346 TEST_F(SocketTaggingTest, ValidFirsttag) {
347     // Valid 1st tag
348     EXPECT_GE(doCtrlCommand("t %d %" PRIu64 " %u", sock0.fd, valid_tag2, fake_uid), 0);
349     EXPECT_TRUE(sock0.checkTag(valid_tag2, fake_uid)) << "Tag not found.";
350 }
351
352 TEST_F(SocketTaggingTest, ValidReTag) {
353     // Valid re-tag
354     EXPECT_GE(doCtrlCommand("t %d %" PRIu64 " %u", sock0.fd, valid_tag2, fake_uid), 0);
355     EXPECT_GE(doCtrlCommand("t %d %" PRIu64 " %u", sock0.fd, valid_tag2, fake_uid), 0);
356     EXPECT_TRUE(sock0.checkTag(valid_tag2, fake_uid)) << "Tag not found.";
357 }
358
359 TEST_F(SocketTaggingTest, ValidReTagWithAcctTagChange) {
360     // Valid re-tag with acct_tag change
361     EXPECT_GE(doCtrlCommand("t %d %" PRIu64 " %u", sock0.fd, valid_tag2, fake_uid), 0);
362     EXPECT_GE(doCtrlCommand("t %d %" PRIu64 " %u", sock0.fd, valid_tag1, fake_uid), 0);
363     EXPECT_TRUE(sock0.checkTag(valid_tag1, fake_uid)) << "Tag not found.";
364 }
365
366 TEST_F(SocketTaggingTest, ReTagWithUidChange) {
367     // Re-tag with uid change
368     EXPECT_GE(doCtrlCommand("t %d %" PRIu64 " %u", sock0.fd, valid_tag1, fake_uid), 0);
369     EXPECT_GE(doCtrlCommand("t %d %" PRIu64 " %u", sock0.fd, valid_tag2, fake_uid2), 0);
370 }
371
372 TEST_F(SocketTaggingTest, Valid64BitAcctTag) {
373     // Valid 64bit acct tag
374     EXPECT_GE(doCtrlCommand("t %d %" PRIu64, sock0.fd, max_uint_tag), 0);
375     EXPECT_TRUE(sock0.checkTag(max_uint_tag, my_uid)) << "Tag not found.";
376 }
377
378 TEST_F(SocketTaggingTest, TagAnotherSocket) {
379     testPrintI("Tag two sockets");
380     EXPECT_GE(doCtrlCommand("t %d %" PRIu64, sock0.fd, max_uint_tag), 0);
381     EXPECT_GE(doCtrlCommand("t %d %" PRIu64 " %u", sock1.fd, valid_tag1, fake_uid2), 0);
382     EXPECT_TRUE(sock1.checkTag(valid_tag1, fake_uid2)) << "Tag not found.";
383     testPrintI("Untag socket0 of them only.");
384     EXPECT_GE(doCtrlCommand("u %d", sock0.fd), 0);
385     EXPECT_FALSE(sock0.checkTag(max_uint_tag, fake_uid)) << "Tag should not be there";
386     EXPECT_TRUE(sock1.checkTag(valid_tag1, fake_uid2)) << "Tag not found";
387     testPrintI("Now untag socket1 as well.");
388     EXPECT_GE(doCtrlCommand("u %d", sock1.fd), 0);
389     EXPECT_FALSE(sock1.checkTag(valid_tag1, fake_uid2)) << "Tag should not be there";
390 }
391
392 TEST_F(SocketTaggingTest, TagInvalidSocketFail) {
393     // Invalid tag. Expected failure
394     close(sock0.fd);
395     EXPECT_LE(doCtrlCommand("t %d %" PRIu64 " %u", sock0.fd, valid_tag1, my_uid), 0);
396     EXPECT_FALSE(sock0.checkTag(valid_tag1, my_uid)) << "Tag should not be there";
397 }
398
399 TEST_F(SocketTaggingTest, UntagInvalidSocketFail) {
400     // Invalid untag. Expected failure";
401     close(sock1.fd);
402     EXPECT_LE(doCtrlCommand("u %d", sock1.fd), 0);
403 }
404
405 }  // namespace android