audit_filter_exe() copies the filtered executable path after the
audit_rule_data header in struct audit_message.  The message buffer was
sized as PATH_MAX + 200 bytes with received records in mind, but
struct audit_rule_data alone takes 1040 bytes.  That leaves only 3256
bytes for the path, while the kernel accepts up to PATH_MAX bytes, so a
long path overflows the message.

Size the buffer for an audit_rule_data followed by a PATH_MAX string.
This only makes the buffer larger, so received records still fit.

Also check that the request fits in the message and return -E2BIG
otherwise, in case exe_len does not match the filter's buffer.

Assisted-by: LLM
Signed-off-by: Günther Noack <[email protected]>
---
 tools/testing/selftests/landlock/audit.h | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/landlock/audit.h 
b/tools/testing/selftests/landlock/audit.h
index 1e533b4e26db..173dcd1088db 100644
--- a/tools/testing/selftests/landlock/audit.h
+++ b/tools/testing/selftests/landlock/audit.h
@@ -41,7 +41,11 @@ struct audit_message {
                struct audit_features features;
                struct audit_rule_data rule;
                struct nlmsgerr err;
-               char data[PATH_MAX + 200];
+               /*
+                * Large enough for an audit_rule_data followed by a PATH_MAX
+                * string (see audit_filter_exe()), and for received records.
+                */
+               char data[sizeof(struct audit_rule_data) + PATH_MAX];
        };
 };
 
@@ -171,6 +175,9 @@ static int audit_filter_exe(const int audit_fd,
        if (filter->record_type != AUDIT_EXE)
                return -EINVAL;
 
+       if (msg.header.nlmsg_len > sizeof(msg))
+               return -E2BIG;
+
        memcpy(msg.rule.buf, filter->exe, filter->exe_len);
        return audit_request(audit_fd, &msg, NULL);
 }
-- 
2.56.0


Reply via email to