1251875Speter// SPDX-License-Identifier: GPL-2.0 2251875Speter#include <netinet/in.h> 3251875Speter#include <linux/bpf.h> 4251875Speter#include <bpf/bpf_helpers.h> 5251875Speter 6251875Speterchar _license[] SEC("license") = "GPL"; 7251875Speter 8251875Speter__s32 page_size = 0; 9251875Speter 10251875SpeterSEC("cgroup/getsockopt") 11251875Speterint _getsockopt_child(struct bpf_sockopt *ctx) 12251875Speter{ 13251875Speter __u8 *optval_end = ctx->optval_end; 14251875Speter __u8 *optval = ctx->optval; 15251875Speter 16251875Speter if (ctx->level != SOL_IP || ctx->optname != IP_TOS) 17251875Speter goto out; 18251875Speter 19251875Speter if (optval + 1 > optval_end) 20251875Speter return 0; /* EPERM, bounds check */ 21251875Speter 22251875Speter if (optval[0] != 0x80) 23251875Speter return 0; /* EPERM, unexpected optval from the kernel */ 24251875Speter 25251875Speter ctx->retval = 0; /* Reset system call return value to zero */ 26251875Speter 27251875Speter optval[0] = 0x90; 28251875Speter ctx->optlen = 1; 29251875Speter 30251875Speter return 1; 31251875Speter 32251875Speterout: 33251875Speter /* optval larger than PAGE_SIZE use kernel's buffer. */ 34251875Speter if (ctx->optlen > page_size) 35251875Speter ctx->optlen = 0; 36251875Speter return 1; 37251875Speter} 38251875Speter 39251875SpeterSEC("cgroup/getsockopt") 40251875Speterint _getsockopt_parent(struct bpf_sockopt *ctx) 41251875Speter{ 42251875Speter __u8 *optval_end = ctx->optval_end; 43251875Speter __u8 *optval = ctx->optval; 44251875Speter 45251875Speter if (ctx->level != SOL_IP || ctx->optname != IP_TOS) 46251875Speter goto out; 47251875Speter 48251875Speter if (optval + 1 > optval_end) 49251875Speter return 0; /* EPERM, bounds check */ 50251875Speter 51251875Speter if (optval[0] != 0x90) 52251875Speter return 0; /* EPERM, unexpected optval from the kernel */ 53251875Speter 54251875Speter ctx->retval = 0; /* Reset system call return value to zero */ 55251875Speter 56251875Speter optval[0] = 0xA0; 57251875Speter ctx->optlen = 1; 58251875Speter 59251875Speter return 1; 60251875Speter 61251875Speterout: 62251875Speter /* optval larger than PAGE_SIZE use kernel's buffer. */ 63251875Speter if (ctx->optlen > page_size) 64251875Speter ctx->optlen = 0; 65251875Speter return 1; 66251875Speter} 67251875Speter 68251875SpeterSEC("cgroup/setsockopt") 69251875Speterint _setsockopt(struct bpf_sockopt *ctx) 70251875Speter{ 71251875Speter __u8 *optval_end = ctx->optval_end; 72251875Speter __u8 *optval = ctx->optval; 73251875Speter 74251875Speter if (ctx->level != SOL_IP || ctx->optname != IP_TOS) 75251875Speter goto out; 76251875Speter 77251875Speter if (optval + 1 > optval_end) 78251875Speter return 0; /* EPERM, bounds check */ 79251875Speter 80251875Speter optval[0] += 0x10; 81251875Speter ctx->optlen = 1; 82251875Speter 83251875Speter return 1; 84251875Speter 85251875Speterout: 86251875Speter /* optval larger than PAGE_SIZE use kernel's buffer. */ 87251875Speter if (ctx->optlen > page_size) 88251875Speter ctx->optlen = 0; 89251875Speter return 1; 90251875Speter} 91251875Speter