From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <53E4B84C.6080506@mailinator.com> Date: Fri, 8 Aug 2014 12:45:16 +0100 From: Porlock User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.0 MIME-Version: 1.0 To: 9fans@9fans.net Content-Type: multipart/mixed; boundary="------------000802070604020407050305" Subject: [9fans] Bug in ramfs.c Topicbox-Message-UUID: 0d1f7b8a-ead9-11e9-9d60-3106f5b1d025 This is a multi-part message in MIME format. --------------000802070604020407050305 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit There is a bug in ramfs which causes it to crash when the length of a file is set to zero (using the wstat message). To see this bug, the attached utility to set the file length is helpful. Having first saved setlength.c into a plan9 directory, the following commands can be used to see the bug :- % 8c setlength.c && 8l -o setlength setlength.8 % ramfs -m /n/junk % echo something >/n/junk/test % ./setlength /n/junk/test 0 setting length of /n/junk/test to 0 ramfs: out of memory: ./setlength: dirwstat failed: i/o on hungup channel % unmount /n/junk The fix for the bug seems to be the following :- /sys/src/cmd/ramfs.c:880,886 - ramfs2.c:880,886 erealloc(void *p, ulong n) { p = realloc(p, n); - if(!p) + if(n && !p) error("out of memory"); return p; } the point is that when n == 0, realloc(p, n) will always return null (after first calling free(p)). So a null p is only an error if n > 0. --------------000802070604020407050305 Content-Type: text/x-csrc; name="setlength.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="setlength.c" #include #include void main(int argc, char **argv) { struct Dir st; int i, n; if (argc < 3) { fprint(2, "usage: %s file length\n", argv[0]); exits("usage"); } n = atoi(argv[2]); if (n < 0) { fprint(2, "%s: invalid length\n", argv[0]); exits("usage"); } nulldir(&st); st.length = n; print("setting length of %s to %d\n", argv[1], n); i = dirwstat(argv[1], &st); if (i < 0) { fprint(2, "%s: dirwstat failed: %r\n", argv[0]); exits("dirwstat"); } exits(0); } --------------000802070604020407050305--