From patchwork Sat Jun 17 09:47:18 2006 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Klaus Schmidinger X-Patchwork-Id: 12335 Received: from raven.cadsoft.de ([217.7.101.211]) by www.linuxtv.org with esmtp (Exim 4.50) id 1FrXOj-00081z-U4 for vdr@linuxtv.org; Sat, 17 Jun 2006 11:47:21 +0200 Received: from [192.168.100.10] (hawk.cadsoft.de [192.168.100.10]) by raven.cadsoft.de (8.13.3/8.13.3) with ESMTP id k5H9lKYh000635 for ; Sat, 17 Jun 2006 11:47:20 +0200 Message-ID: <4493CFA6.8030500@cadsoft.de> Date: Sat, 17 Jun 2006 11:47:18 +0200 From: Klaus Schmidinger Organization: CadSoft Computer GmbH User-Agent: Thunderbird 1.5.0.4 (X11/20060516) MIME-Version: 1.0 To: vdr@linuxtv.org Subject: Re: [vdr] vdr-1.4.1: bug report and fix: ReadLink with relative targets References: <448C9538.2030500@errror.org> <448E3A5B.8070707@errror.org> In-Reply-To: <448E3A5B.8070707@errror.org> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-2.0 (raven.cadsoft.de [192.168.1.1]); Sat, 17 Jun 2006 11:47:21 +0200 (CEST) X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: VDR Mailing List List-Id: VDR Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 17 Jun 2006 09:47:22 -0000 Status: O X-Status: X-Keywords: X-UID: 9808 Patrick Cernko wrote: > Hi again, > > Patrick Cernko wrote: >> Hi Klaus, hi list, >> >> today I discovered that the ReadLink function (used in e.g. cSafeFile) >> does not handle relative links correctly. I used a symlinked >> channels.conf like that: >> >> errror@ds9:/var/lib/vdr> ll channels.conf >> lrwxrwxrwx 1 errror vdr 20 2006-06-12 00:03 channels.conf -> >> channels.conf.normal >> >> but vdr tried to write to channels.conf.$$$ in its current working >> directory ("/") which failed. :-( >> >> The bug is caused by the ReadLink function which always took the >> unchanged value of the found link as target (without prepending the >> links path for relative links). >> >> As a fix, I added a check for relative links (== not starting with a >> '/') and prepend the directory of the symlink. For that purpose I use >> some small parts from the coreutils "dirname" program as I learned for a >> long time that doing something so easy as computing the directory part >> of a path can lead to several errors if not done right. :-) >> >> Appended you find the patch, which makes vdr handle relative symlinks >> correctly. >> >> @Klaus: Feel free to review/reduce the code but pay attention to the >> special cases! ;-) Well, your patch looks like overkill to me ;-) What about using 'canonicalize_file_name()' instead? See the attached patch. Klaus --- tools.c 2006/05/26 10:10:31 1.118 +++ tools.c 2006/06/17 09:45:32 @@ -480,22 +480,16 @@ char *ReadLink(const char *FileName) { - char RealName[PATH_MAX]; - const char *TargetName = NULL; - int n = readlink(FileName, RealName, sizeof(RealName) - 1); - if (n < 0) { - if (errno == ENOENT || errno == EINVAL) // file doesn't exist or is not a symlink - TargetName = FileName; + if (!FileName) + return NULL; + char *TargetName = canonicalize_file_name(FileName); + if (!TargetName) { + if (errno == ENOENT) // file doesn't exist + TargetName = strdup(FileName); else // some other error occurred LOG_ERROR_STR(FileName); } - else if (n < int(sizeof(RealName))) { // got it! - RealName[n] = 0; - TargetName = RealName; - } - else - esyslog("ERROR: symlink's target name too long: %s", FileName); - return TargetName ? strdup(TargetName) : NULL; + return TargetName; } bool SpinUpDisk(const char *FileName)