Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'kconfig-v5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild

Pull Kconfig updates from Masahiro Yamada:

- error out if a user specifies a directory instead of a file from
"Save" menu of GUI interfaces

- do not overwrite .config if there is no change in the configuration

- create parent directories as needed when a user specifies a new file
path from "Save" menu of menuconfig/nconfig

- fix potential buffer overflow

- some trivial cleanups

* tag 'kconfig-v5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild:
kconfig: make conf_get_autoconfig_name() static
kconfig: use snprintf for formatting pathnames
kconfig: remove useless NULL pointer check in conf_write_dep()
kconfig: make parent directories for the saved .config as needed
kconfig: do not write .config if the content is the same
kconfig: do not accept a directory for configuration output
kconfig: remove trailing whitespaces
kconfig: Make nconf-cfg.sh executable

+87 -43
+81 -36
scripts/kconfig/confdata.c
··· 3 3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 4 4 */ 5 5 6 + #include <sys/mman.h> 6 7 #include <sys/stat.h> 7 8 #include <ctype.h> 8 9 #include <errno.h> ··· 35 34 return 0; 36 35 37 36 return S_ISDIR(st.st_mode); 37 + } 38 + 39 + /* return true if the given two files are the same, false otherwise */ 40 + static bool is_same(const char *file1, const char *file2) 41 + { 42 + int fd1, fd2; 43 + struct stat st1, st2; 44 + void *map1, *map2; 45 + bool ret = false; 46 + 47 + fd1 = open(file1, O_RDONLY); 48 + if (fd1 < 0) 49 + return ret; 50 + 51 + fd2 = open(file2, O_RDONLY); 52 + if (fd2 < 0) 53 + goto close1; 54 + 55 + ret = fstat(fd1, &st1); 56 + if (ret) 57 + goto close2; 58 + ret = fstat(fd2, &st2); 59 + if (ret) 60 + goto close2; 61 + 62 + if (st1.st_size != st2.st_size) 63 + goto close2; 64 + 65 + map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0); 66 + if (map1 == MAP_FAILED) 67 + goto close2; 68 + 69 + map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0); 70 + if (map2 == MAP_FAILED) 71 + goto close2; 72 + 73 + if (bcmp(map1, map2, st1.st_size)) 74 + goto close2; 75 + 76 + ret = true; 77 + close2: 78 + close(fd2); 79 + close1: 80 + close(fd1); 81 + 82 + return ret; 38 83 } 39 84 40 85 /* ··· 226 179 return name ? name : ".config"; 227 180 } 228 181 229 - const char *conf_get_autoconfig_name(void) 182 + static const char *conf_get_autoconfig_name(void) 230 183 { 231 184 char *name = getenv("KCONFIG_AUTOCONFIG"); 232 185 ··· 241 194 name = expand_string(conf_defname); 242 195 env = getenv(SRCTREE); 243 196 if (env) { 244 - sprintf(fullname, "%s/%s", env, name); 197 + snprintf(fullname, sizeof(fullname), "%s/%s", env, name); 245 198 if (is_present(fullname)) 246 199 return fullname; 247 200 } ··· 864 817 FILE *out; 865 818 struct symbol *sym; 866 819 struct menu *menu; 867 - const char *basename; 868 820 const char *str; 869 - char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8]; 821 + char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1]; 870 822 char *env; 871 823 872 - dirname[0] = 0; 873 - if (name && name[0]) { 874 - char *slash; 824 + if (!name) 825 + name = conf_get_configname(); 875 826 876 - if (is_dir(name)) { 877 - strcpy(dirname, name); 878 - strcat(dirname, "/"); 879 - basename = conf_get_configname(); 880 - } else if ((slash = strrchr(name, '/'))) { 881 - int size = slash - name + 1; 882 - memcpy(dirname, name, size); 883 - dirname[size] = 0; 884 - if (slash[1]) 885 - basename = slash + 1; 886 - else 887 - basename = conf_get_configname(); 888 - } else 889 - basename = name; 890 - } else 891 - basename = conf_get_configname(); 827 + if (!*name) { 828 + fprintf(stderr, "config name is empty\n"); 829 + return -1; 830 + } 892 831 893 - sprintf(newname, "%s%s", dirname, basename); 832 + if (is_dir(name)) { 833 + fprintf(stderr, "%s: Is a directory\n", name); 834 + return -1; 835 + } 836 + 837 + if (make_parent_dir(name)) 838 + return -1; 839 + 894 840 env = getenv("KCONFIG_OVERWRITECONFIG"); 895 - if (!env || !*env) { 896 - sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid()); 897 - out = fopen(tmpname, "w"); 898 - } else { 841 + if (env && *env) { 899 842 *tmpname = 0; 900 - out = fopen(newname, "w"); 843 + out = fopen(name, "w"); 844 + } else { 845 + snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp", 846 + name, (int)getpid()); 847 + out = fopen(tmpname, "w"); 901 848 } 902 849 if (!out) 903 850 return 1; ··· 938 897 fclose(out); 939 898 940 899 if (*tmpname) { 941 - strcat(dirname, basename); 942 - strcat(dirname, ".old"); 943 - rename(newname, dirname); 944 - if (rename(tmpname, newname)) 900 + if (is_same(name, tmpname)) { 901 + conf_message("No change to %s", name); 902 + unlink(tmpname); 903 + sym_set_change_count(0); 904 + return 0; 905 + } 906 + 907 + snprintf(oldname, sizeof(oldname), "%s.old", name); 908 + rename(name, oldname); 909 + if (rename(tmpname, name)) 945 910 return 1; 946 911 } 947 912 948 - conf_message("configuration written to %s", newname); 913 + conf_message("configuration written to %s", name); 949 914 950 915 sym_set_change_count(0); 951 916 ··· 964 917 struct file *file; 965 918 FILE *out; 966 919 967 - if (!name) 968 - name = ".kconfig.d"; 969 920 out = fopen("..config.tmp", "w"); 970 921 if (!out) 971 922 return 1;
+1 -1
scripts/kconfig/gconf.c
··· 638 638 void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) 639 639 { 640 640 GtkWidget *dialog; 641 - const gchar *intro_text = 641 + const gchar *intro_text = 642 642 "Welcome to gkc, the GTK+ graphical configuration tool\n" 643 643 "For each option, a blank box indicates the feature is disabled, a\n" 644 644 "check indicates it is enabled, and a dot indicates that it is to\n"
+2 -1
scripts/kconfig/lexer.l
··· 378 378 if (!f && name != NULL && name[0] != '/') { 379 379 env = getenv(SRCTREE); 380 380 if (env) { 381 - sprintf(fullname, "%s/%s", env, name); 381 + snprintf(fullname, sizeof(fullname), 382 + "%s/%s", env, name); 382 383 f = fopen(fullname, "r"); 383 384 } 384 385 }
-1
scripts/kconfig/lkc.h
··· 49 49 50 50 /* confdata.c */ 51 51 const char *conf_get_configname(void); 52 - const char *conf_get_autoconfig_name(void); 53 52 char *conf_get_default_confname(void); 54 53 void sym_set_change_count(int count); 55 54 void sym_add_change_count(int count);
+1 -1
scripts/kconfig/lxdialog/BIG.FAT.WARNING
··· 1 1 This is NOT the official version of dialog. This version has been 2 2 significantly modified from the original. It is for use by the Linux 3 - kernel configuration script. Please do not bother Savio Lam with 3 + kernel configuration script. Please do not bother Savio Lam with 4 4 questions about this program.
+1 -1
scripts/kconfig/mconf.c
··· 936 936 set_config_filename(dialog_input_result); 937 937 return; 938 938 } 939 - show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60); 939 + show_textbox(NULL, "Can't create file!", 5, 60); 940 940 break; 941 941 case 1: 942 942 show_helptext("Save Alternate Configuration", save_config_help);
scripts/kconfig/nconf-cfg.sh
+1 -2
scripts/kconfig/nconf.c
··· 1438 1438 set_config_filename(dialog_input_result); 1439 1439 return; 1440 1440 } 1441 - btn_dialog(main_window, "Can't create file! " 1442 - "Probably a nonexistent directory.", 1441 + btn_dialog(main_window, "Can't create file!", 1443 1442 1, "<OK>"); 1444 1443 break; 1445 1444 case 1: