[linux-pam] #27: pam_timestamp path traversal issue
by fedora-badges
#27: pam_timestamp path traversal issue
-----------------------+------------------------------
Reporter: tmraz | Owner: pam-developers@…
Type: security | Status: new
Priority: major | Component: modules
Version: | Keywords:
Blocked By: | Blocking:
-----------------------+------------------------------
pam_timestamp uses PAM_RUSER and PAM_TTY directly without any checks. If
the user can mainpulate PAM_RUSER and PAM_TTY contents (which is mostly
not possible, but there might be scenarios where it is) he would be able
to get access to a service without proper checking.
See http://seclists.org/oss-sec/2014/q1/645 for the original report by
Sebastian Krahmer.
I suppose sufficient mitigation would be to look for ".." in both
PAM_RUSER and PAM_TTY and reject authentication attempt if they contain
this string.
I would also document that the module should never be used with services
where the authenticating user can manipulate the PAM_RUSER variable
contents.
--
Ticket URL: <https://fedorahosted.org/linux-pam/ticket/27>
linux-pam <http://fedorahosted.org/linux-pam>
The Linux-PAM (Pluggable Authentication Modules) project
9 years, 5 months
[linux-pam] #31: typos in doc install rules
by fedora-badges
#31: typos in doc install rules
---------------------+------------------------------
Reporter: vapier | Owner: pam-developers@…
Type: defect | Status: new
Priority: major | Component: documentation
Version: | Keywords:
Blocked By: | Blocking:
---------------------+------------------------------
the current Makefile.am doc install-data-local & releasedocs rules try to
test for files existing in the builddir to see whether it should install
from there or the srcdir. it used to largely work before this commit:
https://git.fedorahosted.org/cgit/linux-
pam.git/commit/doc/adg/Makefile.am?id=65b0aeaecd75e081993c48db2837958073185165
but now when you do out of tree builds, it ends up never installing any of
the doc files even though they exist in $srcdir.
there's also a typo in the adg and mwg files where they try to install
"sag" files.
reported here:
[https://bugs.gentoo.org/473650]
--
Ticket URL: <https://fedorahosted.org/linux-pam/ticket/31>
linux-pam <http://fedorahosted.org/linux-pam>
The Linux-PAM (Pluggable Authentication Modules) project
9 years, 5 months
[PATCH] unionfs support for pam_namespace
by Wichert Akkerman
I just a patch which extends pam_namespace to add unionfs support (via aufs). This makes it possible to provide a private version of a directory that is writeable for the user. Configuration is simple: all you need to do is add a “unionfs” option in namespace.conf. In my test system the entry looks like this:
$HOME /private/home/ tmpfs:union,mntopts=size=128m root
With this line pam_namespace does the following:
when using tmpfs with the union option or a different method an instance directory is created
when using the union option the bind mount is replaced with an aufs mount which adds the instance directory as a branch on top of the polyinstantiated directory
Regards,
Wichert.
Index: pam-1.1.8/modules/pam_namespace/pam_namespace.c
===================================================================
--- pam-1.1.8.orig/modules/pam_namespace/pam_namespace.c 2014-06-22 20:27:45.731009280 +0200
+++ pam-1.1.8/modules/pam_namespace/pam_namespace.c 2014-06-22 20:27:56.331008975 +0200
@@ -230,6 +230,28 @@
return 0;
}
+/**
+ * Check if we can mount directly on top of the polydir_s.dir, or we
+ * need to go through polydir_s.rdir.
+ */
+static int can_mount_polydir_directly(const struct polydir_s* s) {
+ return s->method == TMPFS && !(s->flags & POLYDIR_UNION);
+}
+
+static int is_legal_aufs_path(char* path)
+{
+ /*
+ * From aufs(5):
+ * Comma, colon and the permission flags string (including ‘=’) in
+ * the path are not allowed.
+ */
+ return strchr(path, ',')==NULL &&
+ strchr(path, ',')==NULL &&
+ strstr(path, "=rw")==NULL &&
+ strstr(path, "=ro")==NULL &&
+ strstr(path, "=rr")==NULL;
+}
+
static int parse_method(char *method, struct polydir_s *poly,
struct instance_data *idata)
{
@@ -238,9 +260,9 @@
static const char *method_names[] = { "user", "context", "level", "tmpdir",
"tmpfs", NULL };
static const char *flag_names[] = { "create", "noinit", "iscript",
- "shared", "mntopts", NULL };
+ "shared", "mntopts", "union", NULL };
static const unsigned int flag_values[] = { POLYDIR_CREATE, POLYDIR_NOINIT,
- POLYDIR_ISCRIPT, POLYDIR_SHARED, POLYDIR_MNTOPTS };
+ POLYDIR_ISCRIPT, POLYDIR_SHARED, POLYDIR_MNTOPTS, POLYDIR_UNION };
int i;
char *flag;
@@ -294,6 +316,17 @@
return -1;
}
break;
+
+ case POLYDIR_UNION:
+ if (!is_legal_aufs_path(poly->dir)) {
+ pam_syslog(idata->pamh, LOG_CRIT, "Illegal polydir path for aufs");
+ return -1;
+ }
+ if (!is_legal_aufs_path(poly->rdir)) {
+ pam_syslog(idata->pamh, LOG_CRIT, "Illegal instance path for aufs");
+ return -1;
+ }
+ break;
}
}
}
@@ -459,7 +492,7 @@
/*
* Ensure that all pathnames are absolute path names.
*/
- if ((poly->dir[0] != '/') || (poly->method != TMPFS && poly->instance_prefix[0] != '/')) {
+ if ((poly->dir[0] != '/') || (!can_mount_polydir_directly(poly) && poly->instance_prefix[0] != '/')) {
pam_syslog(idata->pamh, LOG_NOTICE, "Pathnames must start with '/'");
goto skipping;
}
@@ -1453,6 +1486,7 @@
int newdir = 1;
char *inst_dir = NULL;
char *instname = NULL;
+ char *aufs_opts = NULL;
struct stat statbuf;
#ifdef WITH_SELINUX
security_context_t instcontext = NULL, origcontext = NULL;
@@ -1478,7 +1512,7 @@
close(retval);
}
- if (polyptr->method == TMPFS) {
+ if (polyptr->method == TMPFS && can_mount_polydir_directly(polyptr)) {
if (mount("tmpfs", polyptr->dir, "tmpfs", 0, polyptr->mount_opts) < 0) {
pam_syslog(idata->pamh, LOG_ERR, "Error mounting tmpfs on %s, %m",
polyptr->dir);
@@ -1549,15 +1583,41 @@
goto error_out;
}
- /*
- * Bind mount instance directory on top of the polyinstantiated
- * directory to provide an instance of polyinstantiated directory
- * based on polyinstantiated method.
- */
- if (mount(inst_dir, polyptr->dir, NULL, MS_BIND, NULL) < 0) {
- pam_syslog(idata->pamh, LOG_ERR, "Error mounting %s on %s, %m",
- inst_dir, polyptr->dir);
- goto error_out;
+ if (polyptr->method == TMPFS) {
+ if (mount("tmpfs", inst_dir, "tmpfs", 0, polyptr->mount_opts) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error mounting tmpfs on %s, %m",
+ inst_dir);
+ return PAM_SESSION_ERR;
+ }
+ }
+
+ if (!(polyptr->flags & POLYDIR_UNION)) {
+ /*
+ * Bind mount instance directory on top of the polyinstantiated
+ * directory to provide an instance of polyinstantiated directory
+ * based on polyinstantiated method.
+ */
+ if (mount(inst_dir, polyptr->dir, NULL, MS_BIND, NULL) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error mounting %s on %s, %m",
+ inst_dir, polyptr->dir);
+ goto error_out;
+ }
+ } else {
+ /*
+ * Use aufs to add the instance directory as writable branch of the
+ * polyinstantiated directory.
+ */
+ if (asprintf(&aufs_opts, "br=%s:%s", inst_dir, polyptr->dir) == -1) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error aufs mounting %s on %s, %m",
+ inst_dir, polyptr->dir);
+ goto error_out;
+ }
+
+ if (mount(inst_dir, polyptr->dir, "aufs", 0, aufs_opts) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error aufs mounting %s on %s, %m",
+ inst_dir, polyptr->dir);
+ goto error_out;
+ }
}
if (!(polyptr->flags & POLYDIR_NOINIT))
@@ -1573,6 +1633,7 @@
retval = PAM_SESSION_ERR;
cleanup:
+ free(aufs_opts);
free(inst_dir);
free(instname);
#ifdef WITH_SELINUX
Index: pam-1.1.8/modules/pam_namespace/pam_namespace.h
===================================================================
--- pam-1.1.8.orig/modules/pam_namespace/pam_namespace.h 2014-06-22 20:27:45.731009280 +0200
+++ pam-1.1.8/modules/pam_namespace/pam_namespace.h 2014-06-22 20:27:56.331008975 +0200
@@ -117,6 +117,7 @@
#define POLYDIR_SHARED 0x00000008 /* share context/level instances among users */
#define POLYDIR_ISCRIPT 0x00000010 /* non default init script */
#define POLYDIR_MNTOPTS 0x00000020 /* mount options for tmpfs mount */
+#define POLYDIR_UNION 0x00000040 /* aufs mount over polydir */
#define NAMESPACE_MAX_DIR_LEN 80
9 years, 10 months
Adding aufs support to pam_namespace
by Wichert Akkerman
I am trying to setup a system users are allowed to login on a system, but there actions are not persisted. pam_namespace is very helpful there since it gives me a way to setup tmpfs-based /tmp and /var/tmp for each session. What I am missing is a way to give access to the homedirectory for a user, but not persist any changes. Using aufs seems to be a good solution: just setup a temporary directory (like pam_namespace already does), but instead of doing a bind-mount to the desired location use aufs to layer the temporary space on top of an existing space. This should (famous last words) be reasonably easy to add to pam_namespace. Configuration could be something like this:
# Create a /private/home/$USER directory, and layer that on home of $HOME
$HOME /private/home/$USER level,union
# Add a tmpfs on top of $HOME, so the home directory contents remains available
# but all changes are automatically lost on logout.
$HOME unused tmpfs,union
Is there any interested in adding this to linux-pam itself?
Regards,
Wichert.
9 years, 10 months