Skip to content

Commit 282bf16

Browse files
lib/shadow/: Add re-entrant function
Signed-off-by: Alejandro Colomar <[email protected]>
1 parent a17bf41 commit 282bf16

File tree

9 files changed

+163
-38
lines changed

9 files changed

+163
-38
lines changed

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ AC_CHECK_MEMBERS([struct utmpx.ut_name,
6363
dnl Checks for library functions.
6464
AC_FUNC_UTIME_NULL
6565
AC_REPLACE_FUNCS([putgrent putpwent putspent])
66-
AC_REPLACE_FUNCS([sgetgrent sgetpwent sgetspent])
66+
AC_REPLACE_FUNCS([sgetgrent sgetpwent sgetspent sgetspent_r])
6767

6868
AC_CHECK_FUNC([setpgrp])
6969
AC_CHECK_FUNC([secure_getenv],

lib/shadow/group/sgetgrent.c

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
// SPDX-FileCopyrightText: 1996-1998, Marek Michałkiewicz
33
// SPDX-FileCopyrightText: 2005, Tomasz Kłoczko
44
// SPDX-FileCopyrightText: 2008, Nicolas François
5-
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <[email protected]>
5+
// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <[email protected]>
66
// SPDX-License-Identifier: BSD-3-Clause
77

88

99
#include "config.h"
1010

1111
#include "shadow/group/sgetgrent.h"
1212

13+
#include <errno.h>
1314
#include <grp.h>
1415
#include <stddef.h>
1516
#include <stdio.h>
@@ -33,7 +34,7 @@ sgetgrent(const char *s)
3334
static char *buf = NULL;
3435
static struct group *grent = NULL;
3536

36-
char *fields[4];
37+
int e;
3738
char *p, *end;
3839
size_t n, lssize, size;
3940

@@ -51,24 +52,54 @@ sgetgrent(const char *s)
5152
if (grent == NULL)
5253
return NULL;
5354

55+
e = sgetgrent_r(s, grent, buf, size);
56+
if (e != 0) {
57+
errno = e;
58+
return NULL;
59+
}
60+
61+
return grent;
62+
}
63+
64+
65+
// from-string get group entry re-entrant
66+
int
67+
sgetgrent_r(size_t size;
68+
const char *restrict s, struct group *restrict grent,
69+
char buf[restrict size], size_t size)
70+
{
71+
char *p, *end;
72+
char *fields[4];
73+
size_t n, lssize;
74+
75+
if (!is_aligned(buf, char *))
76+
return EINVAL;
77+
78+
// The first 'lssize' bytes of 'buf' are used for 'grent->gr_mem'.
79+
n = strchrcnt(s, ',') + 2;
80+
lssize = n * sizeof(char *);
81+
if (lssize >= size)
82+
return E2BIG;
83+
84+
// The remaining bytes of 'buf' are used for a copy of 's'.
5485
end = buf + size;
5586
p = buf + lssize;
5687
if (stpecpy(p, end, s) == NULL)
57-
return NULL;
88+
return errno;
5889

5990
stpsep(p, "\n");
6091

6192
if (STRSEP2ARR(p, ":", fields) == -1)
62-
return NULL;
93+
return EINVAL;
6394

6495
grent->gr_name = fields[0];
6596
grent->gr_passwd = fields[1];
6697
if (get_gid(fields[2], &grent->gr_gid) == -1)
67-
return NULL;
98+
return errno;
6899

69100
grent->gr_mem = (char **) buf;
70101
if (csv2ls(fields[3], n, grent->gr_mem) == -1)
71-
return NULL;
102+
return errno;
72103

73-
return &grent;
104+
return 0;
74105
}

lib/shadow/group/sgetgrent.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <[email protected]>
1+
// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <[email protected]>
22
// SPDX-License-Identifier: BSD-3-Clause
33

44

@@ -9,9 +9,13 @@
99
#include "config.h"
1010

1111
#include <grp.h>
12+
#include <stddef.h>
1213

1314

1415
struct group *sgetgrent(const char *s);
16+
int sgetgrent_r(size_t size;
17+
const char *restrict s, struct group *restrict grent,
18+
char buf[restrict size], size_t size);
1519

1620

1721
#endif // include guard

lib/shadow/gshadow/sgetsgent.c

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "shadow/gshadow/sgetsgent.h"
1212

13+
#include <errno.h>
1314
#include <stddef.h>
1415
#include <string.h>
1516

@@ -34,7 +35,7 @@ sgetsgent(const char *s)
3435
static char *buf = NULL;
3536
static struct sgrp *sgent = NULL;
3637

37-
char *fields[4];
38+
int e;
3839
char *p, *end;
3940
size_t n, nadm, nmem, lssize, size;
4041

@@ -52,33 +53,62 @@ sgetsgent(const char *s)
5253
if (sgent == NULL)
5354
return NULL;
5455

56+
e = sgetsgent_r(s, sgent, buf, size);
57+
if (e != 0) {
58+
errno = e;
59+
return NULL;
60+
}
61+
62+
return sgent;
63+
}
64+
65+
66+
// from-string get shadow group entry re-entrant
67+
int
68+
sgetsgent_r(size_t size;
69+
const char *s, struct sgrp *sgent, char buf[size], size_t size,
70+
struct sgrp **dummy)
71+
{
72+
char *fields[4];
73+
char *p, *end;
74+
size_t n, nadm, nmem, lssize, size;
75+
76+
// The first 'lssize' bytes of 'buf' are used for 'sg_adm' and 'sg_mem'.
77+
n = strchrcnt(s, ',') + 4;
78+
lssize = n * sizeof(char *);
79+
if (lssize >= size)
80+
return E2BIG;
81+
82+
// The remaining bytes of 'buf' are used for a copy of 's'.
5583
end = buf + size;
5684
p = buf + lssize;
5785
if (stpecpy(p, end, s) == NULL)
58-
return NULL;
86+
return errno;
5987

6088
stpsep(p, "\n");
6189

6290
if (STRSEP2ARR(p, ":", fields) == -1)
63-
return NULL;
91+
return EINVAL;
6492

6593
sgent->sg_namp = fields[0];
6694
sgent->sg_passwd = fields[1];
6795

96+
if (!is_aligned(buf, char *))
97+
return EINVAL;
6898
sgent->sg_adm = (char **) buf;
6999
nadm = strchrcnt(fields[2], ',') + 2;
70100
if (nadm > n)
71-
return NULL;
101+
return E2BIG;
72102
if (csv2ls(fields[2], nadm, sgent->sg_adm) == -1)
73-
return NULL;
103+
return errno;
74104

75105
sgent->sg_mem = sgent->sg_adm + nadm;
76106
nmem = strchrcnt(fields[3], ',') + 2;
77107
if (nmem + nadm > n)
78-
return NULL;
108+
return E2BIG;
79109
if (csv2ls(fields[3], nmem, sgent->sg_mem) == -1)
80-
return NULL;
110+
return errno;
81111

82-
return sgent;
112+
return 0;
83113
}
84114
#endif

lib/shadow/gshadow/sgetsgent.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,16 @@
1313

1414
#include "shadow/gshadow/sgrp.h"
1515

16+
#include <stddef.h>
17+
1618

1719
#if __has_include(<gshadow.h>)
1820
# include <gshadow.h>
1921
#else
2022
struct sgrp *sgetsgent(const char *);
23+
int sgetsgent_r(size_t size;
24+
const char *s, struct sgrp *sgent, char buf[size], size_t size,
25+
struct sgrp **dummy);
2126
#endif
2227

2328

lib/shadow/passwd/sgetpwent.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// SPDX-FileCopyrightText: 1996-1998, Marek Michałkiewicz
33
// SPDX-FileCopyrightText: 2003-2005, Tomasz Kłoczko
44
// SPDX-FileCopyrightText: 2008, Nicolas François
5-
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <[email protected]>
5+
// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <[email protected]>
66
// SPDX-License-Identifier: BSD-3-Clause
77

88

@@ -35,7 +35,7 @@ sgetpwent(const char *s)
3535
static char *buf = NULL;
3636
static struct passwd *pwent = NULL;
3737

38-
char *fields[7];
38+
int e;
3939
size_t size;
4040

4141
size = strlen(s) + 1;
@@ -50,23 +50,41 @@ sgetpwent(const char *s)
5050
if (pwent == NULL)
5151
return NULL;
5252

53-
if (strtcpy(buf, s, size) == -1)
53+
e = sgetpwent_r(s, pwent, buf, size);
54+
if (e != 0)
55+
errno = e;
5456
return NULL;
57+
}
58+
59+
return pwent;
60+
}
61+
62+
63+
// from-string get pasword entry re-entrant
64+
int
65+
sgetpwent_r(size_t size;
66+
const char *restrict s, struct passwd *restrict pwent,
67+
char buf[restrict size], size_t size)
68+
{
69+
char *fields[7];
70+
71+
if (strtcpy(buf, s, size) == -1)
72+
return errno;
5573

5674
stpsep(buf, "\n");
5775

5876
if (STRSEP2ARR(buf, ":", fields) == -1)
59-
return NULL;
77+
return EINVAL;
6078

6179
pwent->pw_name = fields[0];
6280
pwent->pw_passwd = fields[1];
6381
if (get_uid(fields[2], &pwent->pw_uid) == -1)
64-
return NULL;
82+
return errno;
6583
if (get_gid(fields[3], &pwent->pw_gid) == -1)
66-
return NULL;
84+
return errno;
6785
pwent->pw_gecos = fields[4];
6886
pwent->pw_dir = fields[5];
6987
pwent->pw_shell = fields[6];
7088

71-
return pwent;
89+
return 0;
7290
}

lib/shadow/passwd/sgetpwent.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <[email protected]>
1+
// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <[email protected]>
22
// SPDX-License-Identifier: BSD-3-Clause
33

44

@@ -9,9 +9,13 @@
99
#include "config.h"
1010

1111
#include <pwd.h>
12+
#include <stddef.h>
1213

1314

1415
struct passwd *sgetpwent(const char *s);
16+
int sgetpwent_r(size_t size;
17+
const char *restrict s, struct passwd *restrict pwent,
18+
char buf[restrict size], size_t size);
1519

1620

1721
#endif // include guard

0 commit comments

Comments
 (0)