Skip to content

Commit f3e15f3

Browse files
committed
use MASKED_EQ for all 32bit arguments
1 parent 2d3bd1d commit f3e15f3

File tree

3 files changed

+33
-16
lines changed

3 files changed

+33
-16
lines changed

src/seccompiler/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ displaydoc = "0.2.5"
2222
libc = "0.2.168"
2323
serde = { version = "1.0.215", features = ["derive"] }
2424
serde_json = "1.0.133"
25-
thiserror = "2.0.3"
25+
thiserror = "2.0.6"
2626
zerocopy = { version = "0.8.11" }
2727

2828
[lints]

src/seccompiler/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ pub fn compile_bpf(
121121
} else if let Some(rules) = &rule.args {
122122
let comparators = rules
123123
.iter()
124-
.map(|rule| rule.to_scmp_type(&arch, syscall))
124+
.map(|rule| rule.to_scmp_type())
125125
.collect::<Vec<scmp_arg_cmp>>();
126126

127127
// SAFETY: Safe as all args are correct.

src/seccompiler/src/types.rs

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// Copyright 2021 Sony Group Corporation
3+
//
24
// SPDX-License-Identifier: Apache-2.0
35

46
use std::collections::BTreeMap;
@@ -23,39 +25,54 @@ pub enum SeccompCmpOp {
2325
Ne,
2426
}
2527

28+
/// Seccomp argument value length.
29+
#[derive(Clone, Debug, Deserialize, PartialEq)]
30+
#[serde(rename_all = "lowercase")]
31+
pub enum SeccompCmpArgLen {
32+
/// Argument value length is 4 bytes.
33+
Dword,
34+
/// Argument value length is 8 bytes.
35+
Qword,
36+
}
37+
2638
/// Condition that syscall must match in order to satisfy a rule.
2739
#[derive(Debug, Deserialize)]
2840
pub struct SeccompCondition {
2941
pub index: u8,
3042
pub op: SeccompCmpOp,
3143
pub val: u64,
44+
#[serde(rename = "type")]
45+
pub val_len: SeccompCmpArgLen,
3246
}
3347

3448
impl SeccompCondition {
35-
pub fn to_scmp_type(&self, arch: &TargetArch, syscall: i32) -> scmp_arg_cmp {
36-
// For `ioctls` we need to mask upper bits as musl
37-
// sets them to 1, but libseccomp explicitly checks that they are 0.
38-
// with 0x00000000FFFFFFFF mask upper bits are always 0.
39-
let ioctl = match arch {
40-
TargetArch::X86_64 => 16,
41-
TargetArch::Aarch64 => 29,
42-
};
49+
pub fn to_scmp_type(&self) -> scmp_arg_cmp {
4350
match self.op {
4451
SeccompCmpOp::Eq => {
45-
if syscall == ioctl {
46-
scmp_arg_cmp {
52+
// When using EQ libseccomp compares the whole 64 bits. In
53+
// general this is not a problem, but for example we have
54+
// observed musl `ioctl` to leave garbage in the upper bits of
55+
// the `request` argument. There is a GH issue to allow 32bit
56+
// comparisons (see
57+
// https://github.com/seccomp/libseccomp/issues/383) but is not
58+
// merged yet. Until that is available, do a masked comparison
59+
// with the upper 32bits set to 0, so we will compare that `hi32
60+
// & 0x0 == 0`, which is always true. This costs one additional
61+
// instruction, but will be likely be optimized away by the BPF
62+
// JIT.
63+
match self.val_len {
64+
SeccompCmpArgLen::Dword => scmp_arg_cmp {
4765
arg: self.index as u32,
4866
op: scmp_compare::SCMP_CMP_MASKED_EQ,
4967
datum_a: 0x00000000FFFFFFFF,
5068
datum_b: self.val,
51-
}
52-
} else {
53-
scmp_arg_cmp {
69+
},
70+
SeccompCmpArgLen::Qword => scmp_arg_cmp {
5471
arg: self.index as u32,
5572
op: scmp_compare::SCMP_CMP_EQ,
5673
datum_a: self.val,
5774
datum_b: 0,
58-
}
75+
},
5976
}
6077
}
6178
SeccompCmpOp::Ge => scmp_arg_cmp {

0 commit comments

Comments
 (0)