ash: ensure variables are fully initialised when unset
When a variable is unset by calling setvar(name, NULL, 0) the code to initialise the new, empty variable fails to initialise the last character of the string. Attempts to read the contents of the unset variable will result in the uninitialised character at the end of the string being accessed. For example, running BusyBox under Valgrind and unsetting PATH: $ valgrind ./busybox_unstripped sh ==21249== Memcheck, a memory error detector ==21249== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==21249== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==21249== Command: ./busybox_unstripped sh ==21249== /data2/git/build_fix_8721 $ unset PATH /data2/git/build_fix_8721 $ 0 ==21249== Conditional jump or move depends on uninitialised value(s) ==21249== at 0x451371: path_advance (ash.c:2555) ==21249== by 0x456E22: find_command (ash.c:13407) ==21249== by 0x458425: evalcommand (ash.c:10139) ==21249== by 0x454CBC: evaltree (ash.c:9131) ==21249== by 0x456C80: cmdloop (ash.c:13164) Closes https://bugs.busybox.net/show_bug.cgi?id=8721 v2: On the dash mailing list Harald van Dijk was kind enough to point out a flaw in my reasoning and provide an alternative patch. Sadly his patch adds 2 bytes of bloat. Using xzalloc to zero the whole string gives a bloat of -3 bytes. function old new delta setvar 172 169 -3 Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
060f0a050a
commit
e6a63bf683
@ -2420,13 +2420,12 @@ setvar(const char *name, const char *val, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
INT_OFF;
|
INT_OFF;
|
||||||
nameeq = ckmalloc(namelen + vallen + 2);
|
nameeq = ckzalloc(namelen + vallen + 2);
|
||||||
p = mempcpy(nameeq, name, namelen);
|
p = mempcpy(nameeq, name, namelen);
|
||||||
if (val) {
|
if (val) {
|
||||||
*p++ = '=';
|
*p++ = '=';
|
||||||
p = mempcpy(p, val, vallen);
|
memcpy(p, val, vallen);
|
||||||
}
|
}
|
||||||
*p = '\0';
|
|
||||||
vp = setvareq(nameeq, flags | VNOSAVE);
|
vp = setvareq(nameeq, flags | VNOSAVE);
|
||||||
INT_ON;
|
INT_ON;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user