• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
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_init(&key, &zero);  // update counter
46    (*val)++;
47    return 0;
48}
49"""
50
51    def license(self, lic):
52        return '''
53#define BPF_LICENSE %s
54''' % (lic)
55
56    def load_bpf_code(self, bpf_code):
57        event_name = bpf_code.get_syscall_fnname("read")
58        bpf_code.attach_kprobe(event=event_name, fn_name="license_program")
59        bpf_code.detach_kprobe(event=event_name)
60
61    def test_default(self):
62        b = BPF(text=self.gpl_only_text)
63        self.load_bpf_code(b)
64
65    def test_gpl_helper_macro(self):
66        b = BPF(text=self.gpl_only_text + self.license('GPL'))
67        self.load_bpf_code(b)
68
69    def test_proprietary_macro(self):
70        b = BPF(text=self.proprietary_text + self.license('Proprietary'))
71        self.load_bpf_code(b)
72
73    def test_gpl_compatible_macro(self):
74        b = BPF(text=self.gpl_only_text + self.license('Dual BSD/GPL'))
75        self.load_bpf_code(b)
76
77    def test_proprietary_words_macro(self):
78        b = BPF(text=self.proprietary_text + self.license('Proprietary license'))
79        self.load_bpf_code(b)
80
81    @unittest.expectedFailure
82    def test_cflags_fail(self):
83        b = BPF(text=self.gpl_only_text, cflags=["-DBPF_LICENSE=GPL"])
84        self.load_bpf_code(b)
85
86    @unittest.expectedFailure
87    def test_cflags_macro_fail(self):
88        b = BPF(text=self.gpl_only_text + self.license('GPL'), cflags=["-DBPF_LICENSE=GPL"])
89        self.load_bpf_code(b)
90
91    @unittest.expectedFailure
92    def test_empty_fail_macro(self):
93        b = BPF(text=self.gpl_only_text + self.license(''))
94        self.load_bpf_code(b)
95
96    @unittest.expectedFailure
97    def test_proprietary_fail_macro(self):
98        b = BPF(text=self.gpl_only_text + self.license('Proprietary license'))
99        self.load_bpf_code(b)
100
101    @unittest.expectedFailure
102    def test_proprietary_cflags_fail(self):
103        b = BPF(text=self.proprietary_text, cflags=["-DBPF_LICENSE=Proprietary"])
104        self.load_bpf_code(b)
105
106if __name__ == "__main__":
107    unittest.main()
108