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