Loading fs/proc/cmdline.c +158 −21 Original line number Original line Diff line number Diff line Loading @@ -2,6 +2,7 @@ #include <linux/init.h> #include <linux/init.h> #include <linux/proc_fs.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <linux/seq_file.h> #include <linux/ctype.h> #include <asm/setup.h> #include <asm/setup.h> static char new_command_line[COMMAND_LINE_SIZE]; static char new_command_line[COMMAND_LINE_SIZE]; Loading @@ -24,38 +25,174 @@ static const struct file_operations cmdline_proc_fops = { .release = single_release, .release = single_release, }; }; static void remove_flag(char *cmd, const char *flag) static unsigned int arg_len(const char *arg) { { char *start_addr, *end_addr; unsigned int i, quoted = 0; /* Ensure all instances of a flag are removed */ for(i = 0; arg[i] != '\0'; i++) { while ((start_addr = strstr(cmd, flag))) { if (isspace(arg[i]) && !quoted) end_addr = strchr(start_addr, ' '); break; if (end_addr) if (arg[i] == '"') quoted = !quoted; memmove(start_addr, end_addr + 1, strlen(end_addr)); else *(start_addr - 1) = '\0'; } } return i; } } static void remove_safetynet_flags(char *cmd) static char * unquote(char *str) { { remove_flag(cmd, "androidboot.enable_dm_verity="); unsigned int len; remove_flag(cmd, "androidboot.secboot="); remove_flag(cmd, "androidboot.verifiedbootstate="); if (*str == '"') str++; remove_flag(cmd, "androidboot.veritymode="); len = strlen(str); if ((len > 0) && (str[len - 1] == '"')) str[len - 1] = '\0'; return str; } } static int __init proc_cmdline_init(void) static int append(const char *str, unsigned int len) { { strcpy(new_command_line, saved_command_line); unsigned int cmd_len; cmd_len = strlen(new_command_line); if (cmd_len == 0) { if (len >= sizeof(new_command_line)) return -1; } else { if (cmd_len + len + 1 >= sizeof(new_command_line)) return -1; new_command_line[cmd_len++] = ' '; } strncat(new_command_line + cmd_len, str, len); new_command_line[cmd_len + len] = '\0'; return 0; } static int modify_cmd_line(const char *cmd_line, int (*callback)(const char *name, const char *val, const char ***list)) { static char buf[COMMAND_LINE_SIZE]; const char *in, *name, *val, **list; char *q; unsigned int len; int i, accept; in = cmd_line; *new_command_line = '\0'; while(*in != '\0'){ in = skip_spaces(in); len = arg_len(in); if (len >= sizeof(buf)) { pr_err("modify_cmd_line: parameter is too long, len=%d\n", len); goto error; } strncpy(buf, in, len); buf[len] = '\0'; q = strchr(buf, '='); if (q != NULL) { *q = '\0'; name = unquote(buf); val = unquote(q + 1); } else { name = NULL; val = unquote(buf); } list = NULL; accept = (callback == NULL) ? 1 : callback(name, val, &list); if (accept && (append(in, len) != 0)) { pr_err("modify_cmd_line: out string overflow\n"); goto error; } for(i = 0; (list != NULL) && (list[i] != NULL); i++) { if (append(list[i], strlen(list[i])) != 0) { pr_err("modify_cmd_line: out string overflow\n"); goto error; } } in += len; } if (callback != NULL) { list = NULL; callback(NULL, NULL, &list); for(i = 0; (list != NULL) && (list[i] != NULL); i++) { if (append(list[i], strlen(list[i])) != 0) { pr_err("modify_cmd_line: out string overflow\n"); goto error; } } } return 0; error: strcpy(new_command_line, cmd_line); return -1; } /* /* * Remove various flags from command line seen by userspace in order to * This function will be called for each of command line parameters and at the * pass SafetyNet CTS check. * end of patameter list as well. */ */ remove_safetynet_flags(new_command_line); static int modify_cmd_line_callback(const char *name, const char *val, const char ***list) { /* check for end of parameter list */ if ((name == NULL) && (val == NULL)){ // NULL terminated list of strings to append at the end of command line static const char *return_list[] = { NULL }; *list = return_list; return 1; } /* check for unnamed papameters */ if ((name == NULL) && (val != NULL)) { return 1; /* accept */ } /* drop parameters */ if ((strcmp(name, "androidboot.enable_dm_verity") == 0) || (strcmp(name, "androidboot.secboot") == 0) || (strcmp(name, "androidboot.verifiedbootstate") == 0) || (strcmp(name, "androidboot.veritymode") == 0)) { return 0; /* drop */ } #if 0 /* replace parameters */ if (strcmp(name, "some_param") == 0) { // NULL terminated list of strings to replace "some_param" static const char *return_list[] = { "other_param1=some_value1", "other_param2=some_value2", NULL }; // protection against double replacent static int replaced = 0; if (!replaced){ replaced = 1; *list = return_list; } return 0; /* drop */ } /* accept parameters and add some values after it */ if ((strcmp(name, "some_param_qqq") == 0) && (strcmp(val, "some_value_qqq") == 0)) { // NULL terminated list of strings to add after "some_param_qqq=some_value_qqq" static const char *return_list[] = {"other_param_qqq1=some_value1", "other_param_qqq2=some_value2", NULL}; // protection against double addition static int added = 0; if (!added){ added = 1; *list = return_list; } return 1; /* accept */ } #endif return 1; /* accept by default */ } static int __init proc_cmdline_init(void) { modify_cmd_line(saved_command_line, modify_cmd_line_callback); proc_create("cmdline", 0, NULL, &cmdline_proc_fops); proc_create("cmdline", 0, NULL, &cmdline_proc_fops); return 0; return 0; } } Loading Loading
fs/proc/cmdline.c +158 −21 Original line number Original line Diff line number Diff line Loading @@ -2,6 +2,7 @@ #include <linux/init.h> #include <linux/init.h> #include <linux/proc_fs.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <linux/seq_file.h> #include <linux/ctype.h> #include <asm/setup.h> #include <asm/setup.h> static char new_command_line[COMMAND_LINE_SIZE]; static char new_command_line[COMMAND_LINE_SIZE]; Loading @@ -24,38 +25,174 @@ static const struct file_operations cmdline_proc_fops = { .release = single_release, .release = single_release, }; }; static void remove_flag(char *cmd, const char *flag) static unsigned int arg_len(const char *arg) { { char *start_addr, *end_addr; unsigned int i, quoted = 0; /* Ensure all instances of a flag are removed */ for(i = 0; arg[i] != '\0'; i++) { while ((start_addr = strstr(cmd, flag))) { if (isspace(arg[i]) && !quoted) end_addr = strchr(start_addr, ' '); break; if (end_addr) if (arg[i] == '"') quoted = !quoted; memmove(start_addr, end_addr + 1, strlen(end_addr)); else *(start_addr - 1) = '\0'; } } return i; } } static void remove_safetynet_flags(char *cmd) static char * unquote(char *str) { { remove_flag(cmd, "androidboot.enable_dm_verity="); unsigned int len; remove_flag(cmd, "androidboot.secboot="); remove_flag(cmd, "androidboot.verifiedbootstate="); if (*str == '"') str++; remove_flag(cmd, "androidboot.veritymode="); len = strlen(str); if ((len > 0) && (str[len - 1] == '"')) str[len - 1] = '\0'; return str; } } static int __init proc_cmdline_init(void) static int append(const char *str, unsigned int len) { { strcpy(new_command_line, saved_command_line); unsigned int cmd_len; cmd_len = strlen(new_command_line); if (cmd_len == 0) { if (len >= sizeof(new_command_line)) return -1; } else { if (cmd_len + len + 1 >= sizeof(new_command_line)) return -1; new_command_line[cmd_len++] = ' '; } strncat(new_command_line + cmd_len, str, len); new_command_line[cmd_len + len] = '\0'; return 0; } static int modify_cmd_line(const char *cmd_line, int (*callback)(const char *name, const char *val, const char ***list)) { static char buf[COMMAND_LINE_SIZE]; const char *in, *name, *val, **list; char *q; unsigned int len; int i, accept; in = cmd_line; *new_command_line = '\0'; while(*in != '\0'){ in = skip_spaces(in); len = arg_len(in); if (len >= sizeof(buf)) { pr_err("modify_cmd_line: parameter is too long, len=%d\n", len); goto error; } strncpy(buf, in, len); buf[len] = '\0'; q = strchr(buf, '='); if (q != NULL) { *q = '\0'; name = unquote(buf); val = unquote(q + 1); } else { name = NULL; val = unquote(buf); } list = NULL; accept = (callback == NULL) ? 1 : callback(name, val, &list); if (accept && (append(in, len) != 0)) { pr_err("modify_cmd_line: out string overflow\n"); goto error; } for(i = 0; (list != NULL) && (list[i] != NULL); i++) { if (append(list[i], strlen(list[i])) != 0) { pr_err("modify_cmd_line: out string overflow\n"); goto error; } } in += len; } if (callback != NULL) { list = NULL; callback(NULL, NULL, &list); for(i = 0; (list != NULL) && (list[i] != NULL); i++) { if (append(list[i], strlen(list[i])) != 0) { pr_err("modify_cmd_line: out string overflow\n"); goto error; } } } return 0; error: strcpy(new_command_line, cmd_line); return -1; } /* /* * Remove various flags from command line seen by userspace in order to * This function will be called for each of command line parameters and at the * pass SafetyNet CTS check. * end of patameter list as well. */ */ remove_safetynet_flags(new_command_line); static int modify_cmd_line_callback(const char *name, const char *val, const char ***list) { /* check for end of parameter list */ if ((name == NULL) && (val == NULL)){ // NULL terminated list of strings to append at the end of command line static const char *return_list[] = { NULL }; *list = return_list; return 1; } /* check for unnamed papameters */ if ((name == NULL) && (val != NULL)) { return 1; /* accept */ } /* drop parameters */ if ((strcmp(name, "androidboot.enable_dm_verity") == 0) || (strcmp(name, "androidboot.secboot") == 0) || (strcmp(name, "androidboot.verifiedbootstate") == 0) || (strcmp(name, "androidboot.veritymode") == 0)) { return 0; /* drop */ } #if 0 /* replace parameters */ if (strcmp(name, "some_param") == 0) { // NULL terminated list of strings to replace "some_param" static const char *return_list[] = { "other_param1=some_value1", "other_param2=some_value2", NULL }; // protection against double replacent static int replaced = 0; if (!replaced){ replaced = 1; *list = return_list; } return 0; /* drop */ } /* accept parameters and add some values after it */ if ((strcmp(name, "some_param_qqq") == 0) && (strcmp(val, "some_value_qqq") == 0)) { // NULL terminated list of strings to add after "some_param_qqq=some_value_qqq" static const char *return_list[] = {"other_param_qqq1=some_value1", "other_param_qqq2=some_value2", NULL}; // protection against double addition static int added = 0; if (!added){ added = 1; *list = return_list; } return 1; /* accept */ } #endif return 1; /* accept by default */ } static int __init proc_cmdline_init(void) { modify_cmd_line(saved_command_line, modify_cmd_line_callback); proc_create("cmdline", 0, NULL, &cmdline_proc_fops); proc_create("cmdline", 0, NULL, &cmdline_proc_fops); return 0; return 0; } } Loading