In 8-stable, WITH_CTF=1 configure item is enabled in command line, not in make.conf, so when I build kernel module out of /usr/src source tree, such as x11/nvidia-driver, I forgot to use WITH_CTF=1 and nvidia.ko was built without .SUNW_ctf section. However, when I run: #dtrace -lv trigger the NULL pointer dereference at: /usr/src/sys/cddl/dev/fbt/fbt.c > .......................................... > if (*lc.ctfoffp == NULL) { // page fault here > /* > * Initialise the CTF object and function symindx to > * byte offset array. > */ > if (fbt_ctfoff_init(ctl, &lc) != 0) > return; > > /* Initialise the CTF type to byte offset array. */ > if (fbt_typoff_init(&lc) != 0) > return; > } > ........................................................................ the reason is at /usr/src/sys/kern/kern_ctf.c: ................................................................................ ...... /* Search for the section containing the CTF data. */ for (i = 0; i < hdr->e_shnum; i++) if (strcmp(".SUNW_ctf", shstrtab + shdr[i].sh_name) == 0) break; /* Check if the CTF section wasn't found. */ if (i >= hdr->e_shnum) //here we found no ctf data, but NOT update the varible "error" goto out; // see label out /* Read the CTF header. */ if ((error = vn_rdwr(UIO_READ, nd.ni_vp, ctf_hdr, sizeof(ctf_hdr), shdr[i].sh_offset, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid, td)) != 0) goto out; /* Check the CTF magic number. (XXX check for big endian!) */ if (ctf_hdr[0] != 0xf1 || ctf_hdr[1] != 0xcf) goto out; /* Check if version 2. */ if (ctf_hdr[2] != 2) goto out; /* Check if the data is compressed. */ if ((ctf_hdr[3] & 0x1) != 0) { uint32_t *u32 = (uint32_t *) ctf_hdr; /* * The last two fields in the CTF header are the offset * from the end of the header to the start of the string * data and the length of that string data. se this * information to determine the decompressed CTF data * buffer required. */ sz = u32[CTF_HDR_STRTAB_U32] + u32[CTF_HDR_STRLEN_U32] + sizeof(ctf_hdr); /* * Allocate memory for the compressed CTF data, including * the header (which isn't compressed). */ if ((raw = malloc(shdr[i].sh_size, M_LINKER, M_WAITOK)) == NULL) { error = ENOMEM; goto out; } } else { /* * The CTF data is not compressed, so the ELF section * size is the same as the buffer size required. */ sz = shdr[i].sh_size; } /* * Allocate memory to buffer the CTF data in it's decompressed * form. */ if ((ctftab = malloc(sz, M_LINKER, M_WAITOK)) == NULL) { error = ENOMEM; goto out; } /* * Read the CTF data into the raw buffer if compressed, or * directly into the CTF buffer otherwise. */ if ((error = vn_rdwr(UIO_READ, nd.ni_vp, raw == NULL ? ctftab : raw, shdr[i].sh_size, shdr[i].sh_offset, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid, td)) != 0) goto out; /* Check if decompression is required. */ if (raw != NULL) { z_stream zs; int ret; /* * The header isn't compressed, so copy that into the * CTF buffer first. */ bcopy(ctf_hdr, ctftab, sizeof(ctf_hdr)); /* Initialise the zlib structure. */ bzero(&zs, sizeof(zs)); zs.zalloc = z_alloc; zs.zfree = z_free; if (inflateInit(&zs) != Z_OK) { error = EIO; goto out; } zs.avail_in = shdr[i].sh_size - sizeof(ctf_hdr); zs.next_in = ((uint8_t *) raw) + sizeof(ctf_hdr); zs.avail_out = sz - sizeof(ctf_hdr); zs.next_out = ((uint8_t *) ctftab) + sizeof(ctf_hdr); if ((ret = inflate(&zs, Z_FINISH)) != Z_STREAM_END) { printf("%s(%d): zlib inflate returned %d\n", __func__, __LINE__, ret); error = EIO; goto out; } } /* Got the CTF data! */ ef->ctftab = ctftab; ef->ctfcnt = shdr[i].sh_size; /* We'll retain the memory allocated for the CTF data. */ ctftab = NULL; /* Let the caller use the CTF data read. */ lc->ctftab = ef->ctftab; lc->ctfcnt = ef->ctfcnt; lc->symtab = ef->ddbsymtab; lc->strtab = ef->ddbstrtab; lc->strcnt = ef->ddbstrcnt; lc->nsym = ef->ddbsymcnt; lc->ctfoffp = (uint32_t **) &ef->ctfoff; lc->typoffp = (uint32_t **) &ef->typoff; lc->typlenp = &ef->typlen; out: // here error is 0, but we encounter an ERROR and // lc->ctfoffp is NULL VOP_UNLOCK(nd.ni_vp, 0); vn_close(nd.ni_vp, FREAD, td->td_ucred, td); VFS_UNLOCK_GIANT(vfslocked); if (hdr != NULL) free(hdr, M_LINKER); if (shdr != NULL) free(shdr, M_LINKER); if (shstrtab != NULL) free(shstrtab, M_LINKER); if (ctftab != NULL) free(ctftab, M_LINKER); if (raw != NULL) free(raw, M_LINKER); #else error = EOPNOTSUPP; #endif return (error); } Here is patch to fix the missing check .............................................................................................................................. diff --git a/sys/kern/kern_ctf.c b/sys/kern/kern_ctf.c index 758ad81..b78e474 100644 --- a/sys/kern/kern_ctf.c +++ b/sys/kern/kern_ctf.c _at__at_ -164,8 +164,12 _at__at_ link_elf_ctf_get(linker_file_t lf, linker_ctf_t *lc) * section names aren't present, then we can't locate the * .SUNW_ctf section containing the CTF data. */ - if (hdr->e_shstrndx == 0 || shdr[hdr->e_shstrndx].sh_type != SHT_STRTAB) + if (hdr->e_shstrndx == 0 || shdr[hdr->e_shstrndx].sh_type != SHT_STRTAB) { + + printf("%s(%d):e_shstrndx is %d, sh_type is %d\n", lf->pathname, __LINE__, + hdr->e_shstrndx, shdr[hdr->e_shstrndx].sh_type); goto out; + } /* Allocate memory to buffer the section header strings. */ if ((shstrtab = malloc(shdr[hdr->e_shstrndx].sh_size, M_LINKER, _at__at_ -187,8 +191,12 _at__at_ link_elf_ctf_get(linker_file_t lf, linker_ctf_t *lc) break; /* Check if the CTF section wasn't found. */ - if (i >= hdr->e_shnum) + if (i >= hdr->e_shnum) { + error = EFTYPE; + printf("%s(%d): module %s has no .SUNW_ctf section\n", __func__, + __LINE__, lf->pathname); goto out; + } /* Read the CTF header. */ if ((error = vn_rdwr(UIO_READ, nd.ni_vp, ctf_hdr, sizeof(ctf_hdr), _at__at_ -197,12 +205,20 _at__at_ link_elf_ctf_get(linker_file_t lf, linker_ctf_t *lc) goto out; /* Check the CTF magic number. (XXX check for big endian!) */ - if (ctf_hdr[0] != 0xf1 || ctf_hdr[1] != 0xcf) + if (ctf_hdr[0] != 0xf1 || ctf_hdr[1] != 0xcf) { + error = EFTYPE; + printf("%s(%d): module %s has wrong format\n", __func__, __LINE__, + lf->pathname); goto out; + } /* Check if version 2. */ - if (ctf_hdr[2] != 2) + if (ctf_hdr[2] != 2) { + error = EFTYPE; + printf("%s(%d): module %s CTF format version is %d\n", __func__, __LINE__, + lf->pathname, ctf_hdr[2]); goto out; + } /* Check if the data is compressed. */ if ((ctf_hdr[3] & 0x1) != 0) { ......................................................................................................................... 2011/9/26 Paul Ambrose <ambrosehua_at_gmail.com> > Hi, Ryan, I came across the similar problem on 8-stable when I run > # dtrace -lv > the panic message says: > page fault just happened at fbt.c > ........................................................................ > if (*lc.ctfoffp == NULL) { // page fault > /* > * Initialise the CTF object and function symindx to > * byte offset array. > */ > if (fbt_ctfoff_init(ctl, &lc) != 0) > return; > > /* Initialise the CTF type to byte offset array. */ > if (fbt_typoff_init(&lc) != 0) > return; > } > ........................................................................ > > And I came across the similar problem on 9-current only once, but when I > recompile the kernel, > it does not reproduce. I will try your patch on 8-stable, but could you > tell me where did you meet > the problem, and what is your module without CTF data? >Received on Thu Sep 29 2011 - 10:37:36 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:18 UTC