DF-3164 / trigger.c
/* DF-3164 trigger -- failed MNT_UPDATE of a live UDF mount. * * Calls mount(2) directly with MNT_UPDATE and a NEW fspec (/dev/vn1, * a device holding garbage). udf_mount() falls through to udf_mountfs() * (udf_vfsops.c:153-157 -> 186), which clobbers mp->mnt_data (:265) and * then fails at the anchor checktag (:283) -> bail frees the new udfmp * without restoring mp->mnt_data (:393-403). sys_mount's update-failure * path (vfs_syscalls.c:408-419) keeps the mount alive with the dangling * pointer. * * Layout mirrors sys/vfs/udf/udf_mount.h. */ #include <sys/param.h> #include <sys/mount.h> #include <errno.h> #include <stdio.h> #include <string.h> #include <stdlib.h> struct udf_args_df { char *fspec; struct export_args export; int flags; }; int main(int argc, char **argv) { struct udf_args_df args; const char *spec = argc > 1 ? argv[1] : "/dev/vn1"; const char *node = argc > 2 ? argv[2] : "/mnt"; int rc; memset(&args, 0, sizeof(args)); args.fspec = strdup(spec); rc = mount("udf", node, MNT_RDONLY | MNT_UPDATE, &args); printf("mount(\"udf\", \"%s\", MNT_RDONLY|MNT_UPDATE, fspec=\"%s\")" " = %d errno=%d (%s)\n", node, spec, rc, rc == -1 ? errno : 0, rc == -1 ? strerror(errno) : "OK"); if (rc == 0) fprintf(stderr, "UNEXPECTED SUCCESS (remounted)\n"); return (rc == -1 ? 0 : 1); } |