X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=udev_rules.c;h=1139c99a7d0e84ff3b8e289a3c6af251d5aabf76;hp=61b39b45c80514b338b8113024d6c76f2af1b8dd;hb=f7e34eb3e7e8c84cb7ce55ad64e4813e7985936a;hpb=db6e59df561dbedb89a27d7362d6564847258bfe diff --git a/udev_rules.c b/udev_rules.c index 61b39b45c..1139c99a7 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -79,67 +79,37 @@ static int get_key(char **line, char **key, char **value) char *temp; linepos = *line; - if (!linepos) + if (linepos == NULL) return -1; - if (strchr(linepos, '\\')) { - dbg("escaped characters are not supported, skip"); - return -1; - } - /* skip whitespace */ while (isspace(linepos[0])) linepos++; /* get the key */ + temp = strchr(linepos, '='); + if (temp == NULL || temp == linepos) + return -1; + temp[0] = '\0'; *key = linepos; - while (1) { - linepos++; - if (linepos[0] == '\0') - return -1; - if (isspace(linepos[0])) - break; - if (linepos[0] == '=') - break; + linepos = &temp[1]; + + /* get a quoted value */ + if (linepos[0] == '"' || linepos[0] == '\'') { + temp = strchr(&linepos[1], linepos[0]); + if (temp != NULL) { + temp[0] = '\0'; + *value = &linepos[1]; + goto out; + } } - /* terminate key */ - linepos[0] = '\0'; - linepos++; - - /* skip whitespace */ - while (isspace(linepos[0])) - linepos++; - /* get the value*/ - if (linepos[0] == '"') { - linepos++; - temp = strchr(linepos, '"'); - if (!temp) { - dbg("missing closing quote"); - return -1; - } - dbg("value is quoted"); + temp = strchr(linepos, '\n'); + if (temp != NULL) temp[0] = '\0'; - } else if (linepos[0] == '\'') { - linepos++; - temp = strchr(linepos, '\''); - if (!temp) { - dbg("missing closing quote"); - return -1; - } - dbg("value is quoted"); - temp[0] = '\0'; - } else if (linepos[0] == '\0') { - dbg("value is empty"); - } else { - temp = linepos; - while (temp[0] && !isspace(temp[0])) - temp++; - temp[0] = '\0'; - } *value = linepos; - +out: return 0; } @@ -217,7 +187,7 @@ static int import_file_into_env(struct udevice *udev, const char *filename) static int import_program_into_env(struct udevice *udev, const char *program) { - char result[1024]; + char result[2048]; size_t reslen; if (run_program(program, udev->dev->subsystem, result, sizeof(result), &reslen, (udev_log_priority >= LOG_INFO)) != 0) @@ -496,15 +466,15 @@ found: if (value == NULL) break; - /* strip trailing whitespace and replace untrusted characters of sysfs value */ + /* strip trailing whitespace, and replace unwanted characters */ size = strlcpy(temp2, value, sizeof(temp2)); if (size >= sizeof(temp2)) size = sizeof(temp2)-1; while (size > 0 && isspace(temp2[size-1])) temp2[--size] = '\0'; - count = replace_untrusted_chars(temp2); + count = replace_chars(temp2, ALLOWED_CHARS_INPUT); if (count > 0) - info("%i untrusted character(s) replaced" , count); + info("%i character(s) replaced" , count); strlcat(string, temp2, maxsize); dbg("substitute sysfs value '%s'", temp2); } @@ -532,7 +502,7 @@ found: } break; case SUBST_TEMP_NODE: - if (udev->tmp_node[0] == '\0') { + if (udev->tmp_node[0] == '\0' && major(udev->devt) > 0) { dbg("create temporary device node for callout"); snprintf(udev->tmp_node, sizeof(udev->tmp_node), "%s/.tmp-%u-%u", udev_root, major(udev->devt), minor(udev->devt)); @@ -781,9 +751,9 @@ try_parent: dbg("PROGRAM matches"); remove_trailing_chars(result, '\n'); - count = replace_untrusted_chars(result); + count = replace_chars(result, ALLOWED_CHARS_INPUT); if (count) - info("%i untrusted character(s) replaced" , count); + info("%i character(s) replaced" , count); dbg("result is '%s'", result); strlcpy(udev->program_result, result, sizeof(udev->program_result)); dbg("PROGRAM returned successful"); @@ -851,7 +821,7 @@ try_parent: } } - /* if we have ATTR assignements write value to sysfs file */ + /* if we have ATTR assignments, write value to sysfs file */ for (i = 0; i < rule->attr.count; i++) { struct key_pair *pair = &rule->attr.keys[i]; @@ -964,14 +934,13 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev) info("reset symlink list"); name_list_cleanup(&udev->symlink_list); } + /* allow multiple symlinks separated by spaces */ strlcpy(temp, key_val(rule, &rule->symlink), sizeof(temp)); udev_rules_apply_format(udev, temp, sizeof(temp)); - count = replace_untrusted_chars(temp); + count = replace_chars(temp, ALLOWED_CHARS_FILE " "); if (count) - info("%i untrusted character(s) replaced" , count); + info("%i character(s) replaced" , count); dbg("rule applied, added symlink(s) '%s'", temp); - - /* add multiple symlinks separated by spaces */ pos = temp; while (isspace(pos[0])) pos++; @@ -1000,9 +969,9 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev) name_set = 1; strlcpy(udev->name, key_val(rule, &rule->name), sizeof(udev->name)); udev_rules_apply_format(udev, udev->name, sizeof(udev->name)); - count = replace_untrusted_chars(udev->name); + count = replace_chars(udev->name, ALLOWED_CHARS_FILE); if (count) - info("%i untrusted character(s) replaced", count); + info("%i character(s) replaced", count); info("rule applied, '%s' becomes '%s'", udev->dev->kernel, udev->name); if (strcmp(udev->dev->subsystem, "net") != 0)