Page MenuHomeFreeBSD

D47016.id144828.diff
No OneTemporary

D47016.id144828.diff

diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c
--- a/usr.sbin/mountd/mountd.c
+++ b/usr.sbin/mountd/mountd.c
@@ -57,6 +57,7 @@
#include <arpa/inet.h>
+#include <assert.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
@@ -245,7 +246,7 @@
static int makemask(struct sockaddr_storage *ssp, int bitlen);
static void mntsrv(struct svc_req *, SVCXPRT *);
static void nextfield(char **, char **);
-static void out_of_mem(void);
+static void out_of_mem(void) __dead2;
static void parsecred(char *, struct expcred *);
static int parsesec(char *, struct exportlist *);
static int put_exlist(struct dirlist *, XDR *, struct dirlist *,
@@ -302,6 +303,11 @@
static int has_set_publicfh = 0;
static struct pidfh *pfh = NULL;
+
+/* Temporary storage for credentials' groups. */
+static long ngroups_max;
+static gid_t *tmp_groups = NULL;
+
/* Bits for opt_flags above */
#define OP_MAPROOT 0x01
#define OP_MAPALL 0x02
@@ -434,6 +440,18 @@
warn("cannot open or create pidfile");
}
+ openlog("mountd", LOG_PID, LOG_DAEMON);
+
+ /* How many groups do we support? */
+ ngroups_max = sysconf(_SC_NGROUPS_MAX);
+ if (ngroups_max == -1)
+ ngroups_max = NGROUPS_MAX;
+ /* Add space for the effective GID. */
+ ++ngroups_max;
+ tmp_groups = malloc(ngroups_max);
+ if (tmp_groups == NULL)
+ out_of_mem();
+
s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (s < 0)
have_v6 = 0;
@@ -539,7 +557,6 @@
exnames = argv;
else
exnames = exnames_default;
- openlog("mountd", LOG_PID, LOG_DAEMON);
if (debug)
warnx("getting export list");
get_exportlist(0);
@@ -1571,9 +1588,9 @@
int unvis_len;
v4root_phase = 0;
- anon.cr_groups = NULL;
dirhead = (struct dirlist *)NULL;
unvis_dir[0] = '\0';
+
while (get_line()) {
if (debug)
warnx("got line %s", line);
@@ -1586,9 +1603,9 @@
* Set defaults.
*/
has_host = FALSE;
- anon.cr_groups = anon.cr_smallgrps;
anon.cr_uid = UID_NOBODY;
anon.cr_ngroups = 1;
+ anon.cr_groups = tmp_groups;
anon.cr_groups[0] = nogroup();
exflags = MNT_EXPORTED;
got_nondir = 0;
@@ -1918,10 +1935,6 @@
free_dir(dirhead);
dirhead = (struct dirlist *)NULL;
}
- if (anon.cr_groups != anon.cr_smallgrps) {
- free(anon.cr_groups);
- anon.cr_groups = NULL;
- }
}
}
@@ -3187,11 +3200,11 @@
eap->ex_flags = exflags;
eap->ex_uid = anoncrp->cr_uid;
eap->ex_ngroups = anoncrp->cr_ngroups;
- if (eap->ex_ngroups > 0) {
- eap->ex_groups = malloc(eap->ex_ngroups * sizeof(gid_t));
- memcpy(eap->ex_groups, anoncrp->cr_groups, eap->ex_ngroups *
- sizeof(gid_t));
- }
+ /*
+ * Use the memory pointed to by 'anoncrp', as it outlives 'eap' which is
+ * local to this function.
+ */
+ eap->ex_groups = anoncrp->cr_groups;
LOGDEBUG("do_mount exflags=0x%jx", (uintmax_t)exflags);
eap->ex_indexfile = ep->ex_indexfile;
if (grp->gr_type == GT_HOST)
@@ -3381,7 +3394,6 @@
if (cp)
*cp = savedc;
error_exit:
- free(eap->ex_groups);
/* free strings allocated by strdup() in getmntopts.c */
if (iov != NULL) {
free(iov[0].iov_base); /* fstype */
@@ -3609,23 +3621,18 @@
* Parse a description of a credential.
*/
static void
-parsecred(char *namelist, struct expcred *cr)
+parsecred(char *names, struct expcred *cr)
{
char *name;
- char *names;
struct passwd *pw;
- struct group *gr;
- gid_t groups[NGROUPS_MAX + 1];
- int ngroups;
unsigned long name_ul;
char *end = NULL;
- /* Start with 'cr_smallgrps' embedded storage. */
- cr->cr_groups = cr->cr_smallgrps;
+ assert(cr->cr_groups == tmp_groups);
+
/*
* Get the user's password table entry.
*/
- names = namelist;
name = strsep_quote(&names, ":");
name_ul = strtoul(name, &end, 10);
if (*end != '\0' || end == name)
@@ -3650,16 +3657,12 @@
goto fallback;
}
- ngroups = NGROUPS_MAX + 1;
- if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups)) {
+ cr->cr_ngroups = ngroups_max;
+ if (getgrouplist(pw->pw_name, pw->pw_gid,
+ cr->cr_groups, &cr->cr_ngroups) != 0) {
syslog(LOG_ERR, "too many groups");
- ngroups = NGROUPS_MAX + 1;
+ cr->cr_ngroups = ngroups_max;
}
-
- if (ngroups > SMALLNGROUPS)
- cr->cr_groups = malloc(ngroups * sizeof(gid_t));
- cr->cr_ngroups = ngroups;
- memcpy(cr->cr_groups, groups, ngroups * sizeof(gid_t));
return;
}
@@ -3669,6 +3672,7 @@
*/
cr->cr_ngroups = 0;
while (names != NULL && *names != '\0') {
+ const struct group *gr;
gid_t group;
name = strsep_quote(&names, ":");
@@ -3682,19 +3686,17 @@
} else {
group = name_ul;
}
- if (cr->cr_ngroups == NGROUPS_MAX) {
+ ++cr->cr_ngroups;
+ if (cr->cr_ngroups > ngroups_max) {
syslog(LOG_ERR, "too many groups");
break;
}
- groups[cr->cr_ngroups++] = group;
+ cr->cr_groups[cr->cr_ngroups - 1] = group;
}
if (cr->cr_ngroups == 0) {
cr->cr_ngroups = 1;
cr->cr_groups[0] = nogroup();
}
- if (cr->cr_ngroups > SMALLNGROUPS)
- cr->cr_groups = malloc(cr->cr_ngroups * sizeof(gid_t));
- memcpy(cr->cr_groups, groups, cr->cr_ngroups * sizeof(gid_t));
return;
fallback:
@@ -3702,8 +3704,8 @@
* Set up the unprivileged user.
*/
cr->cr_uid = UID_NOBODY;
- cr->cr_groups[0] = nogroup();
cr->cr_ngroups = 1;
+ cr->cr_groups[0] = nogroup();
}
#define STRSIZ (MNTNAMLEN+MNTPATHLEN+50)
@@ -4067,6 +4069,7 @@
static void
terminate(int sig __unused)
{
+ free(tmp_groups);
pidfile_remove(pfh);
rpcb_unset(MOUNTPROG, MOUNTVERS, NULL);
rpcb_unset(MOUNTPROG, MOUNTVERS3, NULL);

File Metadata

Mime Type
text/plain
Expires
Mon, Jan 13, 7:43 PM (18 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15786389
Default Alt Text
D47016.id144828.diff (5 KB)

Event Timeline