• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# Copyright (c) 2018 Clevernet, Inc.
3# Licensed under the Apache License, Version 2.0 (the "License")
4
5import unittest
6from bcc import BPF
7
8class TestLicense(unittest.TestCase):
9    gpl_only_text = """
10#include <uapi/linux/ptrace.h>
11struct gpl_s {
12    u64 ts;
13};
14BPF_PERF_OUTPUT(events);
15int license_program(struct pt_regs *ctx) {
16    struct gpl_s data = {};
17    data.ts = bpf_ktime_get_ns();
18    events.perf_submit(ctx, &data, sizeof(data));
19    return 0;
20}
21"""
22
23    proprietary_text = """
24#include <uapi/linux/ptrace.h>
25struct key_t {
26    u64 ip;
27    u32 pid;
28    u32 uid;
29    char comm[16];
30};
31
32BPF_HASH(counts, struct key_t);
33
34int license_program(struct pt_regs *ctx) {
35    struct key_t key = {};
36    u64 zero = 0 , *val;
37    u64 pid = bpf_get_current_pid_tgid();
38    u32 uid = bpf_get_current_uid_gid();
39
40    key.ip = PT_REGS_IP(ctx);
41    key.pid = pid & 0xFFFFFFFF;
42    key.uid = uid & 0xFFFFFFFF;
43    bpf_get_current_comm(&(key.comm), 16);
44
45    val = counts.lookup_or_try_init(&key, &zero);  // update counter
46    if (val) {
47        (*val)++;
48    }
49    return 0;
50}
51"""
52
53    def license(self, lic):
54        return '''
55#define BPF_LICENSE %s
56''' % (lic)
57
58    def load_bpf_code(self, bpf_code):
59        event_name = bpf_code.get_syscall_fnname("read")
60        bpf_code.attach_kprobe(event=event_name, fn_name="license_program")
61        bpf_code.detach_kprobe(event=event_name)
62
63    def test_default(self):
64        b = BPF(text=self.gpl_only_text)
65        self.load_bpf_code(b)
66
67    def test_gpl_helper_macro(self):
68        b = BPF(text=self.gpl_only_text + self.license('GPL'))
69        self.load_bpf_code(b)
70
71    def test_proprietary_macro(self):
72        b = BPF(text=self.proprietary_text + self.license('Proprietary'))
73        self.load_bpf_code(b)
74
75    def test_gpl_compatible_macro(self):
76        b = BPF(text=self.gpl_only_text + self.license('Dual BSD/GPL'))
77        self.load_bpf_code(b)
78
79    def test_proprietary_words_macro(self):
80        b = BPF(text=self.proprietary_text + self.license('Proprietary license'))
81        self.load_bpf_code(b)
82
83    @unittest.expectedFailure
84    def test_cflags_fail(self):
85        b = BPF(text=self.gpl_only_text, cflags=["-DBPF_LICENSE=GPL"])
86        self.load_bpf_code(b)
87
88    @unittest.expectedFailure
89    def test_cflags_macro_fail(self):
90        b = BPF(text=self.gpl_only_text + self.license('GPL'), cflags=["-DBPF_LICENSE=GPL"])
91        self.load_bpf_code(b)
92
93    @unittest.expectedFailure
94    def test_empty_fail_macro(self):
95        b = BPF(text=self.gpl_only_text + self.license(''))
96        self.load_bpf_code(b)
97
98    @unittest.expectedFailure
99    def test_proprietary_fail_macro(self):
100        b = BPF(text=self.gpl_only_text + self.license('Proprietary license'))
101        self.load_bpf_code(b)
102
103    @unittest.expectedFailure
104    def test_proprietary_cflags_fail(self):
105        b = BPF(text=self.proprietary_text, cflags=["-DBPF_LICENSE=Proprietary"])
106        self.load_bpf_code(b)
107
108if __name__ == "__main__":
109    unittest.main()
110