Commit 2bbacd1a authored by Linus Torvalds's avatar Linus Torvalds

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
parents fcdec143 9b9f5948
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
*/ */
#include <sys/mman.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
...@@ -36,6 +37,52 @@ static bool is_dir(const char *path) ...@@ -36,6 +37,52 @@ static bool is_dir(const char *path)
return S_ISDIR(st.st_mode); return S_ISDIR(st.st_mode);
} }
/* return true if the given two files are the same, false otherwise */
static bool is_same(const char *file1, const char *file2)
{
int fd1, fd2;
struct stat st1, st2;
void *map1, *map2;
bool ret = false;
fd1 = open(file1, O_RDONLY);
if (fd1 < 0)
return ret;
fd2 = open(file2, O_RDONLY);
if (fd2 < 0)
goto close1;
ret = fstat(fd1, &st1);
if (ret)
goto close2;
ret = fstat(fd2, &st2);
if (ret)
goto close2;
if (st1.st_size != st2.st_size)
goto close2;
map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0);
if (map1 == MAP_FAILED)
goto close2;
map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0);
if (map2 == MAP_FAILED)
goto close2;
if (bcmp(map1, map2, st1.st_size))
goto close2;
ret = true;
close2:
close(fd2);
close1:
close(fd1);
return ret;
}
/* /*
* Create the parent directory of the given path. * Create the parent directory of the given path.
* *
...@@ -179,7 +226,7 @@ const char *conf_get_configname(void) ...@@ -179,7 +226,7 @@ const char *conf_get_configname(void)
return name ? name : ".config"; return name ? name : ".config";
} }
const char *conf_get_autoconfig_name(void) static const char *conf_get_autoconfig_name(void)
{ {
char *name = getenv("KCONFIG_AUTOCONFIG"); char *name = getenv("KCONFIG_AUTOCONFIG");
...@@ -194,7 +241,7 @@ char *conf_get_default_confname(void) ...@@ -194,7 +241,7 @@ char *conf_get_default_confname(void)
name = expand_string(conf_defname); name = expand_string(conf_defname);
env = getenv(SRCTREE); env = getenv(SRCTREE);
if (env) { if (env) {
sprintf(fullname, "%s/%s", env, name); snprintf(fullname, sizeof(fullname), "%s/%s", env, name);
if (is_present(fullname)) if (is_present(fullname))
return fullname; return fullname;
} }
...@@ -817,40 +864,34 @@ int conf_write(const char *name) ...@@ -817,40 +864,34 @@ int conf_write(const char *name)
FILE *out; FILE *out;
struct symbol *sym; struct symbol *sym;
struct menu *menu; struct menu *menu;
const char *basename;
const char *str; const char *str;
char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8]; char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
char *env; char *env;
dirname[0] = 0; if (!name)
if (name && name[0]) { name = conf_get_configname();
char *slash;
if (!*name) {
if (is_dir(name)) { fprintf(stderr, "config name is empty\n");
strcpy(dirname, name); return -1;
strcat(dirname, "/"); }
basename = conf_get_configname();
} else if ((slash = strrchr(name, '/'))) { if (is_dir(name)) {
int size = slash - name + 1; fprintf(stderr, "%s: Is a directory\n", name);
memcpy(dirname, name, size); return -1;
dirname[size] = 0; }
if (slash[1])
basename = slash + 1; if (make_parent_dir(name))
else return -1;
basename = conf_get_configname();
} else
basename = name;
} else
basename = conf_get_configname();
sprintf(newname, "%s%s", dirname, basename);
env = getenv("KCONFIG_OVERWRITECONFIG"); env = getenv("KCONFIG_OVERWRITECONFIG");
if (!env || !*env) { if (env && *env) {
sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
out = fopen(tmpname, "w");
} else {
*tmpname = 0; *tmpname = 0;
out = fopen(newname, "w"); out = fopen(name, "w");
} else {
snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp",
name, (int)getpid());
out = fopen(tmpname, "w");
} }
if (!out) if (!out)
return 1; return 1;
...@@ -897,14 +938,20 @@ int conf_write(const char *name) ...@@ -897,14 +938,20 @@ int conf_write(const char *name)
fclose(out); fclose(out);
if (*tmpname) { if (*tmpname) {
strcat(dirname, basename); if (is_same(name, tmpname)) {
strcat(dirname, ".old"); conf_message("No change to %s", name);
rename(newname, dirname); unlink(tmpname);
if (rename(tmpname, newname)) sym_set_change_count(0);
return 0;
}
snprintf(oldname, sizeof(oldname), "%s.old", name);
rename(name, oldname);
if (rename(tmpname, name))
return 1; return 1;
} }
conf_message("configuration written to %s", newname); conf_message("configuration written to %s", name);
sym_set_change_count(0); sym_set_change_count(0);
...@@ -917,8 +964,6 @@ static int conf_write_dep(const char *name) ...@@ -917,8 +964,6 @@ static int conf_write_dep(const char *name)
struct file *file; struct file *file;
FILE *out; FILE *out;
if (!name)
name = ".kconfig.d";
out = fopen("..config.tmp", "w"); out = fopen("..config.tmp", "w");
if (!out) if (!out)
return 1; return 1;
......
...@@ -638,7 +638,7 @@ on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data) ...@@ -638,7 +638,7 @@ on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data)
void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
{ {
GtkWidget *dialog; GtkWidget *dialog;
const gchar *intro_text = const gchar *intro_text =
"Welcome to gkc, the GTK+ graphical configuration tool\n" "Welcome to gkc, the GTK+ graphical configuration tool\n"
"For each option, a blank box indicates the feature is disabled, a\n" "For each option, a blank box indicates the feature is disabled, a\n"
"check indicates it is enabled, and a dot indicates that it is to\n" "check indicates it is enabled, and a dot indicates that it is to\n"
......
...@@ -378,7 +378,8 @@ FILE *zconf_fopen(const char *name) ...@@ -378,7 +378,8 @@ FILE *zconf_fopen(const char *name)
if (!f && name != NULL && name[0] != '/') { if (!f && name != NULL && name[0] != '/') {
env = getenv(SRCTREE); env = getenv(SRCTREE);
if (env) { if (env) {
sprintf(fullname, "%s/%s", env, name); snprintf(fullname, sizeof(fullname),
"%s/%s", env, name);
f = fopen(fullname, "r"); f = fopen(fullname, "r");
} }
} }
......
...@@ -49,7 +49,6 @@ const char *zconf_curname(void); ...@@ -49,7 +49,6 @@ const char *zconf_curname(void);
/* confdata.c */ /* confdata.c */
const char *conf_get_configname(void); const char *conf_get_configname(void);
const char *conf_get_autoconfig_name(void);
char *conf_get_default_confname(void); char *conf_get_default_confname(void);
void sym_set_change_count(int count); void sym_set_change_count(int count);
void sym_add_change_count(int count); void sym_add_change_count(int count);
......
This is NOT the official version of dialog. This version has been This is NOT the official version of dialog. This version has been
significantly modified from the original. It is for use by the Linux significantly modified from the original. It is for use by the Linux
kernel configuration script. Please do not bother Savio Lam with kernel configuration script. Please do not bother Savio Lam with
questions about this program. questions about this program.
...@@ -936,7 +936,7 @@ static void conf_save(void) ...@@ -936,7 +936,7 @@ static void conf_save(void)
set_config_filename(dialog_input_result); set_config_filename(dialog_input_result);
return; return;
} }
show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60); show_textbox(NULL, "Can't create file!", 5, 60);
break; break;
case 1: case 1:
show_helptext("Save Alternate Configuration", save_config_help); show_helptext("Save Alternate Configuration", save_config_help);
......
File mode changed from 100644 to 100755
...@@ -1438,8 +1438,7 @@ static void conf_save(void) ...@@ -1438,8 +1438,7 @@ static void conf_save(void)
set_config_filename(dialog_input_result); set_config_filename(dialog_input_result);
return; return;
} }
btn_dialog(main_window, "Can't create file! " btn_dialog(main_window, "Can't create file!",
"Probably a nonexistent directory.",
1, "<OK>"); 1, "<OK>");
break; break;
case 1: case 1:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment