* bpf_csum_diff - R3 offset is outside of the packet [not found] <BYAPR11MB26157ACA256993F0F15D65E7B45F0@BYAPR11MB2615.namprd11.prod.outlook.com> @ 2019-12-07 0:11 ` Francesco Ruta (fruta) 2019-12-07 13:15 ` Anton Protopopov 0 siblings, 1 reply; 3+ messages in thread From: Francesco Ruta (fruta) @ 2019-12-07 0:11 UTC (permalink / raw) To: xdp-newbies Hello, I am trying to use bpf_csum_diff() to recompute a corrupted checksum in XDP; unfortunately, in this specific case, I am unable to just perform an incremental update. I understand that the verifier will reject code that uses dynamic length, but even the stripped-down test shown below is rejected. I tried directly in assembly adding extra range checks for the r3 register to placate the most phobic verifier to no avail. Is there any workaround -or any alternative? BR F. SEC("test") int intercept(struct xdp_md *ctx) { void * data = (void*)(long)ctx->data; void * dataEnd = (void*)(long)ctx->data_end; void * dataPnt = data; if (dataPnt >= dataEnd) { return XDP_ABORTED; } __u32 dataLen = (__be32 *)dataEnd - (__be32 *)dataPnt; if (dataLen > sizeof(__be32)){ (void)bpf_csum_diff(0, 0, (__be32 *)dataPnt, sizeof(__be32), 0); } return XDP_PASS; } char _license[] SEC("license") = "GPL"; Prog section 'test' rejected: Permission denied (13)! - Type: 6 - Instructions: 18 (0 over limit) - License: GPL Verifier analysis: 0: (b7) r6 = 1 1: (61) r2 = *(u32 *)(r1 +4) 2: (61) r3 = *(u32 *)(r1 +0) 3: (3d) if r3 >= r2 goto pc+12 R1=ctx(id=0,off=0,imm=0) R2=pkt_end(id=0,off=0,imm=0) R3=pkt(id=0,off=0,r=0,imm=0) R6=inv1 R10=fp0,call_-1 4: (1f) r2 -= r3 5: (18) r1 = 0x3fffffffc 7: (5f) r2 &= r1 8: (b7) r6 = 2 9: (b7) r1 = 17 10: (2d) if r1 > r2 goto pc+5 R1=inv17 R2=inv(id=0,umin_value=17,umax_value=17179869180,var_off=(0x0; 0x3fffffffc)) R3=pkt(id=0,off=0,r=0,imm=0) R6=inv2 R10=fp0,call_-1 11: (b7) r1 = 0 12: (b7) r2 = 0 13: (b7) r4 = 4 14: (b7) r5 = 0 15: (85) call bpf_csum_diff#28 invalid access to packet, off=0 size=4, R3(id=0,off=0,r=0) R3 offset is outside of the packet uname -sr Linux 5.0.0-1022-gke ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: bpf_csum_diff - R3 offset is outside of the packet 2019-12-07 0:11 ` bpf_csum_diff - R3 offset is outside of the packet Francesco Ruta (fruta) @ 2019-12-07 13:15 ` Anton Protopopov 2019-12-09 1:22 ` Francesco Ruta (fruta) 0 siblings, 1 reply; 3+ messages in thread From: Anton Protopopov @ 2019-12-07 13:15 UTC (permalink / raw) To: Francesco Ruta (fruta); +Cc: xdp-newbies Hi Francesco, пт, 6 дек. 2019 г. в 19:12, Francesco Ruta (fruta) <fruta@cisco.com>: > > Hello, > > I am trying to use bpf_csum_diff() to recompute a corrupted checksum in XDP; unfortunately, in this specific case, I am unable to just perform an incremental update. > I understand that the verifier will reject code that uses dynamic length, but even the stripped-down test shown below is rejected. > I tried directly in assembly adding extra range checks for the r3 register to placate the most phobic verifier to no avail. > Is there any workaround -or any alternative? > BR > F. > > SEC("test") > int intercept(struct xdp_md *ctx) { > void * data = (void*)(long)ctx->data; > void * dataEnd = (void*)(long)ctx->data_end; > void * dataPnt = data; > if (dataPnt >= dataEnd) { > return XDP_ABORTED; > } > __u32 dataLen = (__be32 *)dataEnd - (__be32 *)dataPnt; > if (dataLen > sizeof(__be32)){ > (void)bpf_csum_diff(0, 0, (__be32 *)dataPnt, sizeof(__be32), 0); > } > return XDP_PASS; > } > char _license[] SEC("license") = "GPL"; > > Prog section 'test' rejected: Permission denied (13)! > - Type: 6 > - Instructions: 18 (0 over limit) > - License: GPL > > Verifier analysis: > > 0: (b7) r6 = 1 > 1: (61) r2 = *(u32 *)(r1 +4) > 2: (61) r3 = *(u32 *)(r1 +0) > 3: (3d) if r3 >= r2 goto pc+12 > R1=ctx(id=0,off=0,imm=0) R2=pkt_end(id=0,off=0,imm=0) R3=pkt(id=0,off=0,r=0,imm=0) R6=inv1 R10=fp0,call_-1 > 4: (1f) r2 -= r3 > 5: (18) r1 = 0x3fffffffc > 7: (5f) r2 &= r1 > 8: (b7) r6 = 2 > 9: (b7) r1 = 17 > 10: (2d) if r1 > r2 goto pc+5 > R1=inv17 R2=inv(id=0,umin_value=17,umax_value=17179869180,var_off=(0x0; 0x3fffffffc)) R3=pkt(id=0,off=0,r=0,imm=0) R6=inv2 R10=fp0,call_-1 > 11: (b7) r1 = 0 > 12: (b7) r2 = 0 > 13: (b7) r4 = 4 > 14: (b7) r5 = 0 > 15: (85) call bpf_csum_diff#28 > invalid access to packet, off=0 size=4, R3(id=0,off=0,r=0) > R3 offset is outside of the packet > > uname -sr > Linux 5.0.0-1022-gke You need to check pointer boundaries, try something like this: SEC("test") int intercept(struct xdp_md *ctx) { void * data = (void*)(long)ctx->data; void * data_end = (void*)(long)ctx->data_end; const int N = sizeof(__be32); if (data >= data_end) return XDP_ABORTED; if (data + N <= data_end) /* lets verifier to know that data[0,...,N-1] is valid */ bpf_csum_diff(0, 0, data, N, 0); return XDP_PASS; } ^ permalink raw reply [flat|nested] 3+ messages in thread
* RE: bpf_csum_diff - R3 offset is outside of the packet 2019-12-07 13:15 ` Anton Protopopov @ 2019-12-09 1:22 ` Francesco Ruta (fruta) 0 siblings, 0 replies; 3+ messages in thread From: Francesco Ruta (fruta) @ 2019-12-09 1:22 UTC (permalink / raw) To: Anton Protopopov; +Cc: xdp-newbies Anton, Thank you for your suggestion. Albeit that would work for the example, it doesn't seem to work for my original problem where the length of the buffer is computed dynamically. Thank you again Francesco -----Original Message----- From: Anton Protopopov <aspsk2@gmail.com> Sent: Saturday, December 7, 2019 7:16 AM To: Francesco Ruta (fruta) <fruta@cisco.com> Cc: xdp-newbies@vger.kernel.org Subject: Re: bpf_csum_diff - R3 offset is outside of the packet Hi Francesco, пт, 6 дек. 2019 г. в 19:12, Francesco Ruta (fruta) <fruta@cisco.com>: > Hello, > > I am trying to use bpf_csum_diff() to recompute a corrupted checksum in XDP; unfortunately, in this specific case, I am unable to just perform an incremental update. > I understand that the verifier will reject code that uses dynamic length, but even the stripped-down test shown below is rejected. > I tried directly in assembly adding extra range checks for the r3 register to placate the most phobic verifier to no avail. > Is there any workaround -or any alternative? > BR > F. > > SEC("test") > int intercept(struct xdp_md *ctx) { > void * data = (void*)(long)ctx->data; > void * dataEnd = (void*)(long)ctx->data_end; > void * dataPnt = data; > if (dataPnt >= dataEnd) { > return XDP_ABORTED; > } > __u32 dataLen = (__be32 *)dataEnd - (__be32 *)dataPnt; > if (dataLen > sizeof(__be32)){ > (void)bpf_csum_diff(0, 0, (__be32 *)dataPnt, sizeof(__be32), 0); > } > return XDP_PASS; > } > char _license[] SEC("license") = "GPL"; > > Prog section 'test' rejected: Permission denied (13)! > - Type: 6 > - Instructions: 18 (0 over limit) > - License: GPL > > Verifier analysis: > > 0: (b7) r6 = 1 > 1: (61) r2 = *(u32 *)(r1 +4) > 2: (61) r3 = *(u32 *)(r1 +0) > 3: (3d) if r3 >= r2 goto pc+12 > R1=ctx(id=0,off=0,imm=0) R2=pkt_end(id=0,off=0,imm=0) > R3=pkt(id=0,off=0,r=0,imm=0) R6=inv1 R10=fp0,call_-1 > 4: (1f) r2 -= r3 > 5: (18) r1 = 0x3fffffffc > 7: (5f) r2 &= r1 > 8: (b7) r6 = 2 > 9: (b7) r1 = 17 > 10: (2d) if r1 > r2 goto pc+5 > R1=inv17 > R2=inv(id=0,umin_value=17,umax_value=17179869180,var_off=(0x0; > 0x3fffffffc)) R3=pkt(id=0,off=0,r=0,imm=0) R6=inv2 R10=fp0,call_-1 > 11: (b7) r1 = 0 > 12: (b7) r2 = 0 > 13: (b7) r4 = 4 > 14: (b7) r5 = 0 > 15: (85) call bpf_csum_diff#28 > invalid access to packet, off=0 size=4, R3(id=0,off=0,r=0) > R3 offset is outside of the packet > > uname -sr > Linux 5.0.0-1022-gke You need to check pointer boundaries, try something like this: SEC("test") int intercept(struct xdp_md *ctx) { void * data = (void*)(long)ctx->data; void * data_end = (void*)(long)ctx->data_end; const int N = sizeof(__be32); if (data >= data_end) return XDP_ABORTED; if (data + N <= data_end) /* lets verifier to know that data[0,...,N-1] is valid */ bpf_csum_diff(0, 0, data, N, 0); return XDP_PASS; } ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2019-12-09 1:29 UTC | newest] Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <BYAPR11MB26157ACA256993F0F15D65E7B45F0@BYAPR11MB2615.namprd11.prod.outlook.com> 2019-12-07 0:11 ` bpf_csum_diff - R3 offset is outside of the packet Francesco Ruta (fruta) 2019-12-07 13:15 ` Anton Protopopov 2019-12-09 1:22 ` Francesco Ruta (fruta)
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.