Skip to content

Commit 80f7484

Browse files
Bryan C. Millsgopherbot
Bryan C. Mills
authored andcommitted
os/user: zero-initialize C structs returned to Go
In the wrappers for getgrnam_r and similar, the structs to be returned are allocated on the C stack and may be uninitialized. If the call to the wrapped C function returns an error (such as ERANGE), it may leave the struct uninitialized, expecting that the caller will not read it. However, when that struct is returned to Go, it may be read by the Go garbage collector. If the uninitialized struct fields happen to contain wild pointers, the Go garbage collector will throw an error. (Prior to CL 449335, the Go runtime would not scan the struct fields because they did not reside in Go memory.) Fix this by always zeroing the struct before the C call. Fixes #57170. Change-Id: I241ae8e4added6f9a406dac37a7f6452341aa0cf Reviewed-on: https://go-review.googlesource.com/c/go/+/456121 TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Run-TryBot: Bryan Mills <[email protected]> Auto-Submit: Bryan Mills <[email protected]>
1 parent e738a2f commit 80f7484

File tree

1 file changed

+21
-16
lines changed

1 file changed

+21
-16
lines changed

src/os/user/cgo_lookup_cgo.go

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,37 +17,42 @@ import (
1717
#include <pwd.h>
1818
#include <grp.h>
1919
#include <stdlib.h>
20+
#include <string.h>
2021
2122
static struct passwd mygetpwuid_r(int uid, char *buf, size_t buflen, int *found, int *perr) {
2223
struct passwd pwd;
23-
struct passwd *result;
24-
*perr = getpwuid_r(uid, &pwd, buf, buflen, &result);
25-
*found = result != NULL;
26-
return pwd;
24+
struct passwd *result;
25+
memset (&pwd, 0, sizeof(pwd));
26+
*perr = getpwuid_r(uid, &pwd, buf, buflen, &result);
27+
*found = result != NULL;
28+
return pwd;
2729
}
2830
2931
static struct passwd mygetpwnam_r(const char *name, char *buf, size_t buflen, int *found, int *perr) {
3032
struct passwd pwd;
31-
struct passwd *result;
32-
*perr = getpwnam_r(name, &pwd, buf, buflen, &result);
33-
*found = result != NULL;
34-
return pwd;
33+
struct passwd *result;
34+
memset(&pwd, 0, sizeof(pwd));
35+
*perr = getpwnam_r(name, &pwd, buf, buflen, &result);
36+
*found = result != NULL;
37+
return pwd;
3538
}
3639
3740
static struct group mygetgrgid_r(int gid, char *buf, size_t buflen, int *found, int *perr) {
3841
struct group grp;
39-
struct group *result;
40-
*perr = getgrgid_r(gid, &grp, buf, buflen, &result);
41-
*found = result != NULL;
42-
return grp;
42+
struct group *result;
43+
memset(&grp, 0, sizeof(grp));
44+
*perr = getgrgid_r(gid, &grp, buf, buflen, &result);
45+
*found = result != NULL;
46+
return grp;
4347
}
4448
4549
static struct group mygetgrnam_r(const char *name, char *buf, size_t buflen, int *found, int *perr) {
4650
struct group grp;
47-
struct group *result;
48-
*perr = getgrnam_r(name, &grp, buf, buflen, &result);
49-
*found = result != NULL;
50-
return grp;
51+
struct group *result;
52+
memset(&grp, 0, sizeof(grp));
53+
*perr = getgrnam_r(name, &grp, buf, buflen, &result);
54+
*found = result != NULL;
55+
return grp;
5156
}
5257
*/
5358
import "C"

0 commit comments

Comments
 (0)