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) {
fprintf(stderr, "config name is empty\n");
return -1;
}
if (is_dir(name)) { if (is_dir(name)) {
strcpy(dirname, name); fprintf(stderr, "%s: Is a directory\n", name);
strcat(dirname, "/"); return -1;
basename = conf_get_configname(); }
} else if ((slash = strrchr(name, '/'))) {
int size = slash - name + 1; if (make_parent_dir(name))
memcpy(dirname, name, size); return -1;
dirname[size] = 0;
if (slash[1])
basename = slash + 1;
else
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;
......
...@@ -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);
......
...@@ -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