[PATCH] smackfs: reject out-of-range IPv4 octets in netlabel writes

From: Hongjian Dai

Date: Sun Sep 20 2026 - 21:47:05 EST


smk_write_net4addr() parses the address with %hhd, which silently
wraps values over 255 (e.g. 300 becomes 44) and accepts them. The
wrong address is then stored and passed to netlbl_cfg_unlbl_static_add(),
so inbound packets get mislabeled and policy can be bypassed or
connections wrongly denied by a privileged misconfiguration.

Parse into unsigned ints like the IPv6 path does and reject any
octet above 255 with -EINVAL, mirroring the existing scanned[i] >
0xffff check in smk_write_net6addr().

Fixes: 6d3dc07cbb1e ("smack: Add support for unlabeled network hosts and networks")
Signed-off-by: Hongjian Dai <daihongjian@xxxxxxxxxxxxxxx>
---
security/smack/smackfs.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index a72bc7fabea9..845660cc3a7b 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -1169,6 +1169,7 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf,
struct in_addr mask;
unsigned int m;
unsigned int masks;
+ unsigned int octet[4];
int found;
u32 mask_bits = (1<<31);
__be32 nsa;
@@ -1198,17 +1199,26 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf,
goto free_data_out;
}

- rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%u %s",
- &host[0], &host[1], &host[2], &host[3], &masks, smack);
+ rc = sscanf(data, "%u.%u.%u.%u/%u %s",
+ &octet[0], &octet[1], &octet[2], &octet[3], &masks, smack);
if (rc != 6) {
- rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s",
- &host[0], &host[1], &host[2], &host[3], smack);
+ rc = sscanf(data, "%u.%u.%u.%u %s",
+ &octet[0], &octet[1], &octet[2], &octet[3], smack);
if (rc != 5) {
rc = -EINVAL;
goto free_out;
}
masks = 32;
}
+ if (octet[0] > 255 || octet[1] > 255 || octet[2] > 255 ||
+ octet[3] > 255) {
+ rc = -EINVAL;
+ goto free_out;
+ }
+ host[0] = octet[0];
+ host[1] = octet[1];
+ host[2] = octet[2];
+ host[3] = octet[3];
if (masks > BEBITS) {
rc = -EINVAL;
goto free_out;
--
2.43.0