/** * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define _GNU_SOURCE #define ARRAY_SIZE(__a) (sizeof(__a) / sizeof((__a)[0])) #include #include #include #include #include #include #include #include static struct sock_filter nlattr[] = { { 0000, 0, 0, 0x87654321 }, { 0x01, 0, 0, 0x0000002a }, { 0x20, 0, 0, 0xfffff00c }, { 0x16, 0, 0, 0000000000 }, }; static struct sock_fprog bpf_nlattr = { .len = ARRAY_SIZE(nlattr), .filter = nlattr, }; static struct sock_filter nlattr_nest[] = { { 0000, 0, 0, 0x87654321 }, { 0x01, 0, 0, 0x0000002a }, { 0x20, 0, 0, 0xfffff010 }, { 0x16, 0, 0, 0000000000 }, }; static struct sock_fprog bpf_nlattr_nest = { .len = ARRAY_SIZE(nlattr_nest), .filter = nlattr_nest, }; static struct sock_filter nest_rem[] = { { 0000, 0, 0, 0000000000 }, { 0x01, 0, 0, 0x0000002a }, { 0x20, 0, 0, 0xfffff010 }, { 0x16, 0, 0, 0000000000 }, }; static struct sock_fprog bpf_nest_rem = { .len = ARRAY_SIZE(nest_rem), .filter = nest_rem, }; static int send_receive_packet(int s[2], const void* pkt, int len) { char tmp[1024]; ssize_t ret; ret = send(s[1], pkt, len, 0); if (ret != len) { return -1; } ret = recv(s[0], tmp, len, MSG_DONTWAIT); if (ret < 0 && errno == EAGAIN) return 0; return 1; } int main() { struct nlattr chkrem[2] = { [0] = { .nla_len = 0xfff0, .nla_type = 0, }, [1] = { .nla_len = sizeof(struct nlattr), .nla_type = 42, }, }; __u16 chksz = 0xfefe; int s[2], ret; ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, s); if (ret) { return -1; } ret = setsockopt(s[0], SOL_SOCKET, SO_ATTACH_FILTER, &bpf_nlattr, sizeof(bpf_nlattr)); if (ret < 0) { return -1; } ret = send_receive_packet(s, &chksz, sizeof(chksz)); if (ret) { ret = 113; goto out; } ret = setsockopt(s[0], SOL_SOCKET, SO_ATTACH_FILTER, &bpf_nlattr_nest, sizeof(bpf_nlattr_nest)); if (ret < 0) { return -1; } ret = send_receive_packet(s, &chksz, sizeof(chksz)); if (ret) { ret = 113; goto out; } ret = setsockopt(s[0], SOL_SOCKET, SO_ATTACH_FILTER, &bpf_nest_rem, sizeof(bpf_nest_rem)); if (ret < 0) { return -1; } ret = send_receive_packet(s, chkrem, sizeof(chkrem)); if(ret){ ret = 113; } out: return ret; }