{"id":16161431,"url":"https://github.com/gamemann/xdp-dynamic-payload-matching","last_synced_at":"2025-03-18T22:30:29.779Z","repository":{"id":92735938,"uuid":"269451312","full_name":"gamemann/XDP-Dynamic-Payload-Matching","owner":"gamemann","description":"Repository to store findings on matching dynamic payload data in XDP.","archived":false,"fork":false,"pushed_at":"2021-09-15T17:39:36.000Z","size":20,"stargazers_count":22,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-28T12:25:24.759Z","etag":null,"topics":["documentation","dynamic","findings","matching","payload","xdp"],"latest_commit_sha":null,"homepage":"https://moddingcommunity.com/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gamemann.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-04T19:49:39.000Z","updated_at":"2024-12-20T11:30:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"7d730037-1642-4040-ad4e-e2aa116b9e0f","html_url":"https://github.com/gamemann/XDP-Dynamic-Payload-Matching","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gamemann%2FXDP-Dynamic-Payload-Matching","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gamemann%2FXDP-Dynamic-Payload-Matching/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gamemann%2FXDP-Dynamic-Payload-Matching/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gamemann%2FXDP-Dynamic-Payload-Matching/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gamemann","download_url":"https://codeload.github.com/gamemann/XDP-Dynamic-Payload-Matching/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243950813,"owners_count":20373664,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["documentation","dynamic","findings","matching","payload","xdp"],"created_at":"2024-10-10T02:25:14.832Z","updated_at":"2025-03-18T22:30:29.774Z","avatar_url":"https://github.com/gamemann.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# XDP Dynamic Payload Matching Findings\nThis repository is used to store my findings on matching dynamic payloads in XDP. In my opinion, being able to match payload data from a BPF map is important for the future of XDP.\n\nI made a thread on the XDP Newbies mailing list [here](https://marc.info/?l=xdp-newbies\u0026m=158894658804356\u0026w=2) addressing this. Unfortunately, it appears nobody has found a way to match XDP payload data dynamically yet. However, Toke did give a suggestion that I plan on trying and noting in this repository.\n\nIn these XDP program sections, we try to compare payload data from the `payload_map` BPF map. You may specify the payload in `src/loader.c`.\n\n## Section \"methodone\" (FAIL)\nIn this method, we attempt to match the payload data using a for loop. We check if the offset is outside of the packet via:\n\n```C\nif (byte + 1 \u003e (uint8_t *)data_end)\n{\n    break;\n}\n```\n\nUnfortunately, this still fails the BPF verifier:\n\n```\ninvalid access to packet, off=22 size=1, R7(id=3,off=22,r=0)\nR7 offset is outside of the packet\nprocessed 55 insns (limit 1000000) max_states_per_insn 0 total_states 4 peak_states 4 mark_read 3\n```\n\n## Section \"methodtwo\" (FAIL)\nIn this method, we attempt to match the payload data using a for loop just like method one. However, we use goto.\n\nWe check if the offset is outside of the packet via:\n\n```C\nif (byte + 1 \u003e (uint8_t *)data_end)\n{\n    break;\n}\n```\n\nUnfortunately, this still fails the BPF verifier just like method one:\n\n```\ninvalid access to packet, off=22 size=1, R7(id=3,off=22,r=0)\nR7 offset is outside of the packet\nprocessed 55 insns (limit 1000000) max_states_per_insn 0 total_states 4 peak_states 4 mark_read 3\n```\n\n## Section \"methodthree\" (FAIL)\n*Not finished*\n\n## Section \"methodfour\" (SUCCESS!)\nThis method works! However, with its current implementation, it can only match payload data from the beginning of the string and once. With that said, the payload needs to be exact.\n\nThis is because we store the payload data we want to match inside of a BPF map as the key. The main code looks like this:\n\n\n```C\nuint8_t *pcktdata = data + sizeof(struct ethhdr) + (iph-\u003eihl * 4) + l4len;\n\nuint8_t hashkey[MAX_PAYLOAD_LENGTH] = {0};\n\nfor (int i = 0; i \u003c MAX_PAYLOAD_LENGTH; i++)\n{\n    if (pcktdata + (i + 1) \u003e (uint8_t *)data_end)\n    {\n        break;\n    }\n\n    hashkey[i] = *(pcktdata + i);\n}\n\nuint8_t *match = bpf_map_lookup_elem(\u0026payload_map, \u0026hashkey);\n\nif (match)\n{\n    printk(\"Dropping matched packet.\\n\");\n}\n```\n\n## Credits\n* [Christian Deacon](https://github.com/gamemann)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgamemann%2Fxdp-dynamic-payload-matching","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgamemann%2Fxdp-dynamic-payload-matching","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgamemann%2Fxdp-dynamic-payload-matching/lists"}