Skip to content

Commit 7888cc4

Browse files
committed
scripts: fix: Make pylint happy
1 parent 404222c commit 7888cc4

File tree

9 files changed

+154
-82
lines changed

9 files changed

+154
-82
lines changed

.github/workflows/check.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,16 @@ jobs:
2424

2525
steps:
2626
- uses: actions/checkout@v6
27-
- name: lint
27+
- name: lint(mypy)
2828
if: matrix.lint == 'mypy'
2929
run: |
3030
apt update && apt install mypy -y
31+
rm .pylintrc
3132
mypy --explicit-package-bases $(find | grep .py)
3233
3334
- name: lint
3435
if: matrix.lint == 'pylint'
3536
run: |
3637
apt update && apt install pylint -y
3738
rm mkdtboimg.py
38-
pylint $(find | grep .py)
39+
pylint $(find | grep .py )

.pylintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[MASTER]
22
# Python version
3-
py-version = 3.13
3+
py-version = 3.10
44

55
# Disable some style warnings that don't affect functionality
66
disable =

action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ runs:
431431
432432
if [ "${{ inputs.nethunter }}" == "true" ]; then
433433
echo "::group::Initializing Kali NetHunter"
434-
python3 ${{ github.action_path }}/nethunter/nconfig.py "$CONFIG_FILE" -w
434+
python3 ${{ github.action_path }}/nethunter/config.py "$CONFIG_FILE" -w
435435
if [ "${{ inputs.nethunter-patch }}" == "true" ]; then
436436
python3 "${{ github.action_path }}/nethunter/patch.py"
437437
fi
@@ -456,7 +456,7 @@ runs:
456456
457457
if [ "${{ inputs.lxc }}" == "true" ]; then
458458
echo "::group::Enabling LXC"
459-
python3 ${{ github.action_path }}/lxcconfig.py "$CONFIG_FILE" -w
459+
python3 ${{ github.action_path }}/nethunter/config.py "$CONFIG_FILE" -w
460460
if [ "${{ inputs.lxc-patch }}" == "true" ]; then
461461
python3 "${{ github.action_path }}/lxc/patch.py"
462462
fi

clean.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ def clean_ccache() -> None:
7575

7676

7777
def clean_env_vars() -> None:
78-
"""Clean build-related environment variables."""
78+
"""Clean build-related environment variables.
79+
80+
Note: This function prints unset commands to stdout for shell evaluation.
81+
Use: eval $(python3 clean.py --env)
82+
"""
7983
env_vars = [
8084
"CMD_PATH", "CMD_CC", "CMD_CLANG_TRIPLE", "CMD_CROSS_COMPILE",
8185
"CMD_CROSS_COMPILE_ARM32", "USE_CCACHE", "CLANG_PATH", "HOMES",
@@ -88,8 +92,7 @@ def clean_env_vars() -> None:
8892
]
8993
for var in env_vars:
9094
if var in os.environ:
91-
del os.environ[var]
92-
print(f"Unset environment variable: {var}")
95+
print(f"unset {var}")
9396

9497

9598
def clean_temp_files() -> None:
@@ -173,7 +176,9 @@ def main() -> None:
173176
clean_ccache()
174177

175178
if args.env:
179+
print("# Run: eval $(python3 clean.py --env)", file=sys.stderr)
176180
clean_env_vars()
181+
return # Exit early to avoid extra output when sourcing
177182

178183
# Detect package manager for info
179184
pkg_mgr = detect_package_manager()

lxc/config.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,13 @@ def main() -> None:
223223
parser.add_argument('-w', action='store_true', help='Write changes to config file')
224224
args = parser.parse_args()
225225

226-
config_file = Path(args.config_file)
226+
config_file = Path(args.config_file).resolve()
227227
write_mode = args.w
228228

229+
if not config_file.is_relative_to(Path.cwd()):
230+
print("Error: Config file must be within the current directory")
231+
sys.exit(1)
232+
229233
if not config_file.exists():
230234
print("Provide a config file as argument")
231235
sys.exit(1)

lxc/patch.py

Lines changed: 116 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
#!/usr/bin/env python3
22
"""
3-
Apply LXC patches using sed to kernel source files.
3+
Apply LXC patches to kernel source files using pure Python.
44
"""
55

6-
import subprocess
76
import sys
87
from pathlib import Path
98

109

1110
def find_cgroup_file() -> str:
1211
"""Determine the cgroup file path based on kernel version."""
13-
if Path("kernel/cgroup.c").exists():
14-
# Check if it contains the function signature
15-
content = Path("kernel/cgroup.c").read_text(encoding='utf-8')
12+
cgroup_path = Path("kernel/cgroup.c")
13+
if cgroup_path.exists():
14+
content = cgroup_path.read_text(encoding='utf-8')
1615
if "int cgroup_add_file" in content:
1716
return "kernel/cgroup.c"
1817
return "kernel/cgroup/cgroup.c"
1918

2019

2120
def check_already_patched(file_path: str, patch_type: str) -> bool:
2221
"""Check if the file already contains LXC patches."""
23-
content = Path(file_path).read_text(encoding='utf-8')
22+
path = Path(file_path)
23+
if not path.exists():
24+
return False
25+
26+
content = path.read_text(encoding='utf-8')
2427

2528
if patch_type == "cgroup":
2629
return 'snprintf(name, CGROUP_FILE_NAME_MAX' in content
@@ -30,54 +33,113 @@ def check_already_patched(file_path: str, patch_type: str) -> bool:
3033

3134

3235
def apply_cgroup_patch(cgroup_file: str) -> None:
33-
"""Apply the cgroup patch using sed."""
34-
sed_script = r'''/int cgroup_add_file/,/return 0;/{
35-
/return 0;/i\
36-
\tif (cft->ss && (cgrp->root->flags & CGRP_ROOT_NOPREFIX) && !(cft->flags & CFTYPE_NO_PREFIX)) {\
37-
\tsnprintf(name, CGROUP_FILE_NAME_MAX, "%s.%s", cft->ss->name, cft->name);\
38-
\tkernfs_create_link(cgrp->kn, name, kn);\
39-
\t}
40-
}'''
41-
42-
try:
43-
subprocess.run(
44-
["sed", "-i", sed_script, cgroup_file],
45-
check=True,
46-
capture_output=True,
47-
text=True
48-
)
49-
print(f"Patch applied successfully to {cgroup_file}")
50-
except subprocess.CalledProcessError as e:
51-
print(f"Error applying cgroup patch: {e}", file=sys.stderr)
52-
sys.exit(1)
36+
"""Apply the cgroup patch using pure Python."""
37+
path = Path(cgroup_file)
38+
content = path.read_text(encoding='utf-8')
39+
lines = content.split('\n')
40+
41+
# Find the cgroup_add_file function and insert the patch before return 0;
42+
new_lines = []
43+
in_function = False
44+
brace_count = 0
45+
inserted = False
46+
47+
for line in lines:
48+
stripped = line.strip()
49+
50+
# Check if we're entering the cgroup_add_file function
51+
if "int cgroup_add_file" in stripped:
52+
in_function = True
53+
54+
if in_function and not inserted:
55+
# Count braces to track function scope
56+
brace_count += stripped.count('{')
57+
brace_count -= stripped.count('}')
58+
59+
# Look for "return 0;" within the function
60+
if stripped == "return 0;" and brace_count > 0:
61+
# Insert the patch before return 0;
62+
indent = len(line) - len(line.lstrip())
63+
base_indent = ' ' * indent
64+
65+
patch_code = [
66+
f"{base_indent}if (cft->ss && (cgrp->root->flags & CGRP_ROOT_NOPREFIX) && !(cft->flags & CFTYPE_NO_PREFIX)) {{",
67+
f"{base_indent} snprintf(name, CGROUP_FILE_NAME_MAX, \"%s.%s\", cft->ss->name, cft->name);",
68+
f"{base_indent} kernfs_create_link(cgrp->kn, name, kn);",
69+
f"{base_indent}}}",
70+
]
71+
new_lines.extend(patch_code)
72+
inserted = True
73+
74+
new_lines.append(line)
75+
76+
if not inserted:
77+
print(f"Warning: Could not find insertion point in {cgroup_file}", file=sys.stderr)
78+
return
79+
80+
path.write_text('\n'.join(new_lines), encoding='utf-8')
81+
print(f"Patch applied successfully to {cgroup_file}")
5382

5483

5584
def apply_netfilter_patch() -> None:
56-
"""Apply the xt_qtaguid patch using sed."""
57-
netfilter_file = "net/netfilter/xt_qtaguid.c"
58-
59-
# This is a complex sed script that:
60-
# 1. Changes 'struct rtnl_link_stats64 dev_stats, *stats' to 'struct rtnl_link_stats64 *stats'
61-
# 2. Adds 'stats = &no_dev_stats;' before the active check
62-
# 3. Deletes the if block and its next 5 lines
63-
sed_script = r'''/int iface_stat_fmt_proc_show/,/^}/ {
64-
s/struct rtnl_link_stats64 dev_stats, \*stats/struct rtnl_link_stats64 *stats/
65-
/if (iface_entry->active)/i\
66-
\tstats = \&no_dev_stats;
67-
/if (iface_entry->active)/,+5d
68-
}'''
69-
70-
try:
71-
subprocess.run(
72-
["sed", "-i", sed_script, netfilter_file],
73-
check=True,
74-
capture_output=True,
75-
text=True
76-
)
77-
print(f"Patch applied successfully to {netfilter_file}")
78-
except subprocess.CalledProcessError as e:
79-
print(f"Error applying netfilter patch: {e}", file=sys.stderr)
80-
sys.exit(1)
85+
"""Apply the xt_qtaguid patch using pure Python."""
86+
netfilter_file = Path("net/netfilter/xt_qtaguid.c")
87+
88+
if not netfilter_file.exists():
89+
print(f"Error: {netfilter_file} not found", file=sys.stderr)
90+
return
91+
92+
content = netfilter_file.read_text(encoding='utf-8')
93+
lines = content.split('\n')
94+
95+
new_lines = []
96+
in_function = False
97+
brace_count = 0
98+
modified = False
99+
skip_lines = 0
100+
101+
for line in lines:
102+
if skip_lines > 0:
103+
skip_lines -= 1
104+
continue
105+
106+
stripped = line.strip()
107+
108+
# Check if we're entering iface_stat_fmt_proc_show function
109+
if "int iface_stat_fmt_proc_show" in stripped:
110+
in_function = True
111+
112+
if in_function and not modified:
113+
# Track braces within the function
114+
brace_count += stripped.count('{')
115+
brace_count -= stripped.count('}')
116+
117+
# Replace variable declaration
118+
if "struct rtnl_link_stats64 dev_stats, *stats" in line:
119+
line = line.replace(
120+
"struct rtnl_link_stats64 dev_stats, *stats",
121+
"struct rtnl_link_stats64 *stats"
122+
)
123+
124+
# Insert stats assignment before the active check
125+
if "if (iface_entry->active)" in line:
126+
indent = len(line) - len(line.lstrip())
127+
base_indent = ' ' * indent
128+
new_lines.append(f"{base_indent}stats = &no_dev_stats;")
129+
130+
# Skip the if block and next 5 lines
131+
skip_lines = 5
132+
modified = True
133+
continue
134+
135+
new_lines.append(line)
136+
137+
if not modified:
138+
print(f"Warning: Could not apply netfilter patch", file=sys.stderr)
139+
return
140+
141+
netfilter_file.write_text('\n'.join(new_lines), encoding='utf-8')
142+
print(f"Patch applied successfully to {netfilter_file}")
81143

82144

83145
def main() -> None:
@@ -89,12 +151,13 @@ def main() -> None:
89151
]
90152

91153
for file_path, patch_type in patch_files:
92-
if not Path(file_path).exists():
154+
path = Path(file_path)
155+
if not path.exists():
93156
print(f"Warning: {file_path} not found, skipping", file=sys.stderr)
94157
continue
95158

96159
if check_already_patched(file_path, patch_type):
97-
print(f"Warning: {file_path} contains LXC")
160+
print(f"Warning: {file_path} already contains LXC patches, skipping")
98161
continue
99162

100163
if patch_type == "cgroup":

lxc/patch_cocci.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,8 @@ def check_dependencies() -> None:
3838
"""Check that required dependencies are installed."""
3939
missing = []
4040

41-
if not shutil.which("curl"):
42-
missing.append("curl")
43-
if not shutil.which("parallel"):
44-
missing.append("parallel")
41+
if not shutil.which("aria2c"):
42+
missing.append("aria2c")
4543
if not shutil.which("spatch"):
4644
missing.append("coccinelle")
4745

@@ -51,13 +49,13 @@ def check_dependencies() -> None:
5149

5250

5351
def download_patch(patch_name: str, temp_dir: Path) -> Path:
54-
"""Download a single patch file."""
52+
"""Download a single patch file using aria2c."""
5553
url = f"{REPO_URL}/{patch_name}"
5654
output_path = temp_dir / patch_name
5755

5856
try:
5957
subprocess.run(
60-
["curl", "-sSfL", url, "-o", str(output_path)],
58+
["aria2c", "-d", str(temp_dir), "-o", patch_name, url],
6159
check=True,
6260
capture_output=True,
6361
text=True

nethunter/config.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,9 +379,13 @@ def main() -> None:
379379
parser.add_argument('-w', action='store_true', help='Write changes to config file')
380380
args = parser.parse_args()
381381

382-
config_file = Path(args.config_file)
382+
config_file = Path(args.config_file).resolve()
383383
write_mode = args.w
384384

385+
if not config_file.is_relative_to(Path.cwd()):
386+
print("Error: Config file must be within the current directory")
387+
sys.exit(1)
388+
385389
if not config_file.exists():
386390
print("Provide a config file as argument")
387391
sys.exit(1)

0 commit comments

Comments
 (0)