diff options
| author | H. Peter Anvin <hpa@linux.intel.com> | 2010-04-28 15:50:20 -0700 |
|---|---|---|
| committer | H. Peter Anvin <hpa@linux.intel.com> | 2010-04-28 15:50:20 -0700 |
| commit | 593ca98d8795f1c97c1424e2b8648c643a4c18f8 (patch) | |
| tree | e9c0fae288ec90b6a08b40ad61bc35cbf9ccc7f9 | |
| parent | 80889d3b8246678bafe6cbdd1abed969f669972f (diff) | |
| download | syslinux-4.00-pre39.tar.gz | |
extlinux: handle cases of a single level of directoriessyslinux-4.00-pre39
We had a boundary condition error where a single-level directory from
the global root (e.g. /boot) would be incorrectly truncated; fix that.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
| -rw-r--r-- | extlinux/main.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/extlinux/main.c b/extlinux/main.c index d1666718..e1d55964 100644 --- a/extlinux/main.c +++ b/extlinux/main.c @@ -441,7 +441,7 @@ int patch_file_and_bootblock(int fd, const char *dir, int devfd) int i, dw, nptrs; uint32_t csum; int secptroffset, diroffset, dirlen, subvoloffset, subvollen; - char *dirpath, *subpath; + char *dirpath, *subpath, *xdirpath, *xsubpath; dirpath = realpath(dir, NULL); if (!dirpath || stat(dir, &dirst)) { @@ -457,10 +457,17 @@ int patch_file_and_bootblock(int fd, const char *dir, int devfd) } subpath = strchr(dirpath, '\0'); - while (--subpath >= dirpath) { + for (;;) { if (*subpath == '/') { - *subpath = '\0'; - if (lstat(dirpath, &xdst) || dirst.st_dev != xdst.st_dev) { + if (subpath > dirpath) { + *subpath = '\0'; + xsubpath = subpath+1; + xdirpath = dirpath; + } else { + xsubpath = subpath; + xdirpath = "/"; + } + if (lstat(xdirpath, &xdst) || dirst.st_dev != xdst.st_dev) { subpath = strchr(subpath+1, '/'); if (!subpath) subpath = "/"; /* It's the root of the filesystem */ @@ -468,6 +475,11 @@ int patch_file_and_bootblock(int fd, const char *dir, int devfd) } *subpath = '/'; } + + if (subpath == dirpath) + break; + + subpath--; } /* Now subpath should contain the path relative to the fs base */ |
