Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

설명

readlink 함수 자체의 예제만으로는 너무 단순해서 좀 확장한 예제를 만들어 봤습니다. 고정폭 버퍼를 사용하여 버퍼오버플로우 취약점을 남겨두는것보다. 다음과 같이 가변적인 버퍼가 되도록 구현하는게 당연히 좋겠죠?

readlink 사용시 가장 주의할것은 readlink 의 buffer 에는 NUL 을 붙여주지 않는다는 점일것입니다. 이것만 주의하면 꽤 유용하겠죠.

사용방법

코드

/* 
 Copyright (C) Information Equipment co.,LTD. 
 All rights reserved. 
 Code by JaeHyuk Cho <mailto:minzkn@infoeq.com> 
 CVSTAG="$Header: /usr/local/mutihost/joinc/modules/moniwiki/data/text/RCS/Code_2fC_2freadlink,v 1.2 2011/02/23 12:07:58 root Exp root $" 
*/ 

#include <sys/types.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 

#if 0 /* recommand */ 
#define def_readlink_start_buffer     (256) 
#define def_readlink_expansion_buffer (8) 
#else /* for test */ 
#define def_readlink_start_buffer     (1) 
#define def_readlink_expansion_buffer (1) 
#endif 

char *mz_readlink(const char *s_path) 
{ 
 char *s_result; 
 size_t s_buffer_size = (size_t)(def_readlink_start_buffer); /* start buffer */ 
 int s_replace_bytes; 
 do 
 { 
  s_result = (char *)malloc(s_buffer_size); 
  if(s_result == ((char *)0))break; /* error */ 
  s_replace_bytes = readlink(s_path, s_result, s_buffer_size); 
  if(s_replace_bytes == (-1)) 
  { /* error */ 
   free(s_result); 
   s_result = (char *)0; 
   break; 
  } 
  if(s_replace_bytes < ((int)s_buffer_size)) 
  { 
   s_result[s_replace_bytes] = '\0'; 
   break; /* ok */ 
  } 
  free((void *)s_result); 
  (void)fprintf(stdout, "buffer replace %d -> %d\n", (int)s_buffer_size, ((int)s_buffer_size) + def_readlink_expansion_buffer); 
  s_buffer_size += def_readlink_expansion_buffer; 
 }while(1); 
 return(s_result); 
} 

int main(int s_argc, char **s_argv) 
{ 
 char *s_linkpath; 
 if(s_argc >= 2) 
 { 
  s_linkpath = mz_readlink(s_argv[1]); 
  if(s_linkpath != ((char *)0)) 
  { 
   (void)fprintf(stdout, "%s -> %s (%d character)\n", s_argv[1], s_linkpath, strlen(s_linkpath)); 
   free(s_linkpath); 
  } 
  else (void)fprintf(stdout, "can not readlink ! (\"%s\")\n", s_argv[1]); 
 } 
 else (void)fprintf(stdout, "usage: %s <link>\nexample: %s /proc/self/exe\n", s_argv[0], s_argv[0]); 
 return(0); 
} 

/* End of source */

변경사항

2005/08/13