Skip to content

Commit f5e5999

Browse files
lib/shadow/: Add re-entrant functions
Signed-off-by: Alejandro Colomar <[email protected]>
1 parent 71067b5 commit f5e5999

File tree

11 files changed

+200
-48
lines changed

11 files changed

+200
-48
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 & 8 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>
@@ -24,6 +25,7 @@
2425
#include "string/strcpy/stpecpy.h"
2526
#include "string/strtok/stpsep.h"
2627
#include "string/strtok/strsep2arr.h"
28+
#include "typetraits.h"
2729

2830

2931
// from-string get group entry
@@ -34,8 +36,7 @@ sgetgrent(const char *s)
3436
static struct group grent_ = {};
3537
struct group *grent = &grent_;
3638

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

4142
n = strchrcnt(s, ',') + 2;
@@ -47,24 +48,53 @@ sgetgrent(const char *s)
4748
if (buf == NULL)
4849
return NULL;
4950

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

5583
stpsep(p, "\n");
5684

5785
if (STRSEP2ARR(p, ":", fields) == -1)
58-
return NULL;
86+
return EINVAL;
5987

6088
grent->gr_name = fields[0];
6189
grent->gr_passwd = fields[1];
6290
if (get_gid(fields[2], &grent->gr_gid) == -1)
63-
return NULL;
91+
return errno;
6492

93+
if (!is_aligned(buf, char *))
94+
return EINVAL;
6595
grent->gr_mem = (char **) buf;
6696
if (csv2ls(fields[3], n, grent->gr_mem) == -1)
67-
return NULL;
97+
return errno;
6898

69-
return grent;
99+
return 0;
70100
}

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: 45 additions & 10 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 <stdlib.h>
1516
#include <string.h>
@@ -22,6 +23,7 @@
2223
#include "string/strcpy/stpecpy.h"
2324
#include "string/strtok/stpsep.h"
2425
#include "string/strtok/strsep2arr.h"
26+
#include "typetraits.h"
2527

2628

2729
#define FIELDS 4
@@ -36,9 +38,9 @@ sgetsgent(const char *s)
3638
static struct sgrp sgent_ = {};
3739
struct sgrp *sgent = &sgent_;
3840

39-
char *fields[4];
40-
char *p, *end;
41-
size_t n, nadm, nmem, lssize, size;
41+
int e;
42+
size_t n, lssize, size;
43+
struct sgrp *dummy;
4244

4345
n = strchrcnt(s, ',') + 4;
4446
lssize = n * sizeof(char *); // For 'sgent->sg_adm' and 'sgent->sg_mem'
@@ -49,33 +51,66 @@ sgetsgent(const char *s)
4951
if (buf == NULL)
5052
return NULL;
5153

54+
e = sgetsgent_r(s, sgent, buf, size, &dummy);
55+
if (e != 0) {
56+
errno = e;
57+
return NULL;
58+
}
59+
60+
return sgent;
61+
}
62+
63+
64+
// from-string get shadow group entry re-entrant
65+
int
66+
sgetsgent_r(size_t size;
67+
const char *s, struct sgrp *sgent, char buf[size], size_t size,
68+
struct sgrp **dummy)
69+
{
70+
char *fields[4];
71+
char *p, *end;
72+
size_t n, nadm, nmem, lssize;
73+
74+
// 'dummy' exists only for historic reasons.
75+
if (dummy != NULL)
76+
*dummy = sgent;
77+
78+
// The first 'lssize' bytes of 'buf' are used for 'sg_adm' and 'sg_mem'.
79+
n = strchrcnt(s, ',') + 4;
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'.
5285
end = buf + size;
5386
p = buf + lssize;
5487
if (stpecpy(p, end, s) == NULL)
55-
return NULL;
88+
return errno;
5689

5790
stpsep(p, "\n");
5891

5992
if (STRSEP2ARR(p, ":", fields) == -1)
60-
return NULL;
93+
return EINVAL;
6194

6295
sgent->sg_namp = fields[0];
6396
sgent->sg_passwd = fields[1];
6497

98+
if (!is_aligned(buf, char *))
99+
return EINVAL;
65100
sgent->sg_adm = (char **) buf;
66101
nadm = strchrcnt(fields[2], ',') + 2;
67102
if (nadm > n)
68-
return NULL;
103+
return E2BIG;
69104
if (csv2ls(fields[2], nadm, sgent->sg_adm) == -1)
70-
return NULL;
105+
return errno;
71106

72107
sgent->sg_mem = sgent->sg_adm + nadm;
73108
nmem = strchrcnt(fields[3], ',') + 2;
74109
if (nmem + nadm > n)
75-
return NULL;
110+
return E2BIG;
76111
if (csv2ls(fields[3], nmem, sgent->sg_mem) == -1)
77-
return NULL;
112+
return errno;
78113

79-
return sgent;
114+
return 0;
80115
}
81116
#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

@@ -36,7 +36,7 @@ sgetpwent(const char *s)
3636
static struct passwd pwent_ = {};
3737
struct passswd *pwent = &pwent_;
3838

39-
char *fields[7];
39+
int e;
4040
size_t size;
4141

4242
size = strlen(s) + 1;
@@ -46,23 +46,41 @@ sgetpwent(const char *s)
4646
if (buf == NULL)
4747
return NULL;
4848

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

5270
stpsep(buf, "\n");
5371

5472
if (STRSEP2ARR(buf, ":", fields) == -1)
55-
return NULL;
73+
return EINVAL;
5674

5775
pwent->pw_name = fields[0];
5876
pwent->pw_passwd = fields[1];
5977
if (get_uid(fields[2], &pwent->pw_uid) == -1)
60-
return NULL;
78+
return errno;
6179
if (get_gid(fields[3], &pwent->pw_gid) == -1)
62-
return NULL;
80+
return errno;
6381
pwent->pw_gecos = fields[4];
6482
pwent->pw_dir = fields[5];
6583
pwent->pw_shell = fields[6];
6684

67-
return pwent;
85+
return 0;
6886
}

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)