home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c      Meh, in C you gotta define EVERYTHING      243,242 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 242,615 of 243,242   
   BGB to Michael Sanders   
   Re: srand(0) (1/2)   
   26 Dec 25 14:48:45   
   
   From: cr88192@gmail.com   
      
   On 12/26/2025 2:23 AM, Michael Sanders wrote:   
   > On Wed, 24 Dec 2025 23:35:55 -0600, BGB wrote:   
   >   
   >> While arguably a typical C library "rand()" isn't that strong, if one   
   >> has a number sequence of output random digits, it might still take an   
   >> impractical amount of time to brute-force search the entire seed space   
   >> for a 64-bit seed.   
   >   
   > That is a great point IMO. After reading this I used Gemini to get a guess   
   > on the number of permutations for A-Z, its reply was:   
   >   
   > 'over 403 quintillion millions' of permatations for A-Z...   
   >   
   > Now if we split that list (assuming each line was randomized 26 characters   
   > A-Z) & used each line exactly *once*, then destroyed it, we might maintain   
   > some privacy. At least till quantum stuff is in every day use...   
   >   
      
   Though, to be fair, 26! is larger than 2^64.   
      
      
   But, yeah, if you have 64 bits of entropy, while it can be brute forced,   
   it wont happen very quickly (and most normal attackers aren't going to   
   have a supercomputer or similar on-call to crack it faster).   
      
      
   Contrast, say for something with a 32 seed, it could be possible that it   
   could be brute forced within a few seconds or so.   
      
      
      
   But, yeah, one of the main use-cases I had often had for large seed   
   state RNGs is things like UUID generation, which requires a reasonably   
   good RNG with 256 or preferably 512 bits or more of seed state.   
      
      
   Intermediate is ASLR, where something like a 64 or 128-bit RNG is mostly   
   fine. Well, and the effectiveness of ASLR is reduced by a few practical   
   limitations:   
      Can usually only do ASLR on page boundaries,   
        losing some bits of entropy;   
      May need to cluster ASLR into reused sections of the address space,   
        as full randomization results in mostly-empty page table pages.   
      
   Say, for example, you start with 48 bits,   
      Cut off 12 to 16 bits for page offset,   
      Cut off a few HOBs for userland (say 46b for userland space);   
      Maybe quantize high order address into 256 or so buckets.   
      ...   
      
      
   Then one finds that effectively they have around 16 bits or so of   
   entropy here.   
      
      
   Well, say, for ASLR allocation, one might have a process like:   
      For N tries, with a counter:   
        Generate a random number to select a bucket;   
          If index is an unused bucket try again (decrementing counter);   
        Generate a random address within this bucket;   
        Check if the span of pages is free;   
          If so, allocate these pages, call it done.   
        Else, retry (decrementing counter).   
      For N more tries:   
        Generate a full address over the allowed range;   
        Check if pages are free;   
          If so, allocate pages;   
          Set up a bucket for this area of address space;   
          Done.   
      If we get here, likely the whole address space is full...   
        Or the user is trying to allocate vast areas of address space,   
          and fragmentation has won the day.   
      
   The first step for allocation is to mark pages as reserved, then return   
   the base address for the region. then generally the pages are modified   
   to have the desired attributes. Typically (at least in my case) pages   
   are not immediately assigned a backing location in the page-file, but   
   this may happen lazily.   
      
   On first access, if a read, it may be assigned initially to a read-only   
   zero page (no dedicated backing RAM); on first write it is given backing   
   RAM (and assigned a location in the pagefile). If something is paged   
   out, it may detect if the page is all zeroes and potentially revert it   
   back to an initial zeroed-page state (freeing the backing page rather   
   than writing it to the pagefile). This can be used to reduce wasting RAM   
   and pagefile space on bulk zeroed memory (can often be a significant   
   chunk of RAM in some cases).   
      
   Though, by itself has a risk of resulting in a situation where the   
   pagefile is over-committed (there is more active memory allocated than   
   available pagefile space should all this RAM actually be used). So,   
   better to keep track of this and have allocations fail should the total   
   number of committed pages would exceed the size of the pagefile   
   regardless of whether or not all the pagefile pages are actually being   
   used (well, could go the other way; but then there is a bad situation   
   where backing storage runs out in the absence of new memory allocations,   
   potentially resulting in processes crashing at random, rather than   
   failing earlier by a "mmap()" call or similar returning NULL).   
      
      
      
   Well, as can note my memory map (custom OS on a custom ISA, though I am   
   also running RISC-V code on this to some extent) looks sorta like (47:32   
   only):   
            0000: Low 4GB region (system, direct-mapped memory)   
      0001..3FFF: Shared / Global Alloc region;   
      4000..7FFF: Private Alloc (per-process private VAS)   
      8000..BFFF: System Reserved (MMU)   
      C000..FFFF: Hardware memory map stuff (NOMMU RAM and MMIO, etc)   
   ...   
      
   The idea here being that private address space is only visible to the   
   process in question, but stuff in the global space may potentially be   
   visible between processes (though is not necessarily accessible to all   
   processes; idea is that an ACL based protection scheme would be used   
   here rather than by address-space isolation).   
      
   There is a region for direct-mapped RAM currently located in   
   0000_40000000..0000_7FFFFFFF; this is generally read-only from userland.   
   Addresses in this range have virtual-address translation, but are mapped   
   1:1 with backing RAM pages (so its size is naturally more limited).   
      
   A sort of ASLR is used in the direct-mapping space as well, but less   
   effective since the space is smaller. In this case, RNG tries to   
   generate starting page addresses directly.   
      
   Well, and, say (low 4GB):   
      00xxxxxx: Mostly ROM, some SRAM for IRQs, and read-only niche pages.   
        There are ROM pages whose sole purpose is to be all zeroes, etc.   
      010xxxxx: RAM area, reserved for kernel stacks and similar   
      011xxxxx: RAM area, kernel image starts here.   
      ...   
      
      
   Can note about how programs work in my case:   
   The executable parts of an EXE or DLL are separate from the   
   user-writable parts;   
   Currently, the executable parts are held in direct-mapped memory rather   
   than pagefile backed memory (stuff tended to break if these parts could   
   be paged out);   
   Things like writable memory (data/bss) and heap, are instead allocated   
   in pagefile backed memory.   
      
      
   Generally, the mappings for the EXEs and DLLs are shared between all   
   instances of that binary; with data/bss being per-process (accessed via   
   the GP/GBR register, *1).   
      
   Well, except ELF PIE binaries, which need to load a new instance each   
   time (so waste RAM, more so with the large amounts of clutter GCC leaves   
   in the ELF binaries; where things like symbol tables, and worse, DWARF   
      
   [continued in next message]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca