Thread: (x)printf() - very confused

  1. #1
    Registered User
    Join Date
    Sep 2004
    Posts
    17

    (x)printf() - very confused

    Hello all. I've been reading through various materials and have come to confuse the living kaboodles out of myself. This might be asking a lot, but could someone please explain the differences (security-wise, and usage-wise) of
    printf()
    sprintf()
    and snprintf()

    I'd really appreciate it, just can't seem to find the right places that give you the information in a format that I can read and comprehend. Thanks a bunch.

  2. #2
    ---
    Join Date
    May 2004
    Posts
    1,379
    have a look here if you would like
    http://www.acm.uiuc.edu/webmonkeys/b...12.html#printf

    Code:
    fprintf sends formatted output to a stream 
    printf sends formatted output to stdout 
    sprintf sends formatted output to a string 
    vfprintf sends formatted output to a stream using an argument list 
    vprintf sends formatted output to stdout using an argument list 
    vsprintf  sends formatted output to a string using an argument list

  3. #3
    Registered User
    Join Date
    Sep 2004
    Posts
    17
    That helped a little bit, but it wasn't what I was really looking for. I want to know in what type of situations you would use the different printf()'s. And how to use them so that your program remains secure. Thanks again.

  4. #4
    Greetings,

    The explanation of the difference is actually quite short.

    » int printf(const char *format[ , argument , ...]);
    Prints to standard output (stdout) a sequence of arguments formatted as the format argument specifies.

    · format
    String that contains the text to be printed.
    Optionally it can contain format tags that are substituted by the values specified in subsequent argument(s) and formatted as requested.
    · argument(s)
    Optional parameter(s) that contain the data to be inserted instead of % tags specified in format parameter.


    » int sprintf(char *buffer, const char *format[ , argument , ...]);
    Writes a sequence of arguments to the given buffer formatted as the format argument specifies.

    · buffer
    Buffer where to store the resulting formatted string.
    · format
    Same as above.
    · argument(s)
    Same as above.


    I don't know much about snprintf() though I believe it is similar to sprintf(), but allows you to choose the buffer size. I believe it is just like the difference between strcpy() and strncpy().

    Edit:

    Examples
    Code:
    #include <stdio.h>
    
    int main() {
    	char buf[64];
    	const char ch[] = "My string";
    	const char str[] = "My other string";
    
    	printf(ch);
    	printf(" - %s", str);
    
    	sprintf(buf, "(%s) [%s]\n", ch, str);
    	printf(buf);
    
    	return 0;
    }
    For more information, I do believe this page will be of some clarification: snprintf() man pages

    Hope this helps,
    - Stack Overflow
    Last edited by Stack Overflow; 09-14-2004 at 07:33 PM.
    Segmentation Fault: I am an error in which a running program attempts to access memory not allocated to it and core dumps with a segmentation violation error. This is often caused by improper usage of pointers, attempts to access a non-existent or read-only physical memory address, re-use of memory if freed within the same scope, de-referencing a null pointer, or (in C) inadvertently using a non-pointer variable as a pointer.

  5. #5
    Registered User
    Join Date
    Sep 2004
    Posts
    17
    I've heard very bad things about sprintf() and that it should not be used. What kind of security risks might it impose? Would printf() be a security hazard? What alternatives are there that provide a safe solution to outputting data to the screen?

  6. #6
    I would suggest snprintf().

    snprintf() will write at most size-1 of the characters printed into the output string (the size'th character then gets the terminating `\0'); if the return value is greater than or equal to the size argument, the string was too short and some of the printed characters were discarded.

    int snprintf(char *str, size_t size, const char *format, ...);

    I edited my post with further information, but I'll post again. Here are the snprintf() man pages
    Segmentation Fault: I am an error in which a running program attempts to access memory not allocated to it and core dumps with a segmentation violation error. This is often caused by improper usage of pointers, attempts to access a non-existent or read-only physical memory address, re-use of memory if freed within the same scope, de-referencing a null pointer, or (in C) inadvertently using a non-pointer variable as a pointer.

  7. #7
    Registered User
    Join Date
    Sep 2004
    Posts
    17
    Do you think you might be able to post a quick example of how snprintf could be used to output information?

  8. #8
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    snprintf() isn't used to output information. snprintf() is to create a formatted string. printf() is used to output information. It's really very simple once you understand that the format string that you pass to all 3 functions behaves exactly the same in all 3 functions. The only difference is printf() writes the formatted string to stdout and sprintf and snprintf() store the formatted string in a buffer. The only difference between sprintf() and snprintf() is that you can be sure to avoid buffer overflows with snprintf().

    Say you have this:
    Code:
    #include <stdio.h>
    
    int main(void)
    {
      char buf[20];
    
      int num = 5;
    
      sprintf(buf, "%d", num);
      return 0;
    }
    Now...if converting num to a string took more than 19 characters then you'd have a buffer overflow problem. You can replace the sprintf() call with snprintf(buf, sizeof(buf), "%d", num);...this makes it so even if convering num took more than 19 characters, it would still only try to store 19 characters in buf...the rest of the numbers would be truncated.

    Think of printf() as the same as:
    Code:
    sprintf(buf, "%d", num);
    puts(buf);
    That's basically all that printf() is only it doesn't suffer from buffer overflows
    Last edited by itsme86; 09-14-2004 at 08:27 PM.
    If you understand what you're doing, you're not learning anything.

  9. #9
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    yeah, the main difference between all the different printf functions is where they print to and what their argument list is (variable length, or va_list). The unsafeness comes from the output mode usually then: if a printf () string is too long, it just prints more to the screen... if an fprintf () string is too long (out of disk space or wahtever), it just fails. if an sprintf () string is longer than the buffer its being written into, it has no way to know this, so it overwrites forbidden memory. the best you could do would be compare sprintf()s return after the fact, but by then its too late... but since you tell snprintf the max size of your buffer, it won't overflow it.

    reminds me of a noob thing i did once forgetting the existance of snprintf... sprintf() to a (hopefully large enough) buffer, then made the program die with error ("it wasnt big enough") if sprintf ended up writing more.. but of course this is insufficient for both stability and security, as a cleverly crafted call to sprintf() might have already overwritten the next instruction before you even get there.
    hello, internet!

  10. #10
    Registered User
    Join Date
    Aug 2004
    Posts
    7

    Printf insecurity

    printf also can be insecure if used badly.
    If you do this:
    printf("%s", mystring);
    then no matter what the contents of mystring are, this line of code will print it to the screen. If however you do:
    printf(mystring);
    then if mystring contains "foo", this will print "foo" to the screen. But if a maliciious, cunning user controls (even indirectly) the contents of mystring, (s)he could cause it to have a value like "%s".
    Now the call becomes:
    printf("%s");
    This will probably crash your program - a denial of service attack at worst.

    The special format string "%n" causes printf to write to memory (it's the only format string that causes this). Extremely cunning use of this can lead to the ability to write somewhere in your process's address space. If (unluckily for you) this somewhere that I can write is the return address of the current stack frame, then I might be able to execute arbitrary code in your process' context. This would amount to a true security breach at worst.

    Short story:

    1. Never ever use sprintf; always use snprintf.
    2. Never call any FOOprintf functions with one argument. Instead of writing printf("hello"); , write puts("hello"); . In the case of "hello" it makes very little difference, but in the case of printf(astring) where the contents of astring are untrusted, this really matters.

  11. #11
    Registered User
    Join Date
    Sep 2004
    Posts
    17
    Thanks very much! I understand now.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Confused about Memory
    By gL_nEwB in forum C++ Programming
    Replies: 22
    Last Post: 06-20-2006, 07:32 PM
  2. Confused
    By jeev2005 in forum C Programming
    Replies: 5
    Last Post: 06-01-2006, 02:04 PM
  3. Confused
    By (TNT) in forum C# Programming
    Replies: 1
    Last Post: 11-23-2005, 04:49 PM
  4. why wont this compile?!? :confused:
    By jdude in forum C++ Programming
    Replies: 5
    Last Post: 11-25-2004, 01:13 AM
  5. confused.. in selecting my line of deapth
    By jawwadalam in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 05-04-2003, 01:21 PM