From: Luke Kenneth Casson Leighton <lkcl@lkcl.net>
To: SELinux <selinux@tycho.nsa.gov>
Subject: Re: running interpreted scripts in different domains
Date: Thu, 22 Jul 2004 09:56:51 +0100 [thread overview]
Message-ID: <20040722085651.GD3252@lkcl.net> (raw)
In-Reply-To: <20040721230605.GD2848@jmh.mhn.de>
On Thu, Jul 22, 2004 at 01:06:06AM +0200, Thomas Bleher wrote:
> How does cron handle this? I think that cron is in a similar situation
> since it can't exec the users crontab. From macros/program/crond_macros.te:
>
> # Permit a transition from the crond_t domain to this domain.
> # The transition is requested explicitly by the modified crond
> # via execve_secure. There is no way to set up an automatic
> # transition, since crontabs are configuration files, not executables.
> domain_trans(crond_t, shell_exec_t, $1_crond_t)
>
> Additionaly, crond has this:
> # Set exec context.
> can_setexec(crond_t)
>
> Maybe someone who knows the cron code better than me can explain what
> exactly cron is doing and if this can be applied to the fastcgi code as
> well.
this patch fragment is out-of-date, dan walsh has done some updates
since:
--- database.c.old 2004-05-19 10:03:06.000000000 +0100
+++ database.c 2004-05-20 15:15:55.000000000 +0100
@@ -30,6 +30,11 @@
#include <sys/stat.h>
#include <sys/file.h>
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#include <selinux/flask.h>
+#include <selinux/av_permissions.h>
+#endif
#define TMAX(a,b) ((a)>(b)?(a):(b))
@@ -46,7 +51,7 @@
#endif /* ifndef PATH_MAX */
-static void process_crontab __P((char *, char *, char *,
+static void process_crontab __P((char *, char *, char *,
struct stat *,
cron_db *, cron_db *));
#ifdef DEBIAN
@@ -167,7 +172,7 @@
new_db.head = new_db.tail = NULL;
if (syscron_stat.st_mtime) {
- process_crontab("root", "*system*",
+ process_crontab(SYSUSERNAME, "*system*",
SYSCRONTAB, &syscron_stat,
&new_db, old_db);
}
@@ -205,7 +210,7 @@
/* statbuf is used as working storage by process_crontab() --
current contents are irrelevant */
- process_crontab("root", fname, tabname,
+ process_crontab(SYSUSERNAME, fname, tabname,
&statbuf, &new_db, old_db);
}
@@ -324,6 +329,13 @@
int crontab_fd = OK - 1;
user *u;
+#ifdef WITH_SELINUX
+ security_context_t file_context=NULL;
+ security_context_t user_context=NULL;
+ struct av_decision avd;
+ int retval=0, selinux_enabled = (is_selinux_enabled() > 0);
+#endif
+
#ifdef DEBIAN
/* If the name begins with *system*, don't worry about password -
it's part of the system crontab */
@@ -349,6 +361,14 @@
goto next_crontab;
}
+#ifdef WITH_SELINUX
+ if (selinux_enabled) {
+ if (fgetfilecon(crontab_fd, &file_context) < OK) {
+ log_it(fname, getpid(), "getfilecon FAILED", tabname);
+ goto next_crontab;
+ }
+ }
+#endif
if (fstat(crontab_fd, statbuf) < OK) {
log_it(fname, getpid(), "FSTAT FAILED", tabname);
goto next_crontab;
@@ -385,6 +405,14 @@
goto next_crontab;
}
+#ifdef WITH_SELINUX
+ if (selinux_enabled) {
+ if (fgetfilecon(crontab_fd, &file_context) < OK) {
+ log_it(fname, getpid(), "getfilecon FAILED", tabname);
+ goto next_crontab;
+ }
+ }
+#endif
if (fstat(crontab_fd, statbuf) < OK) {
log_it(fname, getpid(), "FSTAT FAILED", tabname);
goto next_crontab;
@@ -425,6 +453,31 @@
free_user(u);
log_it(fname, getpid(), "RELOAD", tabname);
}
+#ifdef WITH_SELINUX
+ if (selinux_enabled) {
+ /*
+ * Since crontab files are not directly executed,
+ * crond must ensure that the crontab file has
+ * a context that is appropriate for the context of
+ * the user cron job. It performs an entrypoint
+ * permission check for this purpose.
+ */
+ if (get_default_context(uname, NULL, &user_context)) {
+ log_it(uname, getpid(), "NO CONTEXT", tabname);
+ goto next_crontab;
+ }
+ retval = security_compute_av(user_context, file_context,
+ SECCLASS_FILE, FILE__ENTRYPOINT, &avd);
+ freecon(user_context);
+ freecon(file_context);
+ file_context = NULL;
+
+ if (retval || ((FILE__ENTRYPOINT & avd.allowed) != FILE__ENTRYPOINT)) {
+ log_it(fname, getpid(), "ENTRYPOINT FAILED", tabname);
+ goto next_crontab;
+ }
+ }
+#endif
u = load_user(crontab_fd, pw, fname);
if (u != NULL) {
u->mtime = statbuf->st_mtime;
@@ -436,6 +489,12 @@
Debug(DLOAD, (" [done]\n"))
close(crontab_fd);
}
+#ifdef WITH_SELINUX
+ if(file_context) {
+ freecon(file_context);
+ file_context = NULL;
+ }
+#endif
}
#ifdef DEBIAN
which i believe to be testing the access permissions on the crontab
file, and in child_process() which is called by do_command() which
is called by job_queue():
#ifdef WITH_SELINUX
if (is_selinux_enabled()) {
security_context_t scontext;
if (get_default_context(u->name, NULL, &scontext)) {
fprintf(stderr, "execle_secure: couldn't get security context for user %s\n", u->name);
_exit(ERROR_EXIT);
}
if (setexeccon(scontext) < 0) {
fprintf(stderr, "Could not set exec context to %s for user %s\n", scontext,u->name);
_exit(ERROR_EXIT);
}
freecon(scontext);
}
#endif
execle(shell, shell, "-c", e->cmd, (char *)0, jobenv);
fprintf(stderr, "execl: couldn't exec `%s'\n", shell);
perror("execl");
_exit(ERROR_EXIT);
}
which ensures that the command is run under the correct user context (u->name).
dan, steven, russell and the deb maintainer steve greene had a bash at
going over this because the deb maintainer would not accept the patch:
the reason it turned out was because of bugs in the patch _and_ in
cron over how to deal with running cron jobs as non-user (i.e. as
the cron system, and the fake and deliberately nonexistent username
*system* was used to "represent" the cron system such that if a
getpwnam was called with "*system*" it would always fail).
of course, cron _does_ have the concept of system, called system_u :)
anyway, as you can see, the shell command is exec'd, there's also
a cron_popen() but i haven't tracked down how it's called.
if fastcgi does an exec?e to run the cgi script, cron's code would,
i believe, be a useful starting point.
l.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
next prev parent reply other threads:[~2004-07-22 9:19 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-07-18 20:33 running interpreted scripts in different domains Joshua Brindle
2004-07-19 8:28 ` Luke Kenneth Casson Leighton
2004-07-19 11:56 ` Russell Coker
2004-07-19 12:01 ` Joshua Brindle
2004-07-20 15:42 ` James Carter
2004-07-20 18:14 ` Joshua Brindle
2004-07-20 20:27 ` James Carter
2004-07-20 20:32 ` Joshua Brindle
2004-07-20 23:22 ` Luke Kenneth Casson Leighton
2004-07-21 0:59 ` Joshua Brindle
2004-07-21 23:06 ` Thomas Bleher
2004-07-22 8:56 ` Luke Kenneth Casson Leighton [this message]
2004-07-22 13:19 ` Daniel J Walsh
2004-07-22 14:35 ` Luke Kenneth Casson Leighton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040722085651.GD3252@lkcl.net \
--to=lkcl@lkcl.net \
--cc=selinux@tycho.nsa.gov \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.