Skip to content

Commit 2bbacd1

Browse files
committed
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
2 parents fcdec14 + 9b9f594 commit 2bbacd1

File tree

8 files changed

+89
-45
lines changed

8 files changed

+89
-45
lines changed

scripts/kconfig/confdata.c

Lines changed: 83 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright (C) 2002 Roman Zippel <[email protected]>
44
*/
55

6+
#include <sys/mman.h>
67
#include <sys/stat.h>
78
#include <ctype.h>
89
#include <errno.h>
@@ -36,6 +37,52 @@ static bool is_dir(const char *path)
3637
return S_ISDIR(st.st_mode);
3738
}
3839

40+
/* return true if the given two files are the same, false otherwise */
41+
static bool is_same(const char *file1, const char *file2)
42+
{
43+
int fd1, fd2;
44+
struct stat st1, st2;
45+
void *map1, *map2;
46+
bool ret = false;
47+
48+
fd1 = open(file1, O_RDONLY);
49+
if (fd1 < 0)
50+
return ret;
51+
52+
fd2 = open(file2, O_RDONLY);
53+
if (fd2 < 0)
54+
goto close1;
55+
56+
ret = fstat(fd1, &st1);
57+
if (ret)
58+
goto close2;
59+
ret = fstat(fd2, &st2);
60+
if (ret)
61+
goto close2;
62+
63+
if (st1.st_size != st2.st_size)
64+
goto close2;
65+
66+
map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0);
67+
if (map1 == MAP_FAILED)
68+
goto close2;
69+
70+
map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0);
71+
if (map2 == MAP_FAILED)
72+
goto close2;
73+
74+
if (bcmp(map1, map2, st1.st_size))
75+
goto close2;
76+
77+
ret = true;
78+
close2:
79+
close(fd2);
80+
close1:
81+
close(fd1);
82+
83+
return ret;
84+
}
85+
3986
/*
4087
* Create the parent directory of the given path.
4188
*
@@ -179,7 +226,7 @@ const char *conf_get_configname(void)
179226
return name ? name : ".config";
180227
}
181228

182-
const char *conf_get_autoconfig_name(void)
229+
static const char *conf_get_autoconfig_name(void)
183230
{
184231
char *name = getenv("KCONFIG_AUTOCONFIG");
185232

@@ -194,7 +241,7 @@ char *conf_get_default_confname(void)
194241
name = expand_string(conf_defname);
195242
env = getenv(SRCTREE);
196243
if (env) {
197-
sprintf(fullname, "%s/%s", env, name);
244+
snprintf(fullname, sizeof(fullname), "%s/%s", env, name);
198245
if (is_present(fullname))
199246
return fullname;
200247
}
@@ -817,40 +864,34 @@ int conf_write(const char *name)
817864
FILE *out;
818865
struct symbol *sym;
819866
struct menu *menu;
820-
const char *basename;
821867
const char *str;
822-
char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8];
868+
char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
823869
char *env;
824870

825-
dirname[0] = 0;
826-
if (name && name[0]) {
827-
char *slash;
828-
829-
if (is_dir(name)) {
830-
strcpy(dirname, name);
831-
strcat(dirname, "/");
832-
basename = conf_get_configname();
833-
} else if ((slash = strrchr(name, '/'))) {
834-
int size = slash - name + 1;
835-
memcpy(dirname, name, size);
836-
dirname[size] = 0;
837-
if (slash[1])
838-
basename = slash + 1;
839-
else
840-
basename = conf_get_configname();
841-
} else
842-
basename = name;
843-
} else
844-
basename = conf_get_configname();
845-
846-
sprintf(newname, "%s%s", dirname, basename);
871+
if (!name)
872+
name = conf_get_configname();
873+
874+
if (!*name) {
875+
fprintf(stderr, "config name is empty\n");
876+
return -1;
877+
}
878+
879+
if (is_dir(name)) {
880+
fprintf(stderr, "%s: Is a directory\n", name);
881+
return -1;
882+
}
883+
884+
if (make_parent_dir(name))
885+
return -1;
886+
847887
env = getenv("KCONFIG_OVERWRITECONFIG");
848-
if (!env || !*env) {
849-
sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
850-
out = fopen(tmpname, "w");
851-
} else {
888+
if (env && *env) {
852889
*tmpname = 0;
853-
out = fopen(newname, "w");
890+
out = fopen(name, "w");
891+
} else {
892+
snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp",
893+
name, (int)getpid());
894+
out = fopen(tmpname, "w");
854895
}
855896
if (!out)
856897
return 1;
@@ -897,14 +938,20 @@ int conf_write(const char *name)
897938
fclose(out);
898939

899940
if (*tmpname) {
900-
strcat(dirname, basename);
901-
strcat(dirname, ".old");
902-
rename(newname, dirname);
903-
if (rename(tmpname, newname))
941+
if (is_same(name, tmpname)) {
942+
conf_message("No change to %s", name);
943+
unlink(tmpname);
944+
sym_set_change_count(0);
945+
return 0;
946+
}
947+
948+
snprintf(oldname, sizeof(oldname), "%s.old", name);
949+
rename(name, oldname);
950+
if (rename(tmpname, name))
904951
return 1;
905952
}
906953

907-
conf_message("configuration written to %s", newname);
954+
conf_message("configuration written to %s", name);
908955

909956
sym_set_change_count(0);
910957

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

920-
if (!name)
921-
name = ".kconfig.d";
922967
out = fopen("..config.tmp", "w");
923968
if (!out)
924969
return 1;

scripts/kconfig/gconf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,7 @@ on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data)
638638
void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
639639
{
640640
GtkWidget *dialog;
641-
const gchar *intro_text =
641+
const gchar *intro_text =
642642
"Welcome to gkc, the GTK+ graphical configuration tool\n"
643643
"For each option, a blank box indicates the feature is disabled, a\n"
644644
"check indicates it is enabled, and a dot indicates that it is to\n"

scripts/kconfig/lexer.l

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,8 @@ FILE *zconf_fopen(const char *name)
378378
if (!f && name != NULL && name[0] != '/') {
379379
env = getenv(SRCTREE);
380380
if (env) {
381-
sprintf(fullname, "%s/%s", env, name);
381+
snprintf(fullname, sizeof(fullname),
382+
"%s/%s", env, name);
382383
f = fopen(fullname, "r");
383384
}
384385
}

scripts/kconfig/lkc.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ const char *zconf_curname(void);
4949

5050
/* confdata.c */
5151
const char *conf_get_configname(void);
52-
const char *conf_get_autoconfig_name(void);
5352
char *conf_get_default_confname(void);
5453
void sym_set_change_count(int count);
5554
void sym_add_change_count(int count);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
This is NOT the official version of dialog. This version has been
22
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
44
questions about this program.

scripts/kconfig/mconf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@ static void conf_save(void)
936936
set_config_filename(dialog_input_result);
937937
return;
938938
}
939-
show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60);
939+
show_textbox(NULL, "Can't create file!", 5, 60);
940940
break;
941941
case 1:
942942
show_helptext("Save Alternate Configuration", save_config_help);

scripts/kconfig/nconf-cfg.sh

100644100755
File mode changed.

scripts/kconfig/nconf.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,8 +1438,7 @@ static void conf_save(void)
14381438
set_config_filename(dialog_input_result);
14391439
return;
14401440
}
1441-
btn_dialog(main_window, "Can't create file! "
1442-
"Probably a nonexistent directory.",
1441+
btn_dialog(main_window, "Can't create file!",
14431442
1, "<OK>");
14441443
break;
14451444
case 1:

0 commit comments

Comments
 (0)