Re: [PATCH v2] selinux: add permission checks for loading other kinds of kernel files

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Feb 11, 2025 at 1:22 PM <kippndavis.work@xxxxxxx> wrote:
>
> From: "Kipp N. Davis" <kippndavis.work@xxxxxxx>
>
> Although the LSM hooks for loading kernel modules were later generalized
> to cover loading other kinds of files, SELinux didn't implement
> corresponding permission checks, leaving only the module case covered.
> Define and add new permission checks for these other cases.
>
> Signed-off-by: Cameron K. Williams <ckwilliams.work@xxxxxxxxx>
> Signed-off-by: Kipp N. Davis <kippndavis.work@xxxxxxx>

Acked-by: Stephen Smalley <stephen.smalley.work@xxxxxxxxx>

>
> ---
> Changes in v2:
>   - Removed the `-EACCES` return in default case in
>     selinux_kernel_read_file() and selinux_kernel_load_from_file(),
>     reverting previous fallback behavior.
>   - Added a compile-time check in these functions to catch new
>     READING/LOADING_XXX entries.
>
> Thanks for your review! I've adjusted the default case so as to not
> return an error and depart from pre-existing logic. I first tried to use
> the pre-processor #errors but failed with the READING/LOADING_MAX_ID
> enums, so I opted for BUILD_BUG_ON_MSG as a compile-time check with
> those same enums instead to catch new entries.
> ---
>  security/selinux/hooks.c            | 56 +++++++++++++++++++++++------
>  security/selinux/include/classmap.h |  4 ++-
>  2 files changed, 49 insertions(+), 11 deletions(-)
>
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 7b867dfec88b..67bf37693cd7 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -4096,7 +4096,7 @@ static int selinux_kernel_module_request(char *kmod_name)
>                             SYSTEM__MODULE_REQUEST, &ad);
>  }
>
> -static int selinux_kernel_module_from_file(struct file *file)
> +static int selinux_kernel_load_from_file(struct file *file, u32 requested)
>  {
>         struct common_audit_data ad;
>         struct inode_security_struct *isec;
> @@ -4104,12 +4104,9 @@ static int selinux_kernel_module_from_file(struct file *file)
>         u32 sid = current_sid();
>         int rc;
>
> -       /* init_module */
>         if (file == NULL)
>                 return avc_has_perm(sid, sid, SECCLASS_SYSTEM,
> -                                       SYSTEM__MODULE_LOAD, NULL);
> -
> -       /* finit_module */
> +                                       requested, NULL);
>
>         ad.type = LSM_AUDIT_DATA_FILE;
>         ad.u.file = file;
> @@ -4123,7 +4120,7 @@ static int selinux_kernel_module_from_file(struct file *file)
>
>         isec = inode_security(file_inode(file));
>         return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM,
> -                               SYSTEM__MODULE_LOAD, &ad);
> +                               requested, &ad);
>  }
>
>  static int selinux_kernel_read_file(struct file *file,
> @@ -4131,10 +4128,32 @@ static int selinux_kernel_read_file(struct file *file,
>                                     bool contents)
>  {
>         int rc = 0;
> -
> +       BUILD_BUG_ON_MSG(READING_MAX_ID > 7,
> +                 "New kernel_read_file_id introduced; update SELinux!");
>         switch (id) {
> +       case READING_FIRMWARE:
> +               rc = selinux_kernel_load_from_file(contents ? file : NULL,
> +                               SYSTEM__FIRMWARE_LOAD);
> +               break;
>         case READING_MODULE:
> -               rc = selinux_kernel_module_from_file(contents ? file : NULL);
> +               rc = selinux_kernel_load_from_file(contents ? file : NULL,
> +                               SYSTEM__MODULE_LOAD);
> +               break;
> +       case READING_KEXEC_IMAGE:
> +               rc = selinux_kernel_load_from_file(contents ? file : NULL,
> +                               SYSTEM__KEXEC_IMAGE_LOAD);
> +               break;
> +       case READING_KEXEC_INITRAMFS:
> +               rc = selinux_kernel_load_from_file(contents ? file : NULL,
> +                               SYSTEM__KEXEC_INITRAMFS_LOAD);
> +               break;
> +       case READING_POLICY:
> +               rc = selinux_kernel_load_from_file(contents ? file : NULL,
> +                               SYSTEM__POLICY_LOAD);
> +               break;
> +       case READING_X509_CERTIFICATE:
> +               rc = selinux_kernel_load_from_file(contents ? file : NULL,
> +                               SYSTEM__X509_CERTIFICATE_LOAD);
>                 break;
>         default:
>                 break;
> @@ -4146,10 +4165,27 @@ static int selinux_kernel_read_file(struct file *file,
>  static int selinux_kernel_load_data(enum kernel_load_data_id id, bool contents)
>  {
>         int rc = 0;
> -
> +       BUILD_BUG_ON_MSG(LOADING_MAX_ID > 7,
> +        "New kernel_load_data_id introduced; update SELinux!");
>         switch (id) {
> +       case LOADING_FIRMWARE:
> +               rc = selinux_kernel_load_from_file(NULL, SYSTEM__FIRMWARE_LOAD);
> +               break;
>         case LOADING_MODULE:
> -               rc = selinux_kernel_module_from_file(NULL);
> +               rc = selinux_kernel_load_from_file(NULL, SYSTEM__MODULE_LOAD);
> +               break;
> +       case LOADING_KEXEC_IMAGE:
> +               rc = selinux_kernel_load_from_file(NULL, SYSTEM__KEXEC_IMAGE_LOAD);
> +               break;
> +       case LOADING_KEXEC_INITRAMFS:
> +               rc = selinux_kernel_load_from_file(NULL, SYSTEM__KEXEC_INITRAMFS_LOAD);
> +               break;
> +       case LOADING_POLICY:
> +               rc = selinux_kernel_load_from_file(NULL, SYSTEM__POLICY_LOAD);
> +               break;
> +       case LOADING_X509_CERTIFICATE:
> +               rc = selinux_kernel_load_from_file(NULL,
> +                               SYSTEM__X509_CERTIFICATE_LOAD);
>                 break;
>         default:
>                 break;
> diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
> index 03e82477dce9..cfac41d12f7d 100644
> --- a/security/selinux/include/classmap.h
> +++ b/security/selinux/include/classmap.h
> @@ -63,7 +63,9 @@ const struct security_class_mapping secclass_map[] = {
>         { "process2", { "nnp_transition", "nosuid_transition", NULL } },
>         { "system",
>           { "ipc_info", "syslog_read", "syslog_mod", "syslog_console",
> -           "module_request", "module_load", NULL } },
> +           "module_request", "module_load", "firmware_load",
> +           "kexec_image_load", "kexec_initramfs_load", "policy_load",
> +           "x509_certificate_load", NULL } },
>         { "capability", { COMMON_CAP_PERMS, NULL } },
>         { "filesystem",
>           { "mount", "remount", "unmount", "getattr", "relabelfrom",
> --
> 2.48.1
>





[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux