Re: Kernel Panic while trying to access the datastructure parameter in ioctl call.
site_archiver@lists.apple.com Delivered-To: Darwin-dev@lists.apple.com if (!ctl) { return -1; } - Pointers interior to the ioctl structure are your responsibility. So what could have gone wrong? if ((ctl->dptr) ) { Per the above, the most likely fix is to: (1) use allocated memory instead of a 2K stack buffer (2) check you length argument to ensure that it is > 0 and < 2k -- Terry _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.appl... On Jul 18, 2007, at 11:40 AM, JanakiRam wrote: The problem is the kernel panic is comming up when i try to access the data in kernel function. int ioctl_functionpointer(dev_t dev, u_long cmd, caddr_t arg,int fflag, struct proc *p) { IOCTL_Struct_t*ctl = (PF_Ctl_t*)arg; char data[2048]; if ((ctl->dptr) ) { int res = copyin((void *)ctl->dptr, (void *)data, ctl->bytes); if (res != 0) printf ("error in copyin"); } return 0; } If i comment the line copyin function call , then its working fine. Then the problem is one of you declaring the ioctl argument incorrectly, or alignment/packing, or your pointer is bogus, or your length is bogus, or that your copyin() call is happening in a process context different from the process context in which the original ioctl structure was supplied. The way ioctl works is by allocating memory at the BSD layer, and copying in the argument structure (if any; you must specify either _IOW or _IOWR for the copyin to take place) into that allocated region in kernel space, and then passing the address of that around. It knows the length of this structure by virtue of the declaration of the ioctl; there is a bit field breakdown of the ioctl's numberic namespace that is used for this, which is declared in <sys/ioccom.h>, which everyone who declares an ioctl themselves must use. When the call completes, if the call was successful (no error), AND _IOR or _IOWR was specified, then the contents of that structure are copied back out to user space, and the ioctl returns. (1) If you declared the ioctl argument incorrectly, then the copied in data could be short or incomplete. The fact that the: didn't panic on its own only means that the allocated memory area was either (a) large enough, or (b) that it was allocated adjacent to an already allocated region, so the pointer dereference didn't end up failing. You could still have failed to include 'W' in the _IO declaration, which means the data never made it in from user space, and the only thing in the buffer is stack garbage. (2) If you structure alignment or packing is different in kernel space than in user space (which it could be, because you didn't explicitly use a #pragma or __attribute__ to pack your structure), then the structure you are dereferencing may not have it's fields aligned with the structure that user space filled out. So the field you think you are getting may be overlaid with some other field(s) in the structure, and you are getting garbage. (3) If you fill out a bogus pointer in the structure in user space, then the area you are attempting to copy in may in fact be garbage or not in the user address space; this should not result in a panic, however, and what should happen is EFAULT (or in the case of copyinstr, perhaps ENAMETOOLONG, if there is no NULL termination. (4) The most likely cause is that your length is bogus; I notice that your buffer "data" (which should not be a stack buffer, it should be allocated!) is 2K in size, but you don't do anything to ensure that your count "bytes" is > 0 and less than 2K, so you could easily be overflowing the buffer. Another possibility is that, since 2K is a heck of a lot of data in kernel terms (1/8th of your entire available stack!!!), you could be trashing the kernel stack, resulting in the panic (this is less likely than simply having a bogus length and smashing your own stack, but it's a possibility). (5) Finally, if you are using a worker thread to do the work instead of doing it in the context of the process making the call (you should know whether or not you are using one - in fact, you should have told us this when you asked the question...), then it's trying to copy in from kernel_process, which is the wrong process to copy in from. Basically, all copies in or out MUST occur in the context of the process requesting the copy. I've tried to use the copyinstr instead of copyin , then also its showing panic screen. Please help me to solve this. This email sent to site_archiver@lists.apple.com
participants (1)
-
Terry Lambert