Python, Linux, and the setuid bit

Dave Angel davea at davea.name
Mon Apr 14 21:33:51 EDT 2014


Ethan Furman <ethan at stoneleaf.us> Wrote in message:
> For anyone in the unenviable position of needing [1] to run Python scripts with the setuid bit on, there is an 
> suid-python wrapper [2] that makes this possible.
> 
> When I compiled it I was given a couple warnings.  Can any one shed light on what they mean?
> 
> ==================================================================
> suid-python.c: In function �malloc_abort�:
> suid-python.c:119:17: warning: format �%d� expects argument of type �int�, but argument 3 has type �size_t� [-Wformat]
> suid-python.c: In function �remove_env_prefix�:
> suid-python.c:200:32: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
> suid-python.c:201:32: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
> ==================================================================
> 
> and the code segments in question:
> 
> ==================================================================
> void *
> malloc_abort(size_t size)
> {
>      void *buf;
> 
>      buf = malloc(size);
>      if (!buf)
>      {
>          fprintf(stderr, "Could not allocate %d bytes.  errno=%d\n",
>                  size, errno);

Your variable 'size' is declared as size_t, which is an integer
 the size of a pointer. Not necessarily the same as an int. But if
 your size is reasonable,  no harm done. The correct fix is to use
 some other format rather than % d, I forget what one. Second
 choice is to cast to an int. Third lousy choice,  ignore the
 warning. 


>          exit(1);
>      }
> 
>      return buf;
> }
> ------------------------------------------------------------------
> int
> remove_env_prefix(char **envp, char *prefix)
> {
>      char **envp_read;
>      char **envp_write;
>      int prefix_len = strlen(prefix);
>      int removed_count = 0;
> 
>      envp_write = envp;
>      for (envp_read = envp; *envp_read; envp_read++)
>      {
>          if (!strncmp(*envp_read, prefix, prefix_len))
>          {
>              /* Step past the environment variable that we don't want. */
>              removed_count++;
>              continue;
>          }
> 
>          if (envp_read != envp_write)
>          {
>              *envp_write = *envp_read;
>          }
> 
>          envp_write++;
>      }
> 
>      /* Set the remaining slots to NULL. */
>      if (envp_write < envp_read)
>      {
>          memset(envp_write, 0, ((unsigned int) envp_read -
>                                 (unsigned int) envp_write));

(you really should have put a comment,  so we'd know this is line
 200, 201)

It's incorrect to cast each pointer to an int, but not the
 difference of two pointers.  Subtract the first,  then cast if
 you must.  But the difference of two pointers is type ptr_diff,
 and that should already be the type mem set is expecting.
 

>
> 
> 


-- 
DaveA




More information about the Python-list mailing list