From owner-freebsd-hackers@FreeBSD.ORG Thu Mar 22 20:11:10 2012 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 6B65C1065673 for ; Thu, 22 Mar 2012 20:11:10 +0000 (UTC) (envelope-from eric.saintetienne@gmail.com) Received: from mail-yx0-f182.google.com (mail-yx0-f182.google.com [209.85.213.182]) by mx1.freebsd.org (Postfix) with ESMTP id 2372F8FC15 for ; Thu, 22 Mar 2012 20:11:09 +0000 (UTC) Received: by yenl9 with SMTP id l9so2617024yen.13 for ; Thu, 22 Mar 2012 13:11:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=Kum5JQox+Xze9zc+NNfKu7IK9AAHYmqhmKe01qhqsW4=; b=HvLmX//7elSo8VfuJgIs4osKFmxK9gczYTPIu/xmTisBHEMFqy7lI0nJJOVAdEaKLP j51R6DLoDja6dkKpunXMt3CXERHWOjpLJcnDHccICTUpyr15TSS73NQnXQQJXoZJ1drq DlJ1Oavxnc6nmUO36b2EMei9DIR38yi3hh1JhtmNCr7Ft5EZRP2hgfdnCIoFIQ3kx/Vi FILROIhF85BYSIEznGYzUkbg320Fv8e/Ll+rGq7pbSfJf28ASed42l8AWuPb8/K8VN7l fDWDp8QVxeY5ehi/NVeI90UNKmeKCwplTLguJsYMCoj6F5ORw5v5BFAGfLui6U3rYiU7 lrqQ== Received: by 10.68.237.1 with SMTP id uy1mr8203533pbc.151.1332447069224; Thu, 22 Mar 2012 13:11:09 -0700 (PDT) MIME-Version: 1.0 Received: by 10.68.47.129 with HTTP; Thu, 22 Mar 2012 13:10:39 -0700 (PDT) In-Reply-To: References: From: Eric Saint-Etienne Date: Thu, 22 Mar 2012 20:10:39 +0000 Message-ID: To: Ryan Stone Content-Type: text/plain; charset=UTF-8 Cc: freebsd-hackers@freebsd.org Subject: Re: malloc pages map to user space X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Mar 2012 20:11:10 -0000 Here is some code which fails with malloc < 1 page and sometimes succeeds with large mallocs (> 16 pages) What's wrong? #include #include #include #include #include #include #include #include #include // Copyright: skeleton took from an older post on the freebsd list #include #include #include #include #include #include #include #include MALLOC_DEFINE(M_FIVEG_SYSC, "fiveg_sysc", "fiveg_sysc test"); struct args { unsigned char **p; }; /* String to be located in maped buffer */ #define SIZE PAGE_SIZE // 1 page always fail static void initialize_array(char *p) { int i; for (i = 0; i < 26; i++) p[i] = i+'a'; p[26] = '!'; p[27] = '\0'; } static vm_offset_t addr; // allocated/freed at module load/unload /* Syscall func */ static int syscf(struct thread *td, void *sa) { vm_offset_t user_addr; /* User space address */ struct args *uap = (struct args*) sa; struct proc *procp = (struct proc *)td->td_proc; struct vmspace *vms = procp->p_vmspace; vm_map_t map; int result; vm_object_t object; vm_ooffset_t objoffset; vm_map_entry_t entry; vm_pindex_t pindex; vm_prot_t prot; boolean_t wired; map = kernel_map; // it always return data within kmeme anyway uprintf("KERNEL string is '%s' (%p)\n", (char*) addr, (void*) addr); result = vm_map_lookup(&map, addr, VM_PROT_ALL, &entry, &object, &pindex, &prot, &wired); if (result != KERN_SUCCESS) { uprintf("KERNEL vm_map_lookup failed (%d)\n", result); return ENOMEM; } vm_map_lookup_done(map, entry); if (object == kernel_object) uprintf("object is kernel_object\n"); else if (object == kmem_object) uprintf("object is kmem_object\n"); else uprintf("object=%p (not kmem, not kernel)\n", object); uprintf("entry=%p\n", entry); /* Offset in vm_object */ objoffset = addr - entry->start + entry->offset; user_addr = 0; result = vm_map_find(&vms->vm_map, object, objoffset, (vm_offset_t *) &user_addr, SIZE, VMFS_ANY_SPACE, VM_PROT_RW, VM_PROT_RW, 0); if (result != KERN_SUCCESS) uprintf("vm_map_find failed: %d\n", result); else { *uap->p = (char*) user_addr; uprintf("KERNEL ---> Syscall: user_addr for allocating space = 0x%lx\n", user_addr); } return result; } /* Sysent entity for syscall */ static struct sysent sc_sysent = { 1, /* Number of arguments */ syscf /* Syscall function */ }; //static struct sysent *old_sysent; /* Offset in sysent[] */ static int offset = NO_SYSCALL; /* Loader */ static int load (struct module *m, int cmd, void *something) { int error = 0; switch(cmd){ case MOD_LOAD: //MALLOC(addr, vm_offset_t, SIZE, M_FIVEG_SYSC, M_WAITOK | M_ZERO); addr = (vm_offset_t) malloc(SIZE, M_FIVEG_SYSC, M_WAITOK); initialize_array((char*) addr); uprintf("KERNEL Module with sysc loaded. Offset = %d \n", offset); break; case MOD_UNLOAD: free((void*) addr, M_FIVEG_SYSC); uprintf("KERNEL Module with sysc unloaded. Offset = %d \n", offset); break; default: error = EOPNOTSUPP; break; } return (error); /* Syscall macro*/ SYSCALL_MODULE(fiveg_sysc, &offset, &sc_sysent, load, NULL); /* eof */ ------------------------------------------------ -- USERLAND PROGRAM ------------------------------------------------ #include #include #include #include #include #include int main(int argc, char *argv[]) { int sysc_num, error; struct module_stat mstat; /* This Variable will save the addres of remapped buffer */ unsigned char *some_var = NULL; /* Pointer to pointer to remapped buffer */ unsigned char **p = &some_var; /* Search module with system call */ mstat.version = sizeof(mstat); if (!(modstat(modfind("sys/fiveg_sysc"), &mstat))){ /* Our module */ sysc_num = mstat.data.intval; printf("USER: Module found, Syscall number = %d \n", sysc_num); /* make system call */ error = syscall(sysc_num, p); if (error != 0) { printf("USER: an error occured: %d\n", error); return -1; } /* Read the string from remapped buffer */ printf("USER: p = %p\n", p); printf("USER: *p = %p\n", *p); printf("USER: String = %s\n", *p); } else printf("USER: Module seems to be not loaded! \n"); return 0; } /* eof */