|
|
306fa1 |
autofs-5.1.2 - limit getgrgid_r() buffer size
|
|
|
306fa1 |
|
|
|
306fa1 |
From: Ian Kent <raven@themaw.net>
|
|
|
306fa1 |
|
|
|
306fa1 |
Some older versions of glibc use stack allocation to store group
|
|
|
306fa1 |
information during calls to getgrgid_r(). But before doing this
|
|
|
306fa1 |
it checks if the size of the response info. can fit in the user
|
|
|
306fa1 |
supplied buffer and returns ERANGE if it can't.
|
|
|
306fa1 |
|
|
|
306fa1 |
Now automount(8) doesn't check if the size of the buffer it is
|
|
|
306fa1 |
passing is larger than it's stack size. That's not vey accurrate
|
|
|
306fa1 |
since current stack usage isn't known but better than not checking
|
|
|
306fa1 |
at all.
|
|
|
306fa1 |
|
|
|
306fa1 |
Signed-off-by: Ian Kent <raven@themaw.net>
|
|
|
306fa1 |
---
|
|
|
306fa1 |
CHANGELOG | 1 +
|
|
|
306fa1 |
lib/mounts.c | 47 +++++++++++++++++++++++++++++++++--------------
|
|
|
306fa1 |
2 files changed, 34 insertions(+), 14 deletions(-)
|
|
|
306fa1 |
|
|
|
306fa1 |
--- autofs-5.0.7.orig/CHANGELOG
|
|
|
306fa1 |
+++ autofs-5.0.7/CHANGELOG
|
|
|
306fa1 |
@@ -248,6 +248,7 @@
|
|
|
306fa1 |
- improve scalability of direct mount path component.
|
|
|
306fa1 |
- fix invalid reference in remount_active_mount().
|
|
|
306fa1 |
- increase worker thread per-thread stack size.
|
|
|
306fa1 |
+- limit getgrgid_r() buffer size.
|
|
|
306fa1 |
|
|
|
306fa1 |
25/07/2012 autofs-5.0.7
|
|
|
306fa1 |
=======================
|
|
|
306fa1 |
--- autofs-5.0.7.orig/lib/mounts.c
|
|
|
306fa1 |
+++ autofs-5.0.7/lib/mounts.c
|
|
|
306fa1 |
@@ -48,6 +48,9 @@ static const char mnt_name_template[]
|
|
|
306fa1 |
static struct kernel_mod_version kver = {0, 0};
|
|
|
306fa1 |
static const char kver_options_template[] = "fd=%d,pgrp=%u,minproto=3,maxproto=5";
|
|
|
306fa1 |
|
|
|
306fa1 |
+extern size_t detached_thread_stack_size;
|
|
|
306fa1 |
+static size_t maxgrpbuf = 0;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
#define EXT_MOUNTS_HASH_SIZE 50
|
|
|
306fa1 |
|
|
|
306fa1 |
struct ext_mount {
|
|
|
306fa1 |
@@ -1503,14 +1506,22 @@ void set_tsd_user_vars(unsigned int logo
|
|
|
306fa1 |
}
|
|
|
306fa1 |
|
|
|
306fa1 |
gr_tmp = NULL;
|
|
|
306fa1 |
+ status = ERANGE;
|
|
|
306fa1 |
+ if (!maxgrpbuf)
|
|
|
306fa1 |
+ maxgrpbuf = detached_thread_stack_size * 0.9;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ /* If getting the group name fails go on without it. It's
|
|
|
306fa1 |
+ * used to set an environment variable for program maps
|
|
|
306fa1 |
+ * which may or may not use it so it isn't critical to
|
|
|
306fa1 |
+ * operation.
|
|
|
306fa1 |
+ */
|
|
|
306fa1 |
+
|
|
|
306fa1 |
tmplen = grplen;
|
|
|
306fa1 |
while (1) {
|
|
|
306fa1 |
char *tmp = realloc(gr_tmp, tmplen + 1);
|
|
|
306fa1 |
if (!tmp) {
|
|
|
306fa1 |
error(logopt, "failed to malloc buffer for getgrgid_r");
|
|
|
306fa1 |
- if (gr_tmp)
|
|
|
306fa1 |
- free(gr_tmp);
|
|
|
306fa1 |
- goto free_tsv_home;
|
|
|
306fa1 |
+ goto no_group;
|
|
|
306fa1 |
}
|
|
|
306fa1 |
gr_tmp = tmp;
|
|
|
306fa1 |
pgr = &gr;
|
|
|
306fa1 |
@@ -1519,22 +1530,29 @@ void set_tsd_user_vars(unsigned int logo
|
|
|
306fa1 |
if (status != ERANGE)
|
|
|
306fa1 |
break;
|
|
|
306fa1 |
tmplen += grplen;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ /* Don't tempt glibc to alloca() larger than is (likely)
|
|
|
306fa1 |
+ * available on the stack.
|
|
|
306fa1 |
+ */
|
|
|
306fa1 |
+ if (tmplen < maxgrpbuf)
|
|
|
306fa1 |
+ continue;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ /* Add a message so we know this happened */
|
|
|
306fa1 |
+ debug(logopt, "group buffer allocation would be too large");
|
|
|
306fa1 |
+ break;
|
|
|
306fa1 |
}
|
|
|
306fa1 |
|
|
|
306fa1 |
- if (status || !pgr) {
|
|
|
306fa1 |
+no_group:
|
|
|
306fa1 |
+ if (status || !pgr)
|
|
|
306fa1 |
error(logopt, "failed to get group info from getgrgid_r");
|
|
|
306fa1 |
- free(gr_tmp);
|
|
|
306fa1 |
- goto free_tsv_home;
|
|
|
306fa1 |
+ else {
|
|
|
306fa1 |
+ tsv->group = strdup(gr.gr_name);
|
|
|
306fa1 |
+ if (!tsv->group)
|
|
|
306fa1 |
+ error(logopt, "failed to malloc buffer for group");
|
|
|
306fa1 |
}
|
|
|
306fa1 |
|
|
|
306fa1 |
- tsv->group = strdup(gr.gr_name);
|
|
|
306fa1 |
- if (!tsv->group) {
|
|
|
306fa1 |
- error(logopt, "failed to malloc buffer for group");
|
|
|
306fa1 |
+ if (gr_tmp)
|
|
|
306fa1 |
free(gr_tmp);
|
|
|
306fa1 |
- goto free_tsv_home;
|
|
|
306fa1 |
- }
|
|
|
306fa1 |
-
|
|
|
306fa1 |
- free(gr_tmp);
|
|
|
306fa1 |
|
|
|
306fa1 |
status = pthread_setspecific(key_thread_stdenv_vars, tsv);
|
|
|
306fa1 |
if (status) {
|
|
|
306fa1 |
@@ -1545,7 +1563,8 @@ void set_tsd_user_vars(unsigned int logo
|
|
|
306fa1 |
return;
|
|
|
306fa1 |
|
|
|
306fa1 |
free_tsv_group:
|
|
|
306fa1 |
- free(tsv->group);
|
|
|
306fa1 |
+ if (tsv->group)
|
|
|
306fa1 |
+ free(tsv->group);
|
|
|
306fa1 |
free_tsv_home:
|
|
|
306fa1 |
free(tsv->home);
|
|
|
306fa1 |
free_tsv_user:
|