From: Ben Gras Date: Thu, 26 Jan 2006 14:31:00 +0000 (+0000) Subject: Safety feature for symlink() - verify length of symlink contents X-Git-Tag: v3.1.2a~413 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/static/style.css?a=commitdiff_plain;h=43051c182af2b6099f1fc0035e6e3a2591f8f6ed;p=minix.git Safety feature for symlink() - verify length of symlink contents buffer with strlen() --- diff --git a/servers/fs/open.c b/servers/fs/open.c index 0c97c2a5f..86a17acec 100644 --- a/servers/fs/open.c +++ b/servers/fs/open.c @@ -504,7 +504,7 @@ PUBLIC int do_slink() if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) return(err_code); - if (m_in.name1_length <= 1 || m_in.name1_length > _MIN_BLOCK_SIZE+1) + if (m_in.name1_length <= 1 || m_in.name1_length >= _MIN_BLOCK_SIZE) return(ENAMETOOLONG); /* Create the inode for the symlink. */ @@ -517,10 +517,25 @@ PUBLIC int do_slink() if ((r = err_code) == OK) { r = (bp = new_block(sip, (off_t) 0)) == NIL_BUF ? err_code - : ( sip->i_size = m_in.name1_length-1, - sys_vircopy(who, D, (vir_bytes) m_in.name1, + : sys_vircopy(who, D, (vir_bytes) m_in.name1, SELF, D, (vir_bytes) bp->b_data, - (vir_bytes) m_in.name1_length-1)); + (vir_bytes) m_in.name1_length-1); + + if(r == OK) { + bp->b_data[_MIN_BLOCK_SIZE-1] = '\0'; + sip->i_size = strlen(bp->b_data); + if(sip->i_size != m_in.name1_length-1) { + /* This can happen if the user provides a buffer + * with a \0 in it. This can cause a lot of trouble + * when the symlink is used later. We could just use + * the strlen() value, but we want to let the user + * know he did something wrong. ENAMETOOLONG doesn't + * exactly describe the error, but there is no + * ENAMETOOWRONG. + */ + r = ENAMETOOLONG; + } + } put_block(bp, DIRECTORY_BLOCK); /* put_block() accepts NIL_BUF. */