[Bug 1565567] Re: segv in sudo_getgrgid
Rafael David Tinoco
rafael.tinoco at canonical.com
Wed May 4 04:13:15 UTC 2016
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
Foundations Bugs, which is subscribed to sudo in Ubuntu.
https://bugs.launchpad.net/bugs/1565567
Title:
segv in sudo_getgrgid
Status in sudo package in Ubuntu:
Confirmed
Bug description:
If the user is in a group with no name (because libnss-db got removed
and the group was defined there, for example...) then:
the call to sudo_debug_printf in sudo_getgrgid
(plugins/sudoers/pwutil.c, line 462) causes a SEGV when trying to get
item->d.gr->gr_name (since item->d.gr is NULL).
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/sudo/+bug/1565567/+subscriptions
More information about the foundations-bugs
mailing list