gethostbyname fails on OSX (Yosemite 10.10.4) - macos

"gethostbyname" returns a pointer to this structure:
struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses from name server */
};
When I try to use it, h_name points to a valid string: the partial name I supply is expanded to the correct fully qualified host name.
The value of h_addr_list is 4
h_name is valid
h_aliasis is a valid pointer to a null pointer
h_addrtype is 2 (AF_INET, IPV4)
h_length is 0 (should be 4, or perhaps a multiple of 4)
h_addr_list is 4, fails when dereferenced.
I'm running a 32 bit process (MS Office), the h_name pointer is a valid 32 bit pointer. WTF am I doing wrong? Does gethostbyname work for other people, or on other versions of OSX?

I was able to run this small example successfully on 10.10.4 (taken from paulschreiber.com)
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
int main(int argc, char **argv) {
if (argc < 2) {
printf("Usage: %s hostname", argv[0]);
exit(-1);
}
struct hostent *hp = gethostbyname(argv[1]);
if (hp == NULL) {
printf("gethostbyname() failed\n");
} else {
printf("%s = ", hp->h_name);
unsigned int i=0;
while ( hp -> h_addr_list[i] != NULL) {
printf( "%s ", inet_ntoa( *( struct in_addr*)( hp -> h_addr_list[i])));
i++;
}
printf("\n");
}
}
However, it did segfault on 64-bit without #include <arpa/inet.h: without that, no prototype for inet_ntoa is found, the return type is assumed to be an int (when it's actually a char *), and on 64-bit this truncates the pointer and causes a segfault.

Related

How to dump/list all kernel symbols with addresses from Linux kernel module?

In a kernel module, how to list all the kernel symbols with their addresses?
The kernel should not be re-compiled.
I know "cat /proc/kallsyms" in an interface, but how to get them directly from kernel data structures, using functions like kallsyms_lookup_name.
Example
Working module code:
#include <linux/module.h>
#include <linux/kallsyms.h>
static int prsyms_print_symbol(void *data, const char *namebuf,
struct module *module, unsigned long address)
{
pr_info("### %lx\t%s\n", address, namebuf);
return 0;
}
static int __init prsyms_init(void)
{
kallsyms_on_each_symbol(prsyms_print_symbol, NULL);
return 0;
}
static void __exit prsyms_exit(void)
{
}
module_init(prsyms_init);
module_exit(prsyms_exit);
MODULE_AUTHOR("Sam Protsenko");
MODULE_DESCRIPTION("Module for printing all kernel symbols");
MODULE_LICENSE("GPL");
Explanation
kernel/kallsyms.c implements /proc/kallsyms. Some of its functions are available for external usage. They are exported via EXPORT_SYMBOL_GPL() macro. Yes, your module should have GPL license to use it. Those functions are:
kallsyms_lookup_name()
kallsyms_on_each_symbol()
sprint_symbol()
sprint_symbol_no_offset()
To use those functions, include <linux/kallsyms.h> in your module. It should be mentioned that CONFIG_KALLSYMS must be enabled (=y) in your kernel configuration.
To print all the symbols you obviously have to use kallsyms_on_each_symbol() function. The documentation says next about it:
/* Call a function on each kallsyms symbol in the core kernel */
int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
unsigned long), void *data);
where fn is your callback function that should be called for each symbol found, and data is a pointer to some private data of yours (will be passed as first parameter to your callback function).
Callback function must have next signature:
int fn(void *data, const char *namebuf, struct module *module,
unsigned long address);
This function will be called for each kernel symbol with next parameters:
data: will contain pointer to your private data you passed as last argument to kallsyms_on_each_symbol()
namebuf: will contain name of current kernel symbol
module: will always be NULL, just ignore that
address: will contain address of current kernel symbol
Return value should always be 0 (on non-zero return value the iteration through symbols will be interrupted).
Supplemental
Answering the questions in your comment.
Also, is there a way to output the size of each function?
Yes, you can use sprint_symbol() function I mentioned above to do that. It will print symbol information in next format:
symbol_name+offset/size [module_name]
Example:
psmouse_poll+0x0/0x30 [psmouse]
Module name part can be omitted if symbol is built-in.
I tried the module and see the result with "dmesg". But a lot of symbols are missing such as "futex_requeue". The output symbol number is about 10K, while it is 100K when I use "nm vmlinux".
This is most likely because your printk buffer size is insufficient to store all the output of module above.
Let's improve above module a bit, so it provides symbols information via miscdevice. Also let's add function size to the output, as requested. The code as follows:
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/kallsyms.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/sizes.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#define DEVICE_NAME "prsyms2"
/* 16 MiB is sufficient to store information about approx. 200K symbols */
#define SYMBOLS_BUF_SIZE SZ_16M
struct symbols {
char *buf;
size_t pos;
};
static struct symbols symbols;
/* ---- misc char device definitions ---- */
static ssize_t prsyms2_read(struct file *file, char __user *buf, size_t count,
loff_t *pos)
{
return simple_read_from_buffer(buf, count, pos, symbols.buf,
symbols.pos);
}
static const struct file_operations prsyms2_fops = {
.owner = THIS_MODULE,
.read = prsyms2_read,
};
static struct miscdevice prsyms2_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &prsyms2_fops,
};
/* ---- module init/exit definitions ---- */
static int prsyms2_store_symbol(void *data, const char *namebuf,
struct module *module, unsigned long address)
{
struct symbols *s = data;
int count;
/* Append address of current symbol */
count = sprintf(s->buf + s->pos, "%lx\t", address);
s->pos += count;
/* Append name, offset, size and module name of current symbol */
count = sprint_symbol(s->buf + s->pos, address);
s->pos += count;
s->buf[s->pos++] = '\n';
if (s->pos >= SYMBOLS_BUF_SIZE)
return -ENOMEM;
return 0;
}
static int __init prsyms2_init(void)
{
int ret;
ret = misc_register(&prsyms2_misc);
if (ret)
return ret;
symbols.pos = 0;
symbols.buf = vmalloc(SYMBOLS_BUF_SIZE);
if (symbols.buf == NULL) {
ret = -ENOMEM;
goto err1;
}
dev_info(prsyms2_misc.this_device, "Populating symbols buffer...\n");
ret = kallsyms_on_each_symbol(prsyms2_store_symbol, &symbols);
if (ret != 0) {
ret = -EINVAL;
goto err2;
}
symbols.buf[symbols.pos] = '\0';
dev_info(prsyms2_misc.this_device, "Symbols buffer is ready!\n");
return 0;
err2:
vfree(symbols.buf);
err1:
misc_deregister(&prsyms2_misc);
return ret;
}
static void __exit prsyms2_exit(void)
{
vfree(symbols.buf);
misc_deregister(&prsyms2_misc);
}
module_init(prsyms2_init);
module_exit(prsyms2_exit);
MODULE_AUTHOR("Sam Protsenko");
MODULE_DESCRIPTION("Module for printing all kernel symbols");
MODULE_LICENSE("GPL");
And here is how to use it:
$ sudo insmod prsyms2.ko
$ sudo cat /dev/prsyms2 >symbols.txt
$ wc -l symbols.txt
$ sudo rmmod prsyms2
File symbols.txt will contain all kernel symbols (both built-in and from loaded modules) in next format:
ffffffffc01dc0d0 psmouse_poll+0x0/0x30 [psmouse]
It seems that I can use kallsyms_lookup_name() to find the address of the function, can then use a function pointer to call the function?
Yes, you can. If I recall correctly, it's called reflection. Below is an example how to do so:
typedef int (*custom_print)(const char *fmt, ...);
custom_print my_print;
my_print = (custom_print)kallsyms_lookup_name("printk");
if (my_print == 0) {
pr_err("Unable to find printk\n");
return -EINVAL;
}
my_print(KERN_INFO "### printk found!\n");

gcc using unlink and readdir, 7 days old files needs to be deleted

Using this code fetched from google.
#include <dirent.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
struct dirent *entry;
DIR *dp;
chdir("/mnt/shared");
dp = opendir(".");
while( (entry = readdir(dp)) != NULL ) {
if ( strcmp(entry->d_name, ".") &&strcmp(entry->d_name, "..") ){
unlink(entry->d_name);
}
}
}`
In this could it be possible to delete files older than 7 days from the current date?
In perl i tried as follows, but wondering this could be achived with your help?
my $now = time();
my $DATEAGE = 60*60*24*7;
for my $file (#file_list) {
my #stats = stat($file);
if ($now-$stats[9] > $DATEAGE) {
print "$file\n";}
Build the full string of the file and use several syscalls(2) (notably stat(2)) ; read Advanced Linux Programming
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
struct dirent *entry;
DIR *dp;
time_t weekago;
time(&weekago);
weekago -= 86400*7;
dp = opendir("/mnt/shared");
if (!dp) { perror("/mnt/shared"); exit(EXIT_FAILURE); };
while( (entry = readdir(dp)) != NULL ) {
if ( strcmp(entry->d_name, ".")
&& strcmp(entry->d_name, "..") ){
char buf[256];
if (snprintf(buf, sizeof(buf),
"/mnt/shared/%s", entry->d_name)
>=sizeof(buf))
{ fprintf(stderr, "too long path %s\n", buf);
exit(EXIT_FAILURE);
};
struct stat st;
if (stat(buf,&st)) {
perror(buf);
exit(EXIT_FAILURE);
};
if ((st.st_mode & S_IFMT) == S_IFREG // a plain file
&& (st.st_mtime < weekago))
{
if (remove(buf)) perror(buf);
}
}
}
My untested code above is imperfect (and not very well indented): it don't handle file paths wider than 255. But you could improve it, e.g. using asprintf(3) to build the path in heap (then you'll need to free it).
Practically speaking, use find(1). If you need to recurse in a file tree in C, use nftw(3)

CUDA constant memory issue: invalid device symbol with cudaGetSymbolAddress

I am trying to set constant values on my GPU's constant memory before launching a kernel which needs these values.
My code (simplified):
__constant__ size_t con_N;
int main()
{
size_t N;
size_t* dev_N = NULL;
cudaError_t cudaStatus;
//[...]
cudaStatus = cudaGetSymbolAddress((void **)&dev_N, &con_N);
if (cudaStatus != cudaSuccess) {
cout<<"cudaGetSymbolAddress (dev_N) failed: "<<cudaGetErrorString(cudaStatus)<<endl;
}
I planned to cudaMemcpy my N to dev_N afterwards.
However, all I get at this point in the code is:
cudaGetSymbolAddress (dev_N) failed: invalid device symbol
I'm working with CUDA 6.5 so it's not a quoted symbol issue, as it is in most of the Q&A I've been checking so far.
I tried to replace con_N with con_N[1] (and remove the & before con_N in cudaGetSymbolAddress parameters): same result.
As the prototype of this function is cudaGetSymbolAddress(void **devPtr , const void* symbol ), I guessed it wanted to be given my symbol's address. However, I tried with cudaStatus = cudaGetSymbolAddress((void **)&dev_N, (const void*) con_N); and I got the same message.
I'm also getting the very same error message when I remove cudaGetSymbolAddress((void **)&dev_N, &con_N) and go directly with cudaMemcpyToSymbol(&con_N, &N, sizeof(size_t)) instead.
I'm afraid I missed something essential. Any help will be greatly appreciated.
The correct usage of cudaGetSymbolAddress is
cudaGetSymbolAddress((void **)&dev_N, con_N)
I'm showing this with the simple example below.
As the documentation explains, the symbol should physically reside on the device. Accordingly, using &con_N in the API call appears to be meaningless, since, being cudaGetSymbolAddress a host API, accessing the address of something residing on the device directly from host should not be possible. I'm not sure if the prototype appearing in the CUDA Runtime API document should better read as `
template<class T>
cudaError_t cudaGetSymbolAddress (void **devPtr, const T symbol)
with device symbol reference instead of device symbol address.
#include <stdio.h>
__constant__ int const_symbol;
/********************/
/* CUDA ERROR CHECK */
/********************/
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
if (abort) exit(code);
}
}
/***************/
/* TEST KERNEL */
/***************/
__global__ void kernel() {
printf("Address of symbol from device = %p\n", &const_symbol);
}
/********/
/* MAIN */
/********/
int main()
{
const int N = 16;
int *pointer = NULL;
gpuErrchk(cudaGetSymbolAddress((void**)&pointer, const_symbol));
kernel<<<1,1>>>();
printf("Address of symbol from host = %p\n", pointer);
return 0;
}
In my opinion, A line of your code should be fixed like below.
cudaStatus = cudaGetSymbolAddress((void **)&dev_N, con_N);
Hope this helps you.

Retrieving VolumeDetails of WINDOWS Drives - stuck with 'char []' to 'LPCWSTR' conversion

I am trying to get the VolumeDetails of my WINDOWS system- Drive label plus its respective Volume Serial number. I've tried since an hour and built a code which gone wrong in syntax. At present I am getting the following error with it-
error C2664: 'GetVolumeInformationW' : cannot convert parameter 1 from 'char []' to 'LPCWSTR'
Here is my code:
// getVolDrive.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <direct.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <sstream>
#include <string>
#include <ctype.h>
#include <algorithm>
using namespace std;
//wchar_t mydrives[5];// = " A: ";
char mydrives[] = " A: ";
string retVolSno(char drives[]) //wchar_t drives[]
{
DWORD dwSerial;
stringstream ss;
cout<<drives<<endl;
if(!GetVolumeInformation(drives, NULL, 0, &dwSerial, NULL, NULL, NULL, 0))
{
ss<<"Error: "<<GetLastError();
}
else
{
ss<<hex<<dwSerial;
}
return ss.str();
}
int _tmain(int argc, _TCHAR* argv[])
{
string cVolSno;
ULONG DriveMask = _getdrives();
if(DriveMask == 0)
printf("_getdrives() failed with failure code: %d\n", GetLastError());
else
{
printf("This machine has the following logical drives:\n");
while (DriveMask)
{
cout << "In While" << endl;
if(DriveMask & 1)
printf("%s", mydrives);
wcout << mydrives << endl;
cVolSno = retVolSno(mydrives);
cout<<cVolSno<<endl;
++mydrives[1];
DriveMask >>= 1;
}
}
//std::transform(cVolSno.begin(), cVolSno.end(),cVolSno.begin(), ::toupper);
//cout<<cVolSno<<endl;
_getch();
return 0;
}
I've also tried replacing char with wchar_t, I didn't got any build errors, but while executing the application, got Error Code 3- Path not found!.
CODE MODIFIED:
// getVolDrive.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <direct.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <sstream>
#include <string>
#include <ctype.h>
#include <algorithm>
using namespace std;
//wchar_t mydrives[5];// = " A: ";
char mydrives[] = " A:\\\\ ";
string retVolSno(char drives[]) //wchar_t drives[]
{
DWORD dwSerial;
stringstream ss;
wchar_t text[10];
mbstowcs(text,drives,100); //strlen(drives)+1
LPWSTR ptr = text;
if(!GetVolumeInformation(ptr, NULL, 0, &dwSerial, NULL, NULL, NULL, 0))
{
ss<<"Error: "<<GetLastError();
}
else
{
ss<<hex<<dwSerial;
}
return ss.str();
}
int _tmain(int argc, _TCHAR* argv[])
{
string cVolSno;
ULONG DriveMask = _getdrives();
if(DriveMask == 0)
printf("_getdrives() failed with failure code: %d\n", GetLastError());
else
{
printf("This machine has the following logical drives:\n");
while (DriveMask)
{
if(DriveMask & 1)
printf("%s \n", mydrives);
cVolSno = retVolSno(mydrives);
std::transform(cVolSno.begin(), cVolSno.end(),cVolSno.begin(), ::toupper);
cout<<cVolSno<<endl;
++mydrives[1];
DriveMask >>= 1;
}
}
//std::transform(cVolSno.begin(), cVolSno.end(),cVolSno.begin(), ::toupper);
//cout<<cVolSno<<endl;
_getch();
return 0;
}
OUTPUT:
This machine has the following logical drives:
ERROR: 123
ERROR: 123
C:\\
ERROR: 123
D:\\
ERROR: 123
E:\\
ERROR: 123
I see at least these main issues:
1) wchar_t is the right type because you're compiling for UNICODE, you can write generic code using TCHAR macro or explicitly declare your buffer as wchar_t but that's what to do.
2) You have that error because you're passing wrong path to GetVolumeInformation() (trailing backslash is required so A: must become A:\).
Moreover please note that you have a little bit more easy way to achieve same result, you can use GetLogicalDriveStrings() to directly get a NULL delimited string list. Split it using, for example, this (don't forget UNICODE) and use c_str() with each entry.
EDIT about your modified code:
Why you drive path is A:\\ (escaped to A:\\\\)? Just one trailing backslash is needed so mydrives has to be declared as:
wchar_t mydrives[] = L"A:\\";
EDIT 2: there are more errors in your code so I'll post a reviewed version. There are more things I'd change but I'll point out just what doesn't actually work.
Function retVolSno to read volume serial number. Original version were almost right, in your modified version you perform useless character conversion. What you had to do was just to accept a wchar_t drive path.
Global variable mydrives. You actually don't need any global variable for that. It must be wchar_t and space before/after path are useless. One trailing backslash is needed. Line where you increment character value (++mydrives[0];) must be changed accordingly (index 0 instead of 1).
Check for drive availability. After if(DriveMask & 1) you did forget { then you won't print drive name but you'll perform GetVolumeInformation() even on unavailable drives (error 123). That's why indentation is important...
You're mixing UNICODE/NOT UNICODE and C/C++ stuff. I strongly suggest you pick one of them and you keep it (C or C++? UNICODE or NOT UNICODE?). For example you used C function printf() to print stuff and you have both std::string and wchar_t things.
Let's put everything together to have a working version. First the function to read serial number given drive path:
wstring getVolumeSerialNumber(const wchar_t* drivePath)
{
DWORD dwSerial;
wstringstream ss;
if (!GetVolumeInformation(drivePath, NULL, 0, &dwSerial, NULL, NULL, NULL, 0))
ss << L"Error: " << GetLastError();
else
ss << hex << dwSerial;
return ss.str();
}
It's almost the same as your original version, just changed to work with UNICODE characters. Then main function that cycles through available drives and print out their serial number:
int _tmain(int argc, _TCHAR* argv[])
{
wchar_t drive[] = L"A:\\";
ULONG driveMask = _getdrives();
if (driveMask == 0)
wcout << L"_getdrives() failed with failure code: " << GetLastError() << endl;
else
{
wcout << L"This machine has the following logical drives:" << endl;
while (driveMask)
{
if (driveMask & 1)
{
wcout << drive << endl;
wcout << getVolumeSerialNumber(drive) << endl;
}
++drive[0];
driveMask >>= 1;
}
}
wcin.ignore();
return 0;
}
From the documentation , the first parameters should be with trailing slash if drive letter is passed.
lpRootPathName [in, optional]
A pointer to a string that contains the root directory of the volume to be described.
If this parameter is NULL, the root of the current directory is used.
A trailing backslash is required.
For example, you specify \\MyServer\MyShare as \\MyServer\MyShare\, or the C drive as C:\

Getting process base address in Mac OSX

I'm trying to read the memory of a process using task_for_pid / vm_read.
uint32_t sz;
pointer_t buf;
task_t task;
pid_t pid = 9484;
kern_return_t error = task_for_pid(current_task(), pid, &task);
vm_read(task, 0x10e448000, 2048, &buf, &sz);
In this case I read the first 2048 bytes.
This works when I know the base address of the process (which I can find out using gdb "info shared" - in this case 0x10e448000), but how do I find out the base address at runtime (without looking at it with gdb)?
Answering my own question. I was able to get the base address using mach_vm_region_recurse like below. The offset lands in vmoffset. If there is another way that is more "right" - don't hesitate to comment!
#include <stdio.h>
#include <mach/mach_init.h>
#include <sys/sysctl.h>
#include <mach/mach_vm.h>
...
mach_port_name_t task;
vm_map_offset_t vmoffset;
vm_map_size_t vmsize;
uint32_t nesting_depth = 0;
struct vm_region_submap_info_64 vbr;
mach_msg_type_number_t vbrcount = 16;
kern_return_t kr;
if ((kr = mach_vm_region_recurse(task, &vmoffset, &vmsize,
&nesting_depth,
(vm_region_recurse_info_t)&vbr,
&vbrcount)) != KERN_SUCCESS)
{
printf("FAIL");
}
Since you're calling current_task(), I assume you're aiming at your own process at runtime. So the base address you mentioned should be the dynamic base address, i.e. static base address + image slide caused by ASLR, right? Based on this assumption, you can use "Section and Segment Accessors" to get the static base address of your process, and then use the dyld functions to get the image slide. Here's a snippet:
#import <Foundation/Foundation.h>
#include </usr/include/mach-o/getsect.h>
#include <stdio.h>
#include </usr/include/mach-o/dyld.h>
#include <string.h>
uint64_t StaticBaseAddress(void)
{
const struct segment_command_64* command = getsegbyname("__TEXT");
uint64_t addr = command->vmaddr;
return addr;
}
intptr_t ImageSlide(void)
{
char path[1024];
uint32_t size = sizeof(path);
if (_NSGetExecutablePath(path, &size) != 0) return -1;
for (uint32_t i = 0; i < _dyld_image_count(); i++)
{
if (strcmp(_dyld_get_image_name(i), path) == 0)
return _dyld_get_image_vmaddr_slide(i);
}
return 0;
}
uint64_t DynamicBaseAddress(void)
{
return StaticBaseAddress() + ImageSlide();
}
int main (int argc, const char *argv[])
{
printf("dynamic base address (%0llx) = static base address (%0llx) + image slide (%0lx)\n", DynamicBaseAddress(), StaticBaseAddress(), ImageSlide());
while (1) {}; // you can attach to this process via gdb/lldb to view the base address now :)
return 0;
}
Hope it helps!

Resources