It was brought to my attention a crash just like this one. Here is my
analsysis:
## INTRODUCTION
# From plugins/sudoers/pwutil.c:
/*
* Get a password entry by uid and allocate space for it.
*/
struct passwd *
sudo_getpwuid(uid_t uid)
{
struct cache_item key, *item;
struct rbnode *node;
debug_decl(sudo_getpwuid, SUDOERS_DEBUG_NSS)
key.k.uid = uid;
getauthregistry(IDtouser(uid), key.registry);
if ((node = rbfind(pwcache_byuid, &key)) != NULL) {
item = node->data;
sudo_debug_printf(SUDO_DEBUG_DEBUG,
"%s: uid %u [%s] -> user %s [%s] (cache hit)", __func__,
(unsigned int)uid, key.registry, item->d.pw->pw_name,
item->registry);
goto done;
}
being the last frame in the debugger:
#0 0x00007fa01c0a6944 in sudo_getgrgid (gid=7241) at
/build/sudo-g3ghsu/sudo-1.8.16/plugins/sudoers/pwutil.c:462
key = {refcnt = 1275378544, registry =
"\000V\000\000\330\f\005L\027V\000\000\000\000\000", k = {uid = 7241,
gid = 7241, name = 0x28b4cb5700001c49 <error: Cannot access memory
at address 0x28b4cb5700001c49>}, d = {
pw = 0x7ffffd9d43d0, gr = 0x7ffffd9d43d0, grlist = 0x7ffffd9d43d0}}
item = 0x56174c050700
node = <optimized out>
sudo_debug_subsys = 0
__func__ = "sudo_getgrgid"
We can see that all local variables are accessible but an union:
/*
* Generic cache element.
*/
struct cache_item {
unsigned int refcnt;
char registry[16];
/* key */
union {
uid_t uid;
gid_t gid;
char *name;
} k;
/* datum */
union {
struct passwd *pw;
struct group *gr;
struct group_list *grlist;
} d;
};
(gdb) print item
$35 = (struct cache_item *) 0x56174c050700
(gdb) print item->d
$36 = {pw = 0x0, gr = 0x0, grlist = 0x0}
The union pointer "d" could be either a struct passwd, a struct group or
a struct group_list (union nature).
BUT, we can see that, from sudo_getpwuid, it is being used as a struct
passwd (d.pw):
sudo_debug_printf(SUDO_DEBUG_DEBUG,
"%s: uid %u [%s] -> user %s [%s] (cache hit)", __func__,
(unsigned int)uid, key.registry, item->d.pw->pw_name,
item->registry);
Meaning that, probably, the password structure, for this user, wasn't
filled in.
I can tell that because the "node" (from the tree) seems good:
if ((node = rbfind(pwcache_byuid, &key)) != NULL) {
item = node->data;
(gdb) print item->k
$38 = {uid = 7241, gid = 7241, name = 0x1c49 ""}
since uid 7241 and gid 7241 seems reasonable.
But not the "item->d" union.
So we are only missing:
struct passwd *pw;
>From the node.
"struct passwd" is (from /usr/include/pwd.h):
/* The passwd structure. */
struct passwd
{
char *pw_name; /* Username. */
char *pw_passwd; /* Password. */
__uid_t pw_uid; /* User ID. */
__gid_t pw_gid; /* Group ID. */
char *pw_gecos; /* Real name. */
char *pw_dir; /* Home directory. */
char *pw_shell; /* Shell program. */
};
And tells us that it is/was an easy way for the debug message to get
username from uid.
Now, lets check when this struct should have been filled in:
item comes from "node->data", a generic redblack tree node.
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1565567
Title:
segv in sudo_getgrgid
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/sudo/+bug/1565567/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs