diff --git a/sys/vfs/devfs/devfs_rules.c b/sys/vfs/devfs/devfs_rules.c index 0000000..1111111 100644 --- a/sys/vfs/devfs/devfs_rules.c +++ b/sys/vfs/devfs/devfs_rules.c @@ -111,6 +111,17 @@ } if (templ->rule_cmd & DEVFS_RULE_LINK) { + /* + * devfs_rule_create_link() unconditionally dereferences + * rule->name (to detect a trailing '*' wildcard), so a LINK + * rule must also carry DEVFS_RULE_NAME -- otherwise rule->name + * stays NULL and rule->namlen stays 0, and the later apply + * faults at address 0xffffffffffffffff (NULL + (u_char)0 - 1). + */ + if (!(templ->rule_type & DEVFS_RULE_NAME)) + goto error_out; + /* NOTREACHED */ + if (templ->linkname == NULL) goto error_out; /* NOTREACHED */ @@ -240,7 +251,15 @@ char *path = NULL; char *name, name_buf[PATH_MAX], buf[PATH_MAX]; - if (rule->name[rule->namlen-1] == '*') { + /* + * Defense in depth: devfs_rule_alloc() now rejects LINK rules + * that lack NAME, but be defensive against any pre-existing rule + * or future code path that could leave rule->name == NULL. + * Without a name there is no wildcard suffix to strip, so just + * create the alias verbatim from linkname. + */ + if ((rule->name != NULL) && (rule->namlen > 0) && + (rule->name[rule->namlen-1] == '*')) { devfs_resolve_name_path(rule->name, name_buf, &path, &name); len = strlen(name); --len;