CFStreamCreatePairWithSocketToCFHost CFStreamCreatePairWithSocketToHost and allocations - ios

Can some one please give me the difference between CFStreamCreatePairWithSocketToCFHost and CFStreamCreatePairWithSocketToHost calls.
Also what is a CFAllocator and what is the meaning if that is NULL or kCFAllocatorDefault. Since its a kCFAllocatorDefault is a const can someone explain the beleifits of kCFAllocatorDefault or is it the for historical purposes only?

The difference between CFStreamCreatePairWithSocketToCFHost and CFStreamCreatePairWithSocketToHost is simply the way the address is passed in.
In CFStreamCreatePairWithSocketToHost, you can simply define a CFStringRef (or NSString) to represent the domain / ip of the host.
With the CFHost version, however, it gives you control over the address via the sockaddr_in struct, defined in <netinet/in.h>. You create a CFHostRef in a manner similar to the following:
struct sockaddr_in ip4addr; // note that this only works for ipv4, for ipv6 you need struct sockaddr_in6.
ip4addr.sin_family = AF_INET;
ip4addr.sin_port = htons(3490);
inet_pton(AF_INET, "10.0.0.1", &ip4addr.sin_addr);
CFDataRef sockData = CFDataCreate(NULL, &ip4addr, sizeof(ip4addr));
CFHostRef host = CFHostCreateWithAddress(NULL, sockData);
// use 'host' to create your stream
CFRelease(host);
CFRelease(sockData);
This gives you some (mostly unnecessary) control over what you do with the socket itself, for most situations, the CFHost version is not necessary.
For CFAllocator's, once again, the documentation is your friend. It is used as CoreFoundation's way for debugging malloc, free, and realloc calls throughout the code.
It is an object that allows you to write your own methods for allocating memory for an object, and kCFAllocatorDefault uses the standard malloc, free, and realloc calls used by the system. Passing NULL for a CFAllocator works exactly the same as kCFAllocatorDefault, the code just uses the system calls.

Related

OBJ-C wipe NSData content before nullifying it

For security reasons we need Always to wipe sensitive data from memory.
Usually it is not something that i see done in IOS but for apps and need extended security it is very important.
The Data that Usually needs to be wiped if NSData and NSString objects (pointing to nil does not wipe the data and it is a security breach)
I've managed to wipe my NSStrings with the code below (When password is NSString):
unsigned char *charPass;
if (password != nil) {
charPass = (unsigned char*) CFStringGetCStringPtr((CFStringRef) password, CFStringGetSystemEncoding());
memset(charPass, 0, [password length]);
password = nil;
}
Big remark on this implementation: You HAVE to check for NULL before calling the charPass or it might crash. There is NO guarantee that CFStringGetCStringPtr will return a value!
When password is NSData It suppose to be even more strait forward and the code bellow suppose to work:
memset([password bytes], 0, [password length]);
But this gives me a compilation error:
No matching function for call to 'memset'
I can't find a workaround to point to the password address and wipe the bytes over there like I did with the string (bytes method should let me do just that from what I understand but it doesn't compile for some reason that I cant figure out)
Any one has an idea for this?
10x
Your string deallocator is fragile. You write:
Big remark on this implementation: You HAVE to check for NULL before calling the charPass or it might crash. There is NO guarantee that CFStringGetCStringPtr will return a value!
This is documented behaviour as CFString (and hence NSString) does not guarantee you direct access to its internal buffer. You don't say what how you handle this situation, but if you don't erase the memory you presumably have a security problem.
In the case you do get a valid pointer back you are using the wrong byte count. The call [password length] returns:
The number of UTF-16 code units in the receiver.
which is not the same as the number of bytes. However CFStringGetCStringPtr returns:
A pointer to a C string or NULL if the internal storage of theString does not allow this to be returned efficiently.
If you have a C string you can use C library function strlen() to find its length.
To address the case when CFStringGetCStringPtr returns NULL you could create the string yourself as a CFString and supply a custom CFAllocater. You shouldn't need to write a complete allocator yourself, instead you could build one based on the system one. You can get the default allocators CFAllocatorContext which will return you the function pointers the system uses. You can then create a new CFAllocator based of a CFAllocatorContext which is a copy of the default one except you've changed the deallocate and reallocate pointers to functions which you have implemented in terms of the default allocate, reallocate and deallocate but also call memset appropriately to clear out memory.
Once you've done that doing your security wipe comes down to making sure these custom created CFString objects, aka NSString objects, are deallocated before your app quits.
You can find out about CFAllocator, CFAllocatorContext etc. in Memory Management Programming Guide for Core Foundation.
Which brings us to your actual question, how to zero an NSData. Here you are in luck an NSData object is a CFData object, and CFData's CFDataGetBytePtr, unlike CFStringGetCStringPtr, is guaranteed to return a pointer to the actual bytes, straight from the documentation:
This function is guaranteed to return a pointer to a CFData object's internal bytes. CFData, unlike CFString, does not hide its internal storage.
So code following your pattern for CFString will work here. Note that using NSData's bytes is not guaranteed in the documentation to call CFDataGetBytePtr, it could for example call CFDataGetBytes and return a copy of the bytes, use the CFData functions.
HTH
While I cannot speak for the actual safety of doing this, your problem is that NSData's bytes method returns a const void *
https://developer.apple.com/documentation/foundation/nsdata/1410616-bytes?language=objc
You can cast it to a void * if you want by
memset((void *)[password bytes], 0, [password length]);
If you use a NSMutableData, you won't have to do this.

NativeScript: Get string from interop.reference

To start, here is my code:
var buffer = malloc(interop.sizeof(interop.types.UTF8CString));
var fillBuffer = mac.getBytes(buffer);
var bytes = new interop.Reference(interop.types.UTF8CString, buffer);
var hexMac = bytes[0];
The variable 'Mac' is an NSData objected retrieved from CoreBluetooth. It is the scan response from a BLE device, which contains the peripheral's MAC address (00:0b:57:a2:fb:a0).
This problem is linked to THIS question I had posted earlier.
The solution provided is great; however, I cannot seem to implement this in nativescript :
(instancetype)stringWithFormat:(NSString *)format, ...;
Intellisense tells me the method doesnt exist on type NSString.
Due to that issue, I decided to go another route (as you can tell). I am filling a buffer with the bytes of the MAC address. In the code above, bytes[0] equates to 0xb57a2fba0.
I am now trying to convert that (which is an interop.Reference) into a string that I can store on the back-end (preferably in the xx:xx:xx:xx:xx format).
I have been at this all weekend, and cannot seem to find a solution. I even broke down objc!foundation.d.ts to figure out if stringWithFormat was supported, to no avail.
The nativescript community slack was unable to provide a resolution as well.
Please help if you can!
I don't know anything about NativeScript at all, but given the other code you wrote, I assume you're calling +alloc first, and so mean to use -initWithFormat: (an instance method that initializes) rather than +stringWithFormat: (a class method which handles allocation and initialization).

Does CFHostGetAddressing() support ipv6 DNS entries?

I am trying to use CFHostGetAddressing to do a simple DNS lookup. However, I notice that it returns an array of sockaddr structs, which I guess means it can only do IPV4.
Is there a way to support DNS entries with IPV6 addresses in iOS? Perhaps a similar API that returns an array of sockaddr_storage structs?
The CFHostGetAddressing() documentation might be misleading, because struct sockaddr
is a structure that covers all the common elements of the various socket addresses (IPv4, IPv6, ...). It is usually only used to pass a generic pointer to the socket functions.
Actually CFHostGetAddressing() works well with IPv6. It returns an array of CFData elements where each element contains a struct sockaddr_in or a struct sockaddr_in6.
Using the code from your previous question as a starting point, the following should work:
let hostRef = CFHostCreateWithName(kCFAllocatorDefault, "localhost").takeRetainedValue()
var resolved = CFHostStartInfoResolution(hostRef, CFHostInfoType.Addresses, nil)
let addresses = CFHostGetAddressing(hostRef, &resolved).takeRetainedValue() as NSArray
for addr in addresses as [NSData] {
var sockaddr = UnsafePointer<sockaddr_storage>.alloc(1)
addr.getBytes(sockaddr, length: sizeof(sockaddr_storage))
// ...
sockaddr.destroy()
}

How to trigger a DMA operation on PCI sound card

I'm a newbie to driver development in Linux. I want to trigger a DMA read operation at specified target address, but I have no basic concept about how to do it. Should I write a new driver for my sound card? Or just invoke some APIs(if any) provided by current sound card driver?
I can imagine that what I want looks like this (from LDD3 Ch15),
int dad_transfer(struct dad_dev *dev, int write, void *buffer,
size_t count)
{
dma_addr_t bus_addr;
/* Map the buffer for DMA */
dev->dma_dir = (write ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
dev->dma_size = count;
bus_addr = dma_map_single(&dev->pci_dev->dev, buffer, count,
dev->dma_dir);
dev->dma_addr = bus_addr;
/* Set up the device */
writeb(dev->registers.command, DAD_CMD_DISABLEDMA);
writeb(dev->registers.command, write ? DAD_CMD_WR : DAD_CMD_RD);
writel(dev->registers.addr, cpu_to_le32(bus_addr));
writel(dev->registers.len, cpu_to_le32(count));
/* Start the operation */
writeb(dev->registers.command, DAD_CMD_ENABLEDMA);
return 0;
}
But what should this be, a user-space program or a module? And where can I grub more device-specific details in order to know which and how the registers should be write?
You have several questions buried in here, so I will take them one at a time:
Should I write a new driver or invoke some API function calls?
If the existing driver has such a function accessible from userspace, yes you should use them - they will the easiest option. If they do not already exist, you will have to write a driver because you cannot directly access the kernel's DMA engine from userspace. You need a driver to help you along.
Should this be a userspace program or module?
It would have to be a module so that it can access low-level kernel features. Using your included code as an example, you cannot call "dma_map_single" from userspace or access a PCI device's device structure. You need to be in kernel space to do that, which requires either a driver module or static kernel driver.
Where can I get more device-specific details?
(I assume you meant Grep.) You will have to get a hold of a programmer's guide for the device you want to access. Regular user's manuals won't have the level of detail you need (register addresses, bit patterns, etc) so you may have to contact the manufacturer to get a driver writer's guide. You also may be able to find some examples in the kernel source code. Check http://lxr.free-electrons.com/ for a searchable, up-to-date listing of the entire kernel source. If you look in /drivers/, you may be able to find some examples to get you started.

Difference between writing data in memory directly and using asm instruction

I am reading the Linux kernel. I am curious about the way to write data in memory.
In some part of drivers, they use the writel() function defined in asm/io.h and in definition of that function, they use the movnti instruction - actually I don't understand what this instruction means except it is a kind of mov instruction.
Anyway, when writing data in memory, what's the difference between using writel() and directly writing in memory, e.g. **address = data;.
Here is the case:
static inline void __writel(__u32 val, volatile void __iomem *addr)
{
volatile __u32 __iomem *target = addr;
asm volatile("movnti %1,%0"
: "=m" (*target)
: "r" (val) : "memory");
}
and this is another case:
*(unsigned int*)(MappedAddr+pageOffset) = result;
writel looks like it's intended for memory mapped IO, there are a few things to support this, first the use of the volatile pointer (which prevents optimization such as reordering calls or optimizing them out among other things) and the non-temproal instruction (IO writes/reads shouldn't be cached) and of course the iomem annotation seems to support this too.
If I understand this correctly then using the moventi instruction will minimise the impact on the processor's data caches. Using *(unsigned int*)(MappedAddr+pageOffset) = result; instead leaves the the compiler free to choose whichever move instruction it likes, and its likely to choose one that causes the cache line to be pulled into the cache. Which is probably not what you want if you're interacting with a memory mapped device.

Resources