diff --git a/defs.h b/defs.h index a942dbb..0124f5f 100755 --- a/defs.h +++ b/defs.h @@ -1281,6 +1281,11 @@ struct offset_table { /* stash of commonly-used offsets */ long vfsmount_mnt_list; long vfsmount_mnt_mountpoint; long vfsmount_mnt_parent; + long mount_mnt_parent; + long mount_mnt_mountpoint; + long mount_mnt_list; + long mount_mnt_devname; + long mount_mnt; long namespace_root; long namespace_list; long super_block_s_dirty; @@ -1694,6 +1699,7 @@ struct size_table { /* stash of commonly-used sizes */ long fs_struct; long file; long inode; + long mount; long vfsmount; long super_block; long irqdesc; diff --git a/filesys.c b/filesys.c index 55a4677..0f4db2a 100755 --- a/filesys.c +++ b/filesys.c @@ -1298,7 +1298,7 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex char buf4[BUFSIZE]; ulong *dentry_list, *dp, *mntlist; ulong *vfsmnt; - char *vfsmount_buf, *super_block_buf; + char *vfsmount_buf, *super_block_buf, *mount_buf; ulong dentry, inode, inode_sb, mnt_parent; char *dentry_buf, *inode_buf; int cnt, i, m, files_header_printed; @@ -1336,9 +1336,15 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex devlen = strlen("DEVNAME"); for (m = 0, vfsmnt = mntlist; m < mount_cnt; m++, vfsmnt++) { - readmem(*vfsmnt + OFFSET(vfsmount_mnt_devname), - KVADDR, &devp, sizeof(void *), - "vfsmount mnt_devname", FAULT_ON_ERROR); + if (VALID_STRUCT(mount)) { + readmem(*vfsmnt+OFFSET(mount_mnt_devname), + KVADDR, &devp, sizeof(void *), + "mount mnt_devname", FAULT_ON_ERROR); + } else { + readmem(*vfsmnt+OFFSET(vfsmount_mnt_devname), + KVADDR, &devp, sizeof(void *), + "vfsmount mnt_devname", FAULT_ON_ERROR); + } if (read_string(devp, buf1, BUFSIZE-1)) { if (strlen(buf1) > devlen) @@ -1366,23 +1372,41 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex &cnt); } - vfsmount_buf = GETBUF(SIZE(vfsmount)); + if (VALID_STRUCT(mount)) { + mount_buf = GETBUF(SIZE(mount)); + vfsmount_buf = mount_buf + OFFSET(mount_mnt); + } else { + mount_buf = NULL; + vfsmount_buf = GETBUF(SIZE(vfsmount)); + } super_block_buf = GETBUF(SIZE(super_block)); for (m = 0, vfsmnt = mntlist; m < mount_cnt; m++, vfsmnt++) { - readmem(*vfsmnt, KVADDR, vfsmount_buf, SIZE(vfsmount), - "vfsmount buffer", FAULT_ON_ERROR); - - devp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_devname)); + if (VALID_STRUCT(mount)) { + readmem(*vfsmnt, KVADDR, mount_buf, SIZE(mount), + "mount buffer", FAULT_ON_ERROR); + devp = ULONG(mount_buf + OFFSET(mount_mnt_devname)); + } else { + readmem(*vfsmnt, KVADDR, vfsmount_buf, SIZE(vfsmount), + "vfsmount buffer", FAULT_ON_ERROR); + devp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_devname)); + } if (VALID_MEMBER(vfsmount_mnt_dirname)) { dirp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_dirname)); } else { - mnt_parent = ULONG(vfsmount_buf + - OFFSET(vfsmount_mnt_parent)); - dentry = ULONG(vfsmount_buf + - OFFSET(vfsmount_mnt_mountpoint)); + if (VALID_STRUCT(mount)) { + mnt_parent = ULONG(mount_buf + + OFFSET(mount_mnt_parent)); + dentry = ULONG(mount_buf + + OFFSET(mount_mnt_mountpoint)); + } else { + mnt_parent = ULONG(vfsmount_buf + + OFFSET(vfsmount_mnt_parent)); + dentry = ULONG(vfsmount_buf + + OFFSET(vfsmount_mnt_mountpoint)); + } } sbp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); @@ -1484,7 +1508,10 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex if (!one_vfsmount) FREEBUF(mntlist); - FREEBUF(vfsmount_buf); + if (VALID_STRUCT(mount)) + FREEBUF(mount_buf); + else + FREEBUF(vfsmount_buf); FREEBUF(super_block_buf); } @@ -1520,7 +1547,10 @@ get_mount_list(int *cntptr, struct task_context *namespace_context) RETURN_ON_ERROR|QUIET)) error(FATAL, "cannot determine mount list location!\n"); - ld->start = root + OFFSET(vfsmount_mnt_list); + if (VALID_STRUCT(mount)) + ld->start = root + OFFSET(mount_mnt_list); + else + ld->start = root + OFFSET(vfsmount_mnt_list); ld->end = mnt_ns + OFFSET(mnt_namespace_list); } else if (VALID_MEMBER(namespace_root)) { @@ -1538,14 +1568,19 @@ get_mount_list(int *cntptr, struct task_context *namespace_context) console("namespace: %lx => root: %lx\n", namespace, root); - ld->start = root + OFFSET(vfsmount_mnt_list); + if (VALID_STRUCT(mount)) + ld->start = root + OFFSET(mount_mnt_list); + else + ld->start = root + OFFSET(vfsmount_mnt_list); ld->end = namespace + OFFSET(namespace_list); } else error(FATAL, "cannot determine mount list location!\n"); if (VALID_MEMBER(vfsmount_mnt_list)) ld->list_head_offset = OFFSET(vfsmount_mnt_list); - else + else if (VALID_STRUCT(mount)) + ld->list_head_offset = OFFSET(mount_mnt_list); + else ld->member_offset = OFFSET(vfsmount_mnt_next); hq_open(); @@ -1566,7 +1601,7 @@ static void display_dentry_info(ulong dentry) { int m, found; - char *dentry_buf, *inode_buf, *vfsmount_buf; + char *dentry_buf, *inode_buf, *vfsmount_buf, *mount_buf; ulong inode, superblock, sb, vfs; ulong *mntlist, *vfsmnt; char pathname[BUFSIZE]; @@ -1601,12 +1636,22 @@ display_dentry_info(ulong dentry) if (VALID_MEMBER(file_f_vfsmnt)) { mntlist = get_mount_list(&mount_cnt, pid_to_context(1)); - vfsmount_buf = GETBUF(SIZE(vfsmount)); + if (VALID_STRUCT(mount)) { + mount_buf = GETBUF(SIZE(mount)); + vfsmount_buf = mount_buf + OFFSET(mount_mnt); + } else { + mount_buf = NULL; + vfsmount_buf = GETBUF(SIZE(vfsmount)); + } for (m = found = 0, vfsmnt = mntlist; m < mount_cnt; m++, vfsmnt++) { - readmem(*vfsmnt, KVADDR, vfsmount_buf, SIZE(vfsmount), - "vfsmount buffer", FAULT_ON_ERROR); + if (VALID_STRUCT(mount)) + readmem(*vfsmnt, KVADDR, mount_buf, SIZE(mount), + "mount buffer", FAULT_ON_ERROR); + else + readmem(*vfsmnt, KVADDR, vfsmount_buf, SIZE(vfsmount), + "vfsmount buffer", FAULT_ON_ERROR); sb = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (superblock && (sb == superblock)) { get_pathname(dentry, pathname, @@ -1617,21 +1662,31 @@ display_dentry_info(ulong dentry) if (!found && symbol_exists("pipe_mnt")) { get_symbol_data("pipe_mnt", sizeof(long), &vfs); - readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), - "vfsmount buffer", FAULT_ON_ERROR); + if (VALID_STRUCT(mount)) + readmem(vfs - OFFSET(mount_mnt), KVADDR, mount_buf, SIZE(mount), + "mount buffer", FAULT_ON_ERROR); + else + readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), + "vfsmount buffer", FAULT_ON_ERROR); sb = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (superblock && (sb == superblock)) { - get_pathname(dentry, pathname, BUFSIZE, 1, vfs); + get_pathname(dentry, pathname, BUFSIZE, 1, + vfs - OFFSET(mount_mnt)); found = TRUE; } } if (!found && symbol_exists("sock_mnt")) { get_symbol_data("sock_mnt", sizeof(long), &vfs); - readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), - "vfsmount buffer", FAULT_ON_ERROR); + if (VALID_STRUCT(mount)) + readmem(vfs - OFFSET(mount_mnt), KVADDR, mount_buf, SIZE(mount), + "mount buffer", FAULT_ON_ERROR); + else + readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), + "vfsmount buffer", FAULT_ON_ERROR); sb = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (superblock && (sb == superblock)) { - get_pathname(dentry, pathname, BUFSIZE, 1, vfs); + get_pathname(dentry, pathname, BUFSIZE, 1, + vfs - OFFSET(mount_mnt)); found = TRUE; } } @@ -1642,7 +1697,10 @@ display_dentry_info(ulong dentry) if (mntlist) { FREEBUF(mntlist); - FREEBUF(vfsmount_buf); + if (VALID_STRUCT(mount)) + FREEBUF(mount_buf); + else + FREEBUF(vfsmount_buf); } nopath: @@ -1897,12 +1955,26 @@ vfs_init(void) MEMBER_OFFSET_INIT(vfsmount_mnt_next, "vfsmount", "mnt_next"); MEMBER_OFFSET_INIT(vfsmount_mnt_devname, "vfsmount", "mnt_devname"); + if (INVALID_MEMBER(vfsmount_mnt_devname)) { + MEMBER_OFFSET_INIT(mount_mnt_devname, "mount", "mnt_devname"); + } MEMBER_OFFSET_INIT(vfsmount_mnt_dirname, "vfsmount", "mnt_dirname"); MEMBER_OFFSET_INIT(vfsmount_mnt_sb, "vfsmount", "mnt_sb"); MEMBER_OFFSET_INIT(vfsmount_mnt_list, "vfsmount", "mnt_list"); + if (INVALID_MEMBER(vfsmount_mnt_devname)) { + MEMBER_OFFSET_INIT(mount_mnt_list, "mount", "mnt_list"); + } MEMBER_OFFSET_INIT(vfsmount_mnt_parent, "vfsmount", "mnt_parent"); + if (INVALID_MEMBER(vfsmount_mnt_devname)) { + MEMBER_OFFSET_INIT(mount_mnt_parent, "mount", "mnt_parent"); + } MEMBER_OFFSET_INIT(vfsmount_mnt_mountpoint, "vfsmount", "mnt_mountpoint"); + if (INVALID_MEMBER(vfsmount_mnt_devname)) { + MEMBER_OFFSET_INIT(mount_mnt_mountpoint, + "mount", "mnt_mountpoint"); + } + MEMBER_OFFSET_INIT(mount_mnt, "mount", "mnt"); MEMBER_OFFSET_INIT(namespace_root, "namespace", "root"); MEMBER_OFFSET_INIT(task_struct_nsproxy, "task_struct", "nsproxy"); if (VALID_MEMBER(namespace_root)) { @@ -1939,6 +2011,7 @@ vfs_init(void) STRUCT_SIZE_INIT(fdtable, "fdtable"); STRUCT_SIZE_INIT(file, "file"); STRUCT_SIZE_INIT(inode, "inode"); + STRUCT_SIZE_INIT(mount, "mount"); STRUCT_SIZE_INIT(vfsmount, "vfsmount"); STRUCT_SIZE_INIT(fs_struct, "fs_struct"); STRUCT_SIZE_INIT(super_block, "super_block"); @@ -2226,12 +2299,16 @@ open_files_dump(ulong task, int flags, struct reference *ref) if (VALID_MEMBER(fs_struct_rootmnt)) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_rootmnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(root_dentry, root_pathname, BUFSIZE, 1, vfsmnt); } else if (use_path) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_root) + OFFSET(path_mnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(root_dentry, root_pathname, BUFSIZE, 1, vfsmnt); } else { @@ -2250,12 +2327,16 @@ open_files_dump(ulong task, int flags, struct reference *ref) if (VALID_MEMBER(fs_struct_pwdmnt)) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_pwdmnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(pwd_dentry, pwd_pathname, BUFSIZE, 1, vfsmnt); } else if (use_path) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_pwd) + OFFSET(path_mnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(pwd_dentry, pwd_pathname, BUFSIZE, 1, vfsmnt); @@ -2686,7 +2767,12 @@ file_dump(ulong file, ulong dentry, ulong inode, int fd, int flags) if (flags & DUMP_FULL_NAME) { if (VALID_MEMBER(file_f_vfsmnt)) { vfsmnt = get_root_vfsmount(file_buf); - get_pathname(dentry, pathname, BUFSIZE, 1, vfsmnt); + if (VALID_STRUCT(mount)) + get_pathname(dentry, pathname, BUFSIZE, 1, + vfsmnt - OFFSET(mount_mnt)); + else + get_pathname(dentry, pathname, BUFSIZE, 1, + vfsmnt); if (STRNEQ(pathname, "/pts/") && STREQ(vfsmount_devname(vfsmnt, buf1, BUFSIZE), "devpts")) @@ -2793,13 +2879,24 @@ get_pathname(ulong dentry, char *pathname, int length, int full, ulong vfsmnt) int d_name_len = 0; ulong d_name_name; ulong tmp_vfsmnt, mnt_parent; - char *dentry_buf, *vfsmnt_buf; + char *dentry_buf, *vfsmnt_buf, *mnt_buf; BZERO(buf, BUFSIZE); BZERO(tmpname, BUFSIZE); BZERO(pathname, length); - vfsmnt_buf = VALID_MEMBER(vfsmount_mnt_mountpoint) ? - GETBUF(SIZE(vfsmount)) : NULL; + if (VALID_STRUCT(mount)) { + if (VALID_MEMBER(mount_mnt_mountpoint)) { + mnt_buf = GETBUF(SIZE(mount)); + vfsmnt_buf = mnt_buf + OFFSET(mount_mnt); + } else { + mnt_buf = NULL; + vfsmnt_buf = NULL; + } + } else { + mnt_buf = NULL; + vfsmnt_buf = VALID_MEMBER(vfsmount_mnt_mountpoint) ? + GETBUF(SIZE(vfsmount)) : NULL; + } parent = dentry; tmp_vfsmnt = vfsmnt; @@ -2861,7 +2958,25 @@ get_pathname(ulong dentry, char *pathname, int length, int full, ulong vfsmnt) else tmp_vfsmnt = mnt_parent; } - } else { + } else if (VALID_STRUCT(mount)) { + if (tmp_vfsmnt) { + if (strncmp(pathname, "//", 2) == 0) + shift_string_left(pathname, 1); + readmem(tmp_vfsmnt, KVADDR, mnt_buf, + SIZE(mount), + "mount buffer", + FAULT_ON_ERROR); + parent = ULONG(mnt_buf + + OFFSET(mount_mnt_mountpoint)); + mnt_parent = ULONG(mnt_buf + + OFFSET(mount_mnt_parent)); + if (tmp_vfsmnt == mnt_parent) + break; + else + tmp_vfsmnt = mnt_parent; + } + } + else { parent = ULONG(dentry_buf + OFFSET(dentry_d_covers)); } @@ -2869,7 +2984,9 @@ get_pathname(ulong dentry, char *pathname, int length, int full, ulong vfsmnt) } while (tmp_dentry != parent && parent); - if (vfsmnt_buf) + if (mnt_buf) + FREEBUF(mnt_buf); + else if (vfsmnt_buf) FREEBUF(vfsmnt_buf); } @@ -3901,10 +4018,17 @@ vfsmount_devname(ulong vfsmnt, char *buf, int maxlen) BZERO(buf, maxlen); - if (!readmem(vfsmnt + OFFSET(vfsmount_mnt_devname), - KVADDR, &devp, sizeof(void *), "vfsmount mnt_devname", - QUIET|RETURN_ON_ERROR)) - return buf; + if (VALID_STRUCT(mount)) { + if (!readmem(vfsmnt - OFFSET(mount_mnt) + OFFSET(mount_mnt_devname), + KVADDR, &devp, sizeof(void *), "mount mnt_devname", + QUIET|RETURN_ON_ERROR)) + return buf; + } else { + if (!readmem(vfsmnt + OFFSET(vfsmount_mnt_devname), + KVADDR, &devp, sizeof(void *), "vfsmount mnt_devname", + QUIET|RETURN_ON_ERROR)) + return buf; + } if (read_string(devp, buf, BUFSIZE-1)) return buf; @@ -3925,10 +4049,17 @@ get_root_vfsmount(char *file_buf) return vfsmnt; if (STREQ(buf, "udev")) { - if (!readmem(vfsmnt + OFFSET(vfsmount_mnt_parent), KVADDR, - &mnt_parent, sizeof(void *), "vfsmount mnt_parent", - QUIET|RETURN_ON_ERROR)) - return vfsmnt; + if (VALID_STRUCT(mount)) { + if (!readmem(vfsmnt - OFFSET(mount_mnt) + OFFSET(mount_mnt_parent), KVADDR, + &mnt_parent, sizeof(void *), "mount mnt_parent", + QUIET|RETURN_ON_ERROR)) + return vfsmnt; + } else { + if (!readmem(vfsmnt + OFFSET(vfsmount_mnt_parent), KVADDR, + &mnt_parent, sizeof(void *), "vfsmount mnt_parent", + QUIET|RETURN_ON_ERROR)) + return vfsmnt; + } if (!strlen(vfsmount_devname(mnt_parent, buf, BUFSIZE))) return vfsmnt; diff --git a/memory.c b/memory.c index 55a184b..98cd2df 100755 --- a/memory.c +++ b/memory.c @@ -3477,6 +3477,8 @@ vm_area_dump(ulong task, ulong flag, ulong vaddr, struct reference *ref) if (VALID_MEMBER(file_f_vfsmnt)) { vfsmnt = ULONG(file_buf + OFFSET(file_f_vfsmnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(dentry, buf1, BUFSIZE, 1, vfsmnt); } else { diff --git a/symbols.c b/symbols.c index f88c016..d141f1b 100755 --- a/symbols.c +++ b/symbols.c @@ -7934,6 +7934,16 @@ dump_offset_table(char *spec, ulong makestruct) OFFSET(vfsmount_mnt_mountpoint)); fprintf(fp, " vfsmount_mnt_parent: %ld\n", OFFSET(vfsmount_mnt_parent)); + fprintf(fp, " mount_mnt_parent: %ld\n", + OFFSET(mount_mnt_parent)); + fprintf(fp, " mount_mnt_mountpoint: %ld\n", + OFFSET(mount_mnt_mountpoint)); + fprintf(fp, " mount_mnt_list: %ld\n", + OFFSET(mount_mnt_list)); + fprintf(fp, " mount_mnt_devname: %ld\n", + OFFSET(mount_mnt_devname)); + fprintf(fp, " mount_mnt: %ld\n", + OFFSET(mount_mnt)); fprintf(fp, " namespace_root: %ld\n", OFFSET(namespace_root)); fprintf(fp, " namespace_list: %ld\n", @@ -8701,6 +8711,7 @@ dump_offset_table(char *spec, ulong makestruct) fprintf(fp, " file: %ld\n", SIZE(file)); fprintf(fp, " inode: %ld\n", SIZE(inode)); fprintf(fp, " vfsmount: %ld\n", SIZE(vfsmount)); + fprintf(fp, " mount: %ld\n", SIZE(mount)); fprintf(fp, " super_block: %ld\n", SIZE(super_block)); fprintf(fp, " irqdesc: %ld\n", SIZE(irqdesc));