Skip to content

Commit 405070d

Browse files
committed
Add sudo_login_name_max() and sudo_host_name_max()
These convenience functions cache the value and handle any potenial errors from sysconf().
1 parent 7c075c1 commit 405070d

8 files changed

Lines changed: 107 additions & 50 deletions

File tree

include/sudo_util.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* SPDX-License-Identifier: ISC
33
*
4-
* Copyright (c) 2013-2023 Todd C. Miller <[email protected]>
4+
* Copyright (c) 2013-2025 Todd C. Miller <[email protected]>
55
*
66
* Permission to use, copy, modify, and distribute this software for any
77
* purpose with or without fee is hereby granted, provided that the above
@@ -185,6 +185,8 @@ sudo_dso_public char *sudo_basename_v1(const char *filename);
185185
/* gethostname.c */
186186
sudo_dso_public char *sudo_gethostname_v1(void);
187187
#define sudo_gethostname() sudo_gethostname_v1()
188+
sudo_dso_public size_t sudo_host_name_max_v1(void);
189+
#define sudo_host_name_max() sudo_host_name_max_v1()
188190

189191
/* gettime.c */
190192
sudo_dso_public int sudo_gettime_awake_v1(struct timespec *ts);
@@ -225,6 +227,10 @@ sudo_dso_public bool sudo_str2logfac_v1(const char *str, int *logfac);
225227
sudo_dso_public const char *sudo_logfac2str_v1(int num);
226228
#define sudo_logfac2str(_a) sudo_logfac2str_v1((_a))
227229

230+
/* login_max.c */
231+
sudo_dso_public size_t sudo_login_name_max_v1(void);
232+
#define sudo_login_name_max() sudo_login_name_max_v1()
233+
228234
/* logpri.c */
229235
sudo_dso_public bool sudo_str2logpri_v1(const char *str, int *logpri);
230236
#define sudo_str2logpri(_a, _b) sudo_str2logpri_v1((_a), (_b))

lib/util/Makefile.in

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#
22
# SPDX-License-Identifier: ISC
33
#
4-
# Copyright (c) 2011-2024 Todd C. Miller <[email protected]>
4+
# Copyright (c) 2011-2025 Todd C. Miller <[email protected]>
55
#
66
# Permission to use, copy, modify, and distribute this software for any
77
# purpose with or without fee is hereby granted, provided that the above
@@ -147,11 +147,11 @@ SHELL = @SHELL@
147147

148148
LTOBJS = basename.lo @DIGEST@ event.lo fatal.lo key_val.lo gethostname.lo \
149149
gettime.lo getgrouplist.lo gidlist.lo hexchar.lo json.lo lbuf.lo \
150-
locking.lo logfac.lo logpri.lo mkdir_parents.lo mmap_alloc.lo \
151-
multiarch.lo parseln.lo progname.lo rcstr.lo regex.lo roundup.lo \
152-
secure_path.lo setgroups.lo strsplit.lo strtobool.lo strtoid.lo \
153-
strtomode.lo strtonum.lo sudo_conf.lo sudo_debug.lo sudo_dso.lo \
154-
term.lo ttyname_dev.lo ttysize.lo uuid.lo \
150+
locking.lo logfac.lo login_max.lo logpri.lo mkdir_parents.lo \
151+
mmap_alloc.lo multiarch.lo parseln.lo progname.lo rcstr.lo regex.lo \
152+
roundup.lo secure_path.lo setgroups.lo strsplit.lo strtobool.lo \
153+
strtoid.lo strtomode.lo strtonum.lo sudo_conf.lo sudo_debug.lo \
154+
sudo_dso.lo term.lo ttyname_dev.lo ttysize.lo uuid.lo \
155155
@COMMON_OBJS@ @LTLIBOBJS@
156156

157157
IOBJS = $(LTOBJS:.lo=.i)
@@ -1102,6 +1102,16 @@ logfac.i: $(srcdir)/logfac.c $(incdir)/compat/stdbool.h \
11021102
$(CPP) $(CPPFLAGS) $(srcdir)/logfac.c > $@
11031103
logfac.plog: logfac.i
11041104
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/logfac.c --i-file logfac.i --output-file $@
1105+
login_max.lo: $(srcdir)/login_max.c $(incdir)/compat/stdbool.h \
1106+
$(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
1107+
$(top_builddir)/config.h
1108+
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/login_max.c
1109+
login_max.i: $(srcdir)/login_max.c $(incdir)/compat/stdbool.h \
1110+
$(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
1111+
$(top_builddir)/config.h
1112+
$(CPP) $(CPPFLAGS) $(srcdir)/login_max.c > $@
1113+
login_max.plog: login_max.i
1114+
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/login_max.c --i-file login_max.i --output-file $@
11051115
logpri.lo: $(srcdir)/logpri.c $(incdir)/compat/stdbool.h \
11061116
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
11071117
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(top_builddir)/config.h

lib/util/gethostname.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* SPDX-License-Identifier: ISC
33
*
4-
* Copyright (c) 2015 Todd C. Miller <[email protected]>
4+
* Copyright (c) 2015, 2025 Todd C. Miller <[email protected]>
55
*
66
* Permission to use, copy, modify, and distribute this software for any
77
* purpose with or without fee is hereby granted, provided that the above
@@ -36,16 +36,8 @@
3636
char *
3737
sudo_gethostname_v1(void)
3838
{
39-
char *hname;
40-
size_t host_name_max;
41-
42-
#ifdef _SC_HOST_NAME_MAX
43-
host_name_max = (size_t)sysconf(_SC_HOST_NAME_MAX);
44-
if ((ssize_t)host_name_max <= 0)
45-
#endif
46-
host_name_max = 255; /* POSIX and historic BSD */
47-
48-
hname = malloc(host_name_max + 1);
39+
const size_t host_name_max = sudo_host_name_max();
40+
char *hname = malloc(host_name_max + 1);
4941
if (hname != NULL) {
5042
if (gethostname(hname, host_name_max + 1) == 0 && *hname != '\0') {
5143
/* Old gethostname() may not NUL-terminate if there is no room. */
@@ -57,3 +49,22 @@ sudo_gethostname_v1(void)
5749
}
5850
return hname;
5951
}
52+
53+
size_t
54+
sudo_host_name_max_v1(void)
55+
{
56+
static size_t maxval;
57+
58+
if (maxval == 0) {
59+
long lval;
60+
61+
#ifdef _SC_HOST_NAME_MAX
62+
lval = sysconf(_SC_HOST_NAME_MAX);
63+
if (lval <= 0)
64+
#endif
65+
lval = 255; /* POSIX and historic BSD */
66+
maxval = (size_t)lval;
67+
}
68+
69+
return maxval;
70+
}

lib/util/login_max.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* SPDX-License-Identifier: ISC
3+
*
4+
* Copyright (c) 2025 Todd C. Miller <[email protected]>
5+
*
6+
* Permission to use, copy, modify, and distribute this software for any
7+
* purpose with or without fee is hereby granted, provided that the above
8+
* copyright notice and this permission notice appear in all copies.
9+
*
10+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17+
*/
18+
19+
/*
20+
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
21+
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
22+
*/
23+
24+
#include <config.h>
25+
26+
#include <stdlib.h>
27+
#include <unistd.h>
28+
#include <limits.h>
29+
30+
#include <sudo_compat.h>
31+
#include <sudo_util.h>
32+
33+
size_t
34+
sudo_login_name_max_v1(void)
35+
{
36+
static size_t maxval;
37+
38+
if (maxval == 0) {
39+
long lval;
40+
41+
#ifdef _SC_LOGIN_NAME_MAX
42+
lval = sysconf(_SC_LOGIN_NAME_MAX);
43+
if (lval < 0)
44+
#endif
45+
lval = LOGIN_NAME_MAX;
46+
maxval = (size_t)lval;
47+
}
48+
49+
return maxval;
50+
}

lib/util/util.exp.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ sudo_gettime_awake_v1
9696
sudo_gettime_mono_v1
9797
sudo_gettime_real_v1
9898
sudo_hexchar_v1
99+
sudo_host_name_max_v1
99100
sudo_isatty_v1
100101
sudo_json_add_value_as_object_v1
101102
sudo_json_add_value_v1
@@ -119,6 +120,7 @@ sudo_lbuf_print_v1
119120
sudo_lock_file_v1
120121
sudo_lock_region_v1
121122
sudo_logfac2str_v1
123+
sudo_login_name_max_v1
122124
sudo_logpri2str_v1
123125
sudo_mkdir_parents_v1
124126
sudo_mmap_alloc_v1

plugins/sudoers/cvtsudoers_pwutil.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* SPDX-License-Identifier: ISC
33
*
4-
* Copyright (c) 1996, 1998-2005, 2007-2019
4+
* Copyright (c) 1996, 1998-2005, 2007-2020, 2022-2025
55
* Todd C. Miller <[email protected]>
66
*
77
* Permission to use, copy, modify, and distribute this software for any
@@ -403,7 +403,7 @@ cvtsudoers_make_grlist_item(const struct passwd *pw, char * const *unused1)
403403
struct cache_item_grlist *grlitem;
404404
struct sudoers_string *s;
405405
struct group_list *grlist;
406-
long groupname_len;
406+
const size_t groupname_len = sudo_login_name_max();
407407
debug_decl(cvtsudoers_make_grlist_item, SUDOERS_DEBUG_NSS);
408408

409409
/*
@@ -420,18 +420,10 @@ cvtsudoers_make_grlist_item(const struct passwd *pw, char * const *unused1)
420420
ngroups++;
421421
}
422422

423-
#ifdef _SC_LOGIN_NAME_MAX
424-
groupname_len = sysconf(_SC_LOGIN_NAME_MAX);
425-
if (groupname_len < 32)
426-
groupname_len = 32;
427-
#else
428-
groupname_len = MAX(LOGIN_NAME_MAX, 32);
429-
#endif
430-
431423
/* Allocate in one big chunk for easy freeing. */
432424
nsize = strlen(pw->pw_name) + 1;
433425
total = sizeof(*grlitem) + nsize;
434-
total += (size_t)groupname_len * ngroups;
426+
total += groupname_len * ngroups;
435427

436428
again:
437429
if ((grlitem = calloc(1, total)) == NULL) {
@@ -472,7 +464,7 @@ cvtsudoers_make_grlist_item(const struct passwd *pw, char * const *unused1)
472464
}
473465
len = strlen(s->str) + 1;
474466
if ((size_t)(cp - (char *)grlitem) + len > total) {
475-
total += len + (size_t)groupname_len;
467+
total += len + groupname_len;
476468
free(grlitem);
477469
goto again;
478470
}

plugins/sudoers/match.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* SPDX-License-Identifier: ISC
33
*
4-
* Copyright (c) 1996, 1998-2005, 2007-2023
4+
* Copyright (c) 1996, 1998-2005, 2007-2023, 2025
55
* Todd C. Miller <[email protected]>
66
*
77
* Permission to use, copy, modify, and distribute this software for any
@@ -703,15 +703,9 @@ sudo_getdomainname(void)
703703
debug_decl(sudo_getdomainname, SUDOERS_DEBUG_MATCH);
704704

705705
if (!initialized) {
706-
size_t host_name_max;
706+
const size_t host_name_max = sudo_host_name_max();
707707
int rc;
708708

709-
# ifdef _SC_HOST_NAME_MAX
710-
host_name_max = (size_t)sysconf(_SC_HOST_NAME_MAX);
711-
if (host_name_max == (size_t)-1)
712-
# endif
713-
host_name_max = 255; /* POSIX and historic BSD */
714-
715709
domain = malloc(host_name_max + 1);
716710
if (domain != NULL) {
717711
domain[0] = '\0';

plugins/sudoers/pwutil_impl.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* SPDX-License-Identifier: ISC
33
*
4-
* Copyright (c) 1996, 1998-2005, 2007-2018
4+
* Copyright (c) 1996, 1998-2005, 2007-2021, 2023-2025
55
* Todd C. Miller <[email protected]>
66
*
77
* Permission to use, copy, modify, and distribute this software for any
@@ -363,12 +363,12 @@ PREFIX(make_gidlist_item)(const struct passwd *pw, int ngids, GETGROUPS_T *gids,
363363
struct cache_item *
364364
PREFIX(make_grlist_item)(const struct passwd *pw, char * const *unused1)
365365
{
366+
const size_t groupname_len = sudo_login_name_max();
366367
size_t len, ngroups, nsize, total;
367368
struct cache_item_grlist *grlitem;
368369
struct group_list *grlist;
369370
struct gid_list *gidlist;
370371
struct group *grp = NULL;
371-
long groupname_len;
372372
char *cp;
373373
int i;
374374
debug_decl(sudo_make_grlist_item, SUDOERS_DEBUG_NSS);
@@ -381,19 +381,11 @@ PREFIX(make_grlist_item)(const struct passwd *pw, char * const *unused1)
381381
debug_return_ptr(NULL);
382382
}
383383

384-
#ifdef _SC_LOGIN_NAME_MAX
385-
groupname_len = sysconf(_SC_LOGIN_NAME_MAX);
386-
if (groupname_len < 32)
387-
groupname_len = 32;
388-
#else
389-
groupname_len = MAX(LOGIN_NAME_MAX, 32);
390-
#endif
391-
392384
/* Allocate in one big chunk for easy freeing. */
393385
nsize = strlen(pw->pw_name) + 1;
394386
total = sizeof(*grlitem) + nsize;
395387
total += sizeof(char *) * (size_t)gidlist->ngids;
396-
total += (size_t)(groupname_len * gidlist->ngids);
388+
total += groupname_len * (size_t)gidlist->ngids;
397389

398390
again:
399391
if ((grlitem = calloc(1, total)) == NULL) {
@@ -432,7 +424,7 @@ PREFIX(make_grlist_item)(const struct passwd *pw, char * const *unused1)
432424
if ((grp = sudo_getgrgid(gidlist->gids[i])) != NULL) {
433425
len = strlen(grp->gr_name) + 1;
434426
if ((size_t)(cp - (char *)grlitem) + len > total) {
435-
total += len + (size_t)groupname_len;
427+
total += len + groupname_len;
436428
free(grlitem);
437429
sudo_gr_delref(grp);
438430
goto again;

0 commit comments

Comments
 (0)