[systemd-devel] [PATCH] mount and initialize Smack
Lennart Poettering
lennart at poettering.net
Thu Mar 7 11:59:11 PST 2013
On Thu, 07.03.13 11:06, Nathaniel Chen (nathaniel.chen at intel.com) wrote:
> SMACK is the Simple Mandatory Access Control Kernel, a minimal
> approach to Access Control implemented as a kernel LSM.
>
> The kernel exposes the smackfs filesystem API through which access
> rules can be loaded. At boot time, we want to load the access rules
> as early as possible to ensure all early boot steps are checked by Smack.
>
> This patch mounts smackfs at the new location at /sys/fs/smackfs for
> kernels 3.8 and above. The /smack mountpoint is not supported.
> After mounting smackfs, rules are loaded from the usual location.
>
> For more information about Smack see:
> http://www.kernel.org/doc/Documentation/security/Smack.txt
Merged all three, but made some changes. Just to point this out:
> +int smack_setup(void) {
> +
> + FILE _cleanup_fclose_ *smack = NULL;
> + FILE _cleanup_fclose_ *policy = NULL;
> + int _cleanup_close_ dfd = -1;
> + int _cleanup_close_ pol = -1;
The _cleanup_xyz_ stuff works on the C block scope. i.e. if you use this
like this these the four variables will be freed once when the function
exits. However, you allocate into them a couple of times inside the
inner loop, so the earlier instances are lost. Moving this into the loop
instead fixes it, since then the per-scope logic makes sure the
variables are freed on each loop iteration.
Also, the diretcory fd is closed as part of the DIR* object anyway, and
similar the pol fd is closed as part of the policy FILE* object. So you
closed these twice.
> + DIR *dir = NULL;
> + struct dirent *entry;
> + char buf[NAME_MAX];
> +
> + smack = fopen("/sys/fs/smackfs/load2", "we");
> + if (smack == NULL) {
> + log_info("Smack is not enabled in the kernel, not loading access rules.");
> + return 0;
> + }
> +
> + /* write rules to load2 from every file in the directory */
> + dir = opendir(ACCESSES_D_PATH);
> + if (dir == NULL) {
> + log_info("Smack access rules directory not found: %s", ACCESSES_D_PATH);
> + return 0;
> + }
> + dfd = dirfd(dir);
> + if (dfd == -1) {
> + log_error("Smack access rules directory %s not opened: %m.", ACCESSES_D_PATH);
> + return 0;
> + }
> + FOREACH_DIRENT(entry, dir, return 0;) {
> + if (entry->d_name[0] == '.')
> + continue;
This is actually redundant, as the macro does it anyway...
> + pol = openat(dfd, entry->d_name, O_RDONLY);
> + if (pol == -1) {
> + log_error("Smack access rule file %s not opened: %m", entry->d_name);
> + continue;
> + }
> + policy = fdopen(pol, "re");
> + if (policy == NULL) {
> + log_error("Smack access rule file %s not opened: %m", entry->d_name);
> + continue;
> + }
> + /* load2 write rules in the kernel require a line buffered stream */
> + FOREACH_LINE(buf, policy, log_error("Failed to read
> from Smack access rule file %s: %m", policy); continue;) {
You certainly don't want to continue reading file after we hit an IO
error... That would result in a busy loop.
> + fputs(buf, smack);
> + fflush(smack);
> + }
> + }
> + log_info("Successfully loaded Smack policies.");
Anyway, all commited, but not tested after my changes, since I don't
have SMACK. Please test.
Lennart
--
Lennart Poettering - Red Hat, Inc.
More information about the systemd-devel
mailing list