mirror of
https://github.com/systemd/systemd.git
synced 2024-11-23 02:03:37 +08:00
Revert "audit-util: return -ENODATA from audit_{session|loginuid}_from_pid() …"
This commit is contained in:
parent
52b0351a15
commit
be46e1d70f
@ -15,59 +15,27 @@
|
||||
#include "parse-util.h"
|
||||
#include "process-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "user-util.h"
|
||||
#include "virt.h"
|
||||
|
||||
static int audit_read_field(const PidRef *pid, const char *field, char **ret) {
|
||||
int r;
|
||||
|
||||
assert(field);
|
||||
assert(ret);
|
||||
|
||||
if (!pidref_is_set(pid))
|
||||
return -ESRCH;
|
||||
|
||||
/* Auditing is currently not virtualized for containers. Let's hence not use the audit session ID or
|
||||
* login UID for now, it will be leaked in from the host */
|
||||
if (detect_container() > 0)
|
||||
return -ENODATA;
|
||||
|
||||
const char *p = procfs_file_alloca(pid->pid, field);
|
||||
|
||||
int audit_session_from_pid(pid_t pid, uint32_t *id) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
bool enoent = false;
|
||||
r = read_virtual_file(p, SIZE_MAX, &s, /* ret_size= */ NULL);
|
||||
if (r == -ENOENT) {
|
||||
if (proc_mounted() == 0)
|
||||
return -ENOSYS;
|
||||
enoent = true;
|
||||
} else if (r < 0)
|
||||
return r;
|
||||
|
||||
r = pidref_verify(pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (enoent) /* We got ENOENT, but /proc/ was mounted and the PID still valid? In that case it appears
|
||||
* auditing is not supported by the kernel. */
|
||||
return -ENODATA;
|
||||
|
||||
delete_trailing_chars(s, NEWLINE);
|
||||
|
||||
*ret = TAKE_PTR(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int audit_session_from_pid(const PidRef *pid, uint32_t *ret_id) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
int r;
|
||||
|
||||
r = audit_read_field(pid, "sessionid", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
const char *p;
|
||||
uint32_t u;
|
||||
int r;
|
||||
|
||||
assert(id);
|
||||
|
||||
/* We don't convert ENOENT to ESRCH here, since we can't
|
||||
* really distinguish between "audit is not available in the
|
||||
* kernel" and "the process does not exist", both which will
|
||||
* result in ENOENT. */
|
||||
|
||||
p = procfs_file_alloca(pid, "sessionid");
|
||||
|
||||
r = read_one_line_file(p, &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = safe_atou32(s, &u);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -75,24 +43,32 @@ int audit_session_from_pid(const PidRef *pid, uint32_t *ret_id) {
|
||||
if (!audit_session_is_valid(u))
|
||||
return -ENODATA;
|
||||
|
||||
if (ret_id)
|
||||
*ret_id = u;
|
||||
|
||||
*id = u;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int audit_loginuid_from_pid(const PidRef *pid, uid_t *ret_uid) {
|
||||
int audit_loginuid_from_pid(pid_t pid, uid_t *uid) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
const char *p;
|
||||
uid_t u;
|
||||
int r;
|
||||
|
||||
r = audit_read_field(pid, "loginuid", &s);
|
||||
assert(uid);
|
||||
|
||||
p = procfs_file_alloca(pid, "loginuid");
|
||||
|
||||
r = read_one_line_file(p, &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (streq(s, "4294967295")) /* loginuid as 4294967295 means not part of any session. */
|
||||
r = parse_uid(s, &u);
|
||||
if (r == -ENXIO) /* the UID was -1 */
|
||||
return -ENODATA;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return parse_uid(s, ret_uid);
|
||||
*uid = u;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int try_audit_request(int fd) {
|
||||
@ -137,32 +113,33 @@ bool use_audit(void) {
|
||||
static int cached_use = -1;
|
||||
int r;
|
||||
|
||||
if (cached_use >= 0)
|
||||
return cached_use;
|
||||
if (cached_use < 0) {
|
||||
int fd;
|
||||
|
||||
_cleanup_close_ int fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_AUDIT);
|
||||
if (fd < 0) {
|
||||
cached_use = !ERRNO_IS_PRIVILEGE(errno) && !ERRNO_IS_NOT_SUPPORTED(errno);
|
||||
if (cached_use)
|
||||
log_debug_errno(errno, "Unexpected error while creating audit socket, proceeding with its use: %m");
|
||||
else
|
||||
log_debug_errno(errno, "Won't talk to audit, because feature or privilege absent: %m");
|
||||
} else {
|
||||
/* If we try and use the audit fd but get -ECONNREFUSED, it is because we are not in the
|
||||
* initial user namespace, and the kernel does not have support for audit outside of the
|
||||
* initial user namespace (see
|
||||
* https://elixir.bootlin.com/linux/latest/C/ident/audit_netlink_ok).
|
||||
*
|
||||
* If we receive any other error, do not disable audit because we are not sure that the error
|
||||
* indicates that audit will not work in general. */
|
||||
r = try_audit_request(fd);
|
||||
if (r < 0) {
|
||||
cached_use = r != -ECONNREFUSED;
|
||||
log_debug_errno(r, cached_use ?
|
||||
"Failed to make request on audit fd, ignoring: %m" :
|
||||
"Won't talk to audit: %m");
|
||||
} else
|
||||
cached_use = true;
|
||||
fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_AUDIT);
|
||||
if (fd < 0) {
|
||||
cached_use = !IN_SET(errno, EAFNOSUPPORT, EPROTONOSUPPORT, EPERM);
|
||||
if (!cached_use)
|
||||
log_debug_errno(errno, "Won't talk to audit: %m");
|
||||
} else {
|
||||
/* If we try and use the audit fd but get -ECONNREFUSED, it is because
|
||||
* we are not in the initial user namespace, and the kernel does not
|
||||
* have support for audit outside of the initial user namespace
|
||||
* (see https://elixir.bootlin.com/linux/latest/C/ident/audit_netlink_ok).
|
||||
*
|
||||
* If we receive any other error, do not disable audit because we are not
|
||||
* sure that the error indicates that audit will not work in general. */
|
||||
r = try_audit_request(fd);
|
||||
if (r < 0) {
|
||||
cached_use = r != -ECONNREFUSED;
|
||||
log_debug_errno(r, cached_use ?
|
||||
"Failed to make request on audit fd, ignoring: %m" :
|
||||
"Won't talk to audit: %m");
|
||||
} else
|
||||
cached_use = true;
|
||||
|
||||
safe_close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
return cached_use;
|
||||
|
@ -5,12 +5,10 @@
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "pidref.h"
|
||||
|
||||
#define AUDIT_SESSION_INVALID UINT32_MAX
|
||||
|
||||
int audit_session_from_pid(const PidRef *pid, uint32_t *id);
|
||||
int audit_loginuid_from_pid(const PidRef *pid, uid_t *uid);
|
||||
int audit_session_from_pid(pid_t pid, uint32_t *id);
|
||||
int audit_loginuid_from_pid(pid_t pid, uid_t *uid);
|
||||
|
||||
bool use_audit(void);
|
||||
|
||||
|
@ -1815,9 +1815,6 @@ int namespace_fork(
|
||||
int set_oom_score_adjust(int value) {
|
||||
char t[DECIMAL_STR_MAX(int)];
|
||||
|
||||
if (!oom_score_adjust_is_valid(value))
|
||||
return -EINVAL;
|
||||
|
||||
xsprintf(t, "%i", value);
|
||||
|
||||
return write_string_file("/proc/self/oom_score_adj", t,
|
||||
@ -1834,16 +1831,11 @@ int get_oom_score_adjust(int *ret) {
|
||||
|
||||
delete_trailing_chars(t, WHITESPACE);
|
||||
|
||||
r = safe_atoi(t, &a);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!oom_score_adjust_is_valid(a))
|
||||
return -ENODATA;
|
||||
assert_se(safe_atoi(t, &a) >= 0);
|
||||
assert_se(oom_score_adjust_is_valid(a));
|
||||
|
||||
if (ret)
|
||||
*ret = a;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -526,8 +526,8 @@ static void client_context_really_refresh(
|
||||
client_context_read_basic(c);
|
||||
(void) client_context_read_label(c, label, label_size);
|
||||
|
||||
(void) audit_session_from_pid(&PIDREF_MAKE_FROM_PID(c->pid), &c->auditid);
|
||||
(void) audit_loginuid_from_pid(&PIDREF_MAKE_FROM_PID(c->pid), &c->loginuid);
|
||||
(void) audit_session_from_pid(c->pid, &c->auditid);
|
||||
(void) audit_loginuid_from_pid(c->pid, &c->loginuid);
|
||||
|
||||
(void) client_context_read_cgroup(s, c, unit_id);
|
||||
(void) client_context_read_invocation_id(s, c);
|
||||
|
@ -1118,7 +1118,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, PidRef *pidref, pid_t tid
|
||||
}
|
||||
|
||||
if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
|
||||
r = audit_session_from_pid(pidref, &c->audit_session_id);
|
||||
r = audit_session_from_pid(pidref->pid, &c->audit_session_id);
|
||||
if (r == -ENODATA) {
|
||||
/* ENODATA means: no audit session id assigned */
|
||||
c->audit_session_id = AUDIT_SESSION_INVALID;
|
||||
@ -1131,7 +1131,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, PidRef *pidref, pid_t tid
|
||||
}
|
||||
|
||||
if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
|
||||
r = audit_loginuid_from_pid(pidref, &c->audit_login_uid);
|
||||
r = audit_loginuid_from_pid(pidref->pid, &c->audit_login_uid);
|
||||
if (r == -ENODATA) {
|
||||
/* ENODATA means: no audit login uid assigned */
|
||||
c->audit_login_uid = UID_INVALID;
|
||||
|
@ -1006,7 +1006,7 @@ static int create_session(
|
||||
"Maximum number of sessions (%" PRIu64 ") reached, refusing further sessions.",
|
||||
m->sessions_max);
|
||||
|
||||
(void) audit_session_from_pid(&leader, &audit_id);
|
||||
(void) audit_session_from_pid(leader.pid, &audit_id);
|
||||
if (audit_session_is_valid(audit_id)) {
|
||||
/* Keep our session IDs and the audit session IDs in sync */
|
||||
|
||||
|
@ -254,7 +254,7 @@ int session_set_leader_consume(Session *s, PidRef _leader) {
|
||||
s->leader_fd_saved = true;
|
||||
}
|
||||
|
||||
(void) audit_session_from_pid(&s->leader, &s->audit_id);
|
||||
(void) audit_session_from_pid(s->leader.pid, &s->audit_id);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -46,7 +46,6 @@ simple_tests += files(
|
||||
'test-alloc-util.c',
|
||||
'test-architecture.c',
|
||||
'test-argv-util.c',
|
||||
'test-audit-util.c',
|
||||
'test-barrier.c',
|
||||
'test-bitfield.c',
|
||||
'test-bitmap.c',
|
||||
|
@ -1,35 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "audit-util.h"
|
||||
#include "tests.h"
|
||||
|
||||
TEST(audit_loginuid_from_pid) {
|
||||
_cleanup_(pidref_done) PidRef self = PIDREF_NULL, pid1 = PIDREF_NULL;
|
||||
int r;
|
||||
|
||||
assert_se(pidref_set_self(&self) >= 0);
|
||||
assert_se(pidref_set_pid(&pid1, 1) >= 0);
|
||||
|
||||
uid_t uid;
|
||||
r = audit_loginuid_from_pid(&self, &uid);
|
||||
assert_se(r >= 0 || r == -ENODATA);
|
||||
if (r >= 0)
|
||||
log_info("self audit login uid: " UID_FMT, uid);
|
||||
|
||||
assert_se(audit_loginuid_from_pid(&pid1, &uid) == -ENODATA);
|
||||
|
||||
uint32_t sessionid;
|
||||
r = audit_session_from_pid(&self, &sessionid);
|
||||
assert_se(r >= 0 || r == -ENODATA);
|
||||
if (r >= 0)
|
||||
log_info("self audit session id: %" PRIu32, sessionid);
|
||||
|
||||
assert_se(audit_session_from_pid(&pid1, &sessionid) == -ENODATA);
|
||||
}
|
||||
|
||||
static int intro(void) {
|
||||
log_show_color(true);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro);
|
Loading…
Reference in New Issue
Block a user