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