Commit 2bbacd1a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+83 −38
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
 */

#include <sys/mman.h>
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h>
@@ -36,6 +37,52 @@ static bool is_dir(const char *path)
	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.
 *
@@ -179,7 +226,7 @@ const char *conf_get_configname(void)
	return name ? name : ".config";
}

const char *conf_get_autoconfig_name(void)
static const char *conf_get_autoconfig_name(void)
{
	char *name = getenv("KCONFIG_AUTOCONFIG");

@@ -194,7 +241,7 @@ char *conf_get_default_confname(void)
	name = expand_string(conf_defname);
	env = getenv(SRCTREE);
	if (env) {
		sprintf(fullname, "%s/%s", env, name);
		snprintf(fullname, sizeof(fullname), "%s/%s", env, name);
		if (is_present(fullname))
			return fullname;
	}
@@ -817,40 +864,34 @@ int conf_write(const char *name)
	FILE *out;
	struct symbol *sym;
	struct menu *menu;
	const char *basename;
	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;

	dirname[0] = 0;
	if (name && name[0]) {
		char *slash;
	if (!name)
		name = conf_get_configname();

	if (!*name) {
		fprintf(stderr, "config name is empty\n");
		return -1;
	}

	if (is_dir(name)) {
			strcpy(dirname, name);
			strcat(dirname, "/");
			basename = conf_get_configname();
		} else if ((slash = strrchr(name, '/'))) {
			int size = slash - name + 1;
			memcpy(dirname, name, size);
			dirname[size] = 0;
			if (slash[1])
				basename = slash + 1;
			else
				basename = conf_get_configname();
		} else
			basename = name;
	} else
		basename = conf_get_configname();
		fprintf(stderr, "%s: Is a directory\n", name);
		return -1;
	}

	if (make_parent_dir(name))
		return -1;

	sprintf(newname, "%s%s", dirname, basename);
	env = getenv("KCONFIG_OVERWRITECONFIG");
	if (!env || !*env) {
		sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
		out = fopen(tmpname, "w");
	} else {
	if (env && *env) {
		*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)
		return 1;
@@ -897,14 +938,20 @@ next:
	fclose(out);

	if (*tmpname) {
		strcat(dirname, basename);
		strcat(dirname, ".old");
		rename(newname, dirname);
		if (rename(tmpname, newname))
		if (is_same(name, tmpname)) {
			conf_message("No change to %s", name);
			unlink(tmpname);
			sym_set_change_count(0);
			return 0;
		}

		snprintf(oldname, sizeof(oldname), "%s.old", name);
		rename(name, oldname);
		if (rename(tmpname, name))
			return 1;
	}

	conf_message("configuration written to %s", newname);
	conf_message("configuration written to %s", name);

	sym_set_change_count(0);

@@ -917,8 +964,6 @@ static int conf_write_dep(const char *name)
	struct file *file;
	FILE *out;

	if (!name)
		name = ".kconfig.d";
	out = fopen("..config.tmp", "w");
	if (!out)
		return 1;
+2 −1
Original line number Diff line number Diff line
@@ -378,7 +378,8 @@ FILE *zconf_fopen(const char *name)
	if (!f && name != NULL && name[0] != '/') {
		env = getenv(SRCTREE);
		if (env) {
			sprintf(fullname, "%s/%s", env, name);
			snprintf(fullname, sizeof(fullname),
				 "%s/%s", env, name);
			f = fopen(fullname, "r");
		}
	}
+0 −1
Original line number Diff line number Diff line
@@ -49,7 +49,6 @@ const char *zconf_curname(void);

/* confdata.c */
const char *conf_get_configname(void);
const char *conf_get_autoconfig_name(void);
char *conf_get_default_confname(void);
void sym_set_change_count(int count);
void sym_add_change_count(int count);
+1 −1
Original line number Diff line number Diff line
@@ -936,7 +936,7 @@ static void conf_save(void)
				set_config_filename(dialog_input_result);
				return;
			}
			show_textbox(NULL, "Can't create file!  Probably a nonexistent directory.", 5, 60);
			show_textbox(NULL, "Can't create file!", 5, 60);
			break;
		case 1:
			show_helptext("Save Alternate Configuration", save_config_help);

scripts/kconfig/nconf-cfg.sh

100644 → 100755
+0 −0

File mode changed from 100644 to 100755.

Loading