Compare commits
14 Commits
062e5bb60e
...
f0d7ec56b3
| Author | SHA1 | Date | |
|---|---|---|---|
| f0d7ec56b3 | |||
| e34b7546a4 | |||
| e12212cd2c | |||
| 104cb98d9e | |||
| 7f59bb7c02 | |||
| 6c0b368f6b | |||
| 52ce39d579 | |||
|
7348681b65
|
|||
|
5178a7b8ea
|
|||
|
a3ff953e50
|
|||
|
b0f68fa7e0
|
|||
|
c25294333b
|
|||
|
08fac67f73
|
|||
|
06deeb3ae7
|
@@ -4,7 +4,7 @@ on: [push]
|
|||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
shell: bash -l {0}
|
shell: bash -le -o pipefail {0}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-oci-image:
|
build-oci-image:
|
||||||
@@ -98,10 +98,6 @@ jobs:
|
|||||||
|
|
||||||
- name: build and check
|
- name: build and check
|
||||||
run: |
|
run: |
|
||||||
echo $USER
|
|
||||||
echo "CC=$CC"
|
|
||||||
echo "CXX=$CXX"
|
|
||||||
source /etc/profile
|
|
||||||
meson setup -Dfuzz=enabled -Dtests=enabled -Dbuildtype=debugoptimized -Ddocs=enabled build
|
meson setup -Dfuzz=enabled -Dtests=enabled -Dbuildtype=debugoptimized -Ddocs=enabled build
|
||||||
meson compile -C build
|
meson compile -C build
|
||||||
|
|
||||||
@@ -125,6 +121,37 @@ jobs:
|
|||||||
meson compile -C build
|
meson compile -C build
|
||||||
ninja test -C build
|
ninja test -C build
|
||||||
|
|
||||||
|
fuzz:
|
||||||
|
runs-on: brutalisk
|
||||||
|
env:
|
||||||
|
CC: 'clang'
|
||||||
|
CXX: 'clang++'
|
||||||
|
FUZZER_TIMEOUT_S: 300
|
||||||
|
needs: [build-oci-image, build]
|
||||||
|
container:
|
||||||
|
image: ${{ vars.REGISTRY_URL }}/${{ gitea.repository }}:${{ needs.build-oci-image.outputs.image_tag }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout repo
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
|
# FIXME: Get rid of this step when portage has fixes merged?
|
||||||
|
# needed because portage has fixes upstream we need that arent stable yet
|
||||||
|
- name: Checkout tip of portage
|
||||||
|
run: |
|
||||||
|
git clone https://github.com/gentoo/portage.git
|
||||||
|
cd portage
|
||||||
|
python -m venv .venv && ./.venv/bin/pip install -e .
|
||||||
|
source ./.venv/bin/activate
|
||||||
|
which emerge
|
||||||
|
|
||||||
|
- name: build and fuzz
|
||||||
|
run: |
|
||||||
|
source ./portage/.venv/bin/activate
|
||||||
|
which emerge
|
||||||
|
meson setup -Dfuzz=enabled -Dtests=enabled -Dbuildtype=debugoptimized build
|
||||||
|
meson compile atom_parser_fuzzer:alias -C build
|
||||||
|
timeout 10m ./scripts/fuzz.sh
|
||||||
|
|
||||||
check-format:
|
check-format:
|
||||||
runs-on: brutalisk
|
runs-on: brutalisk
|
||||||
needs: [build-oci-image]
|
needs: [build-oci-image]
|
||||||
@@ -153,3 +180,16 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
meson setup -Ddocs=enabled docs
|
meson setup -Ddocs=enabled docs
|
||||||
ninja rustdoc -C docs
|
ninja rustdoc -C docs
|
||||||
|
|
||||||
|
grep:
|
||||||
|
runs-on: brutalisk
|
||||||
|
needs: [build-oci-image]
|
||||||
|
container:
|
||||||
|
image: ${{ vars.REGISTRY_URL }}/${{ gitea.repository }}:${{ needs.build-oci-image.outputs.image_tag }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout repo
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
|
- name: grep for patterns
|
||||||
|
run: |
|
||||||
|
git grep -E 'todo!|dbg!' -- '*.rs' && exit 1 || exit 0
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ ninja rustfmt -C build
|
|||||||
ninja rustdoc -C build
|
ninja rustdoc -C build
|
||||||
ninja clippy -C build
|
ninja clippy -C build
|
||||||
ninja test -C build
|
ninja test -C build
|
||||||
|
git grep -E 'todo!|dbg!' -- '*.rs' && exit 1 || exit 0
|
||||||
|
|||||||
@@ -4,25 +4,12 @@
|
|||||||
use core::slice;
|
use core::slice;
|
||||||
use gentoo_utils::{Parseable, atom::Atom};
|
use gentoo_utils::{Parseable, atom::Atom};
|
||||||
use std::{
|
use std::{
|
||||||
|
env::{self},
|
||||||
io::{self, Write},
|
io::{self, Write},
|
||||||
sync::{LazyLock, Mutex},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct State {
|
|
||||||
input: io::Stdin,
|
|
||||||
output: io::Stdout,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn LLVMFuzzerTestOneInput(input: *const u8, len: usize) -> i32 {
|
pub unsafe extern "C" fn LLVMFuzzerTestOneInput(input: *const u8, len: usize) -> i32 {
|
||||||
static PIPES: LazyLock<Mutex<State>> = LazyLock::new(|| {
|
|
||||||
Mutex::new(State {
|
|
||||||
input: io::stdin(),
|
|
||||||
output: io::stdout(),
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
let slice = unsafe { slice::from_raw_parts(input, len) };
|
let slice = unsafe { slice::from_raw_parts(input, len) };
|
||||||
let str = str::from_utf8(slice).expect("expected ascii input");
|
let str = str::from_utf8(slice).expect("expected ascii input");
|
||||||
|
|
||||||
@@ -30,13 +17,13 @@ pub unsafe extern "C" fn LLVMFuzzerTestOneInput(input: *const u8, len: usize) ->
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut state = PIPES.lock().unwrap();
|
let stdin = io::stdin();
|
||||||
|
let mut stdout = io::stdout();
|
||||||
writeln!(&mut state.output, "{str}").unwrap();
|
|
||||||
|
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
|
|
||||||
state.input.read_line(&mut buffer).unwrap();
|
writeln!(&mut stdout, "{str}").unwrap();
|
||||||
|
|
||||||
|
stdin.read_line(&mut buffer).unwrap();
|
||||||
|
|
||||||
let control = match buffer.as_str().trim() {
|
let control = match buffer.as_str().trim() {
|
||||||
"0" => Ok(()),
|
"0" => Ok(()),
|
||||||
@@ -48,23 +35,32 @@ pub unsafe extern "C" fn LLVMFuzzerTestOneInput(input: *const u8, len: usize) ->
|
|||||||
|
|
||||||
match (control, gentoo_utils) {
|
match (control, gentoo_utils) {
|
||||||
(Ok(_), Ok(_)) => {
|
(Ok(_), Ok(_)) => {
|
||||||
eprintln!("agreement that {str} is valid");
|
if env::var("FUZZER_LOG").is_ok() {
|
||||||
|
eprintln!("agreement that {str} is valid");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(Err(_), Err(_)) => {
|
(Err(_), Err(_)) => {
|
||||||
eprintln!("agreement that {str} is invalid");
|
if env::var("FUZZER_LOG").is_ok() {
|
||||||
|
eprintln!("agreement that {str} is invalid");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(Ok(_), Err(rest)) => {
|
(Ok(_), Err(rest)) => {
|
||||||
panic!("disagreement on {str}\ncontrol:Ok\ngentoo-utils:Err({rest})");
|
panic!("disagreement on {str}\ncontrol:Ok\ngentoo-utils:Err({rest})");
|
||||||
}
|
}
|
||||||
(Err(_), Ok(atom))
|
(Err(_), Ok(atom))
|
||||||
if atom
|
if atom.usedeps().iter().any(|usedep| {
|
||||||
.usedeps()
|
atom.usedeps()
|
||||||
.iter()
|
.iter()
|
||||||
.any(|usedep| atom.usedeps().iter().filter(|u| usedep == *u).count() > 1) =>
|
.filter(|u| *usedep.flag() == *u.flag())
|
||||||
|
.count()
|
||||||
|
> 1
|
||||||
|
}) =>
|
||||||
{
|
{
|
||||||
eprintln!(
|
if env::var("FUZZER_LOG").is_ok() {
|
||||||
"disagreement, but we will allow it since its probably because of duplicated usdeps"
|
eprintln!(
|
||||||
);
|
"disagreement, but we will allow it since its probably because of duplicated usdeps"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(Err(_), Ok(_)) => {
|
(Err(_), Ok(_)) => {
|
||||||
panic!("disagreement on {str}\ncontrol:Err\ngentoo-utils:Ok")
|
panic!("disagreement on {str}\ncontrol:Err\ngentoo-utils:Ok")
|
||||||
|
|||||||
@@ -2,12 +2,13 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
from portage.dep import Atom
|
from portage.dep import Atom
|
||||||
|
from portage.exception import InvalidAtom
|
||||||
|
|
||||||
for line in sys.stdin.buffer:
|
for line in sys.stdin.buffer:
|
||||||
try:
|
try:
|
||||||
Atom(line.decode().strip())
|
Atom(line.decode().strip())
|
||||||
sys.stdout.buffer.write(b"0\n")
|
sys.stdout.buffer.write(b"0\n")
|
||||||
except:
|
except InvalidAtom:
|
||||||
sys.stdout.buffer.write(b"1\n")
|
sys.stdout.buffer.write(b"1\n")
|
||||||
finally:
|
finally:
|
||||||
sys.stdout.buffer.flush()
|
sys.stdout.buffer.flush()
|
||||||
|
|||||||
23
scripts/fuzz.sh
Executable file
23
scripts/fuzz.sh
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
CWD="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
|
||||||
|
PROJECT_DIR=$(realpath "${CWD}/../")
|
||||||
|
|
||||||
|
in=$(mktemp -u) || exit $?
|
||||||
|
out=$(mktemp -u) || exit $?
|
||||||
|
|
||||||
|
mkfifo ${in} ${out} || exit $?
|
||||||
|
|
||||||
|
if [[ -z "$FUZZER_TIMEOUT_S" ]]; then
|
||||||
|
FUZZER_TIMEOUT_S=600
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
${PROJECT_DIR}/scripts/atom.py <${in} >${out} \
|
||||||
|
| ${PROJECT_DIR}/build/fuzz/atom/parser/fuzzer -max_total_time=$FUZZER_TIMEOUT_S >${in} <${out} \
|
||||||
|
${PROJECT_DIR}/build/atom_parser_fuzzer_corpus \
|
||||||
|
-only_ascii=1 \
|
||||||
|
-fork=2 \
|
||||||
|
-timeout=2 \
|
||||||
|
-max_total_time=$FUZZER_TIMEOUT_S \
|
||||||
|
-timeout_exitcode=0 \
|
||||||
|
"$@"
|
||||||
@@ -102,7 +102,7 @@ impl Iterator for Ebuilds {
|
|||||||
Ok(ebuild) => break Some(Ok(ebuild)),
|
Ok(ebuild) => break Some(Ok(ebuild)),
|
||||||
Err(e) => break Some(Err(e)),
|
Err(e) => break Some(Err(e)),
|
||||||
},
|
},
|
||||||
_ => todo!(),
|
Err(e) => break Some(Err(Error::ReadDir(self.0.clone(), e))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user