]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: downgrade errors about BPF loading when called from socket_bind_supported() 19835/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 7 Jun 2021 08:20:30 +0000 (10:20 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 7 Jun 2021 08:28:46 +0000 (10:28 +0200)
prepare_socket_bind_bpf() is called from two sites: socket_bind_supported() and
socket_bind_install_impl(). For the latter, when errors occur we certainly want
to log, since they'll be fatal for the unit.  But for the former, we should be
quiet, at least on the "expected" errors like lack of permissions. I kept error
on map resizing and such, which should not fail, at log_warning(). They are not
fatal when called from socket_bind_suppported(), but still a sign that
something is off.

Currently BPF filters can only be used by privileged users. Thus each systemd
--user will fail in socket_bind_supported(). With the patch, we only log this
at debug level.

https://lwn.net/ml/bpf/cover.1620499942.git.yifeifz2@illinois.edu/ gives some
hope that unprivileged access will be possible, so let's keep the code trying.
We might get lucky and get support for filters in user mode without any changes
on our side.

src/core/socket-bind.c

index 25c6fecb5a0bf0fdb4193f865bc9c757e54d13d3..352b47ad9fb43e230a18d2d70f77a2049287c12f 100644 (file)
@@ -61,45 +61,47 @@ static int prepare_socket_bind_bpf(
                 deny_count++;
 
         if (allow_count > SOCKET_BIND_MAX_RULES)
-                return log_unit_error_errno(u, SYNTHETIC_ERRNO(EINVAL),
-                                "Maximum number of socket bind rules=%u is exceeded", SOCKET_BIND_MAX_RULES);
+                return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, SYNTHETIC_ERRNO(EINVAL),
+                                           "Maximum number of socket bind rules=%u is exceeded", SOCKET_BIND_MAX_RULES);
 
         if (deny_count > SOCKET_BIND_MAX_RULES)
-                return log_unit_error_errno(u, SYNTHETIC_ERRNO(EINVAL),
-                                "Maximum number of socket bind rules=%u is exceeded", SOCKET_BIND_MAX_RULES);
+                return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, SYNTHETIC_ERRNO(EINVAL),
+                                           "Maximum number of socket bind rules=%u is exceeded", SOCKET_BIND_MAX_RULES);
 
         obj = socket_bind_bpf__open();
         if (!obj)
-                return log_unit_error_errno(u, SYNTHETIC_ERRNO(ENOMEM), "Failed to open BPF object");
+                return log_unit_full_errno(u, u ? LOG_ERR : LOG_DEBUG, SYNTHETIC_ERRNO(ENOMEM),
+                                           "Failed to open BPF object");
 
         if (sym_bpf_map__resize(obj->maps.sd_bind_allow, MAX(allow_count, 1u)) != 0)
-                return log_unit_error_errno(u, errno,
-                                "Failed to resize BPF map '%s': %m", sym_bpf_map__name(obj->maps.sd_bind_allow));
+                return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, errno,
+                                           "Failed to resize BPF map '%s': %m", sym_bpf_map__name(obj->maps.sd_bind_allow));
 
         if (sym_bpf_map__resize(obj->maps.sd_bind_deny, MAX(deny_count, 1u)) != 0)
-                return log_unit_error_errno(u, errno,
-                                "Failed to resize BPF map '%s': %m", sym_bpf_map__name(obj->maps.sd_bind_deny));
+                return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, errno,
+                                           "Failed to resize BPF map '%s': %m", sym_bpf_map__name(obj->maps.sd_bind_deny));
 
         if (socket_bind_bpf__load(obj) != 0)
-                return log_unit_error_errno(u, errno, "Failed to load BPF object: %m");
+                return log_unit_full_errno(u, u ? LOG_ERR : LOG_DEBUG, errno,
+                                           "Failed to load BPF object: %m");
 
         allow_map_fd = sym_bpf_map__fd(obj->maps.sd_bind_allow);
         assert(allow_map_fd >= 0);
 
         r = update_rules_map(allow_map_fd, allow);
         if (r < 0)
-                return log_unit_error_errno(
-                                u, r, "Failed to put socket bind allow rules into BPF map '%s'",
-                                sym_bpf_map__name(obj->maps.sd_bind_allow));
+                return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, r,
+                                           "Failed to put socket bind allow rules into BPF map '%s'",
+                                           sym_bpf_map__name(obj->maps.sd_bind_allow));
 
         deny_map_fd = sym_bpf_map__fd(obj->maps.sd_bind_deny);
         assert(deny_map_fd >= 0);
 
         r = update_rules_map(deny_map_fd, deny);
         if (r < 0)
-                return log_unit_error_errno(
-                                u, r, "Failed to put socket bind deny rules into BPF map '%s'",
-                                sym_bpf_map__name(obj->maps.sd_bind_deny));
+                return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, r,
+                                           "Failed to put socket bind deny rules into BPF map '%s'",
+                                           sym_bpf_map__name(obj->maps.sd_bind_deny));
 
         *ret_obj = TAKE_PTR(obj);
         return 0;