Passing capabilities through exec

1,567

Solution 1

It turns out that setting +i on the wrapper does not add the capability to the CAP_INHERITABLE set for the wrapper process, thus it is not passed through exec. I therefore had to manually add CAP_DAC_OVERRIDE to CAP_INHERITABLE before calling execl:

#include <sys/capability.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv[]) {
    cap_t caps = cap_get_proc();
    printf("Capabilities: %s\n", cap_to_text(caps, NULL));
    cap_value_t newcaps[1] = { CAP_DAC_OVERRIDE, };
    cap_set_flag(caps, CAP_INHERITABLE, 1, newcaps, CAP_SET);
    cap_set_proc(caps);
    printf("Capabilities: %s\n", cap_to_text(caps, NULL));
    cap_free(caps);
    return execl("/usr/bin/net", "net", "ads", "dns", "register", "-P", NULL);
}

In addition, I had to add cap_dac_override to the permitted file capabilities set on /usr/bin/net and set the effective bit:

~ $ sudo setcap cap_dac_override=p ./registerdns
~ $ sudo setcap cap_dac_override=ei /usr/bin/net
~ $ ./registerdns
Capabilities = cap_dac_override+p
Capabilities = cap_dac_override+ip
Successfully registered hostname with DNS

I think I now fully understand what's happening:

  1. The wrapper needs CAP_DAC_OVERRIDE in its permitted set so it can add it to its inheritable set.
  2. The wrapper's process inheritable set is different than its file inheritable set, so setting +i on the file is useless; the wrapper must explicitly add CAP_DAC_OVERRIDE to CAP_INHERITABLE using cap_set_flag/cap_set_proc.
  3. The net file needs to have CAP_DAC_OVERRIDE in its inheritable set so that it can in fact inherit the capability from the wrapper into its CAP_PERMITTED set. It also needs the effective bit to be set so that it will be automatically promoted to CAP_EFFECTIVE.

Solution 2

I think you need both:

setcap cap_dac_override+pe ./registerdns
setcap cap_dac_override+i /usr/bin/net

The pe flags on registerdns say that running the program acquires the capability. The i flag on net says that it's allowed to inherit the capability from the calling program.

Share:
1,567

Related videos on Youtube

hhhh
Author by

hhhh

Updated on September 18, 2022

Comments

  • hhhh
    hhhh almost 2 years

    Hi when i am trying this code to dipaly images from imageurl in gridview it is showing null pointer exception can any one help me: my code is

    public class Gridview extends Activity {
    
    
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gridview);
    
        GridView gridview = (GridView) findViewById(R.id.gridview);   
        gridview.setAdapter(new ImageAdapter(this));
       }
    public class ImageAdapter extends BaseAdapter{
    
    
        private Context mContext;
        private Integer[] mThumbIds;
        public ImageAdapter(Context c)
        {
            mContext = c;     
        }
    public int getCount() {
        return mThumbIds.length;
    }
    public Object getItem(int position) {
        return position;
    }
    public long getItemId(int position) {
        return position;
    }
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) {
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(45, 45));
            imageView.setAdjustViewBounds(false);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(8, 8, 8, 8);
        } else {
            imageView = (ImageView) convertView;
        }
        imageView
                .setImageDrawable(LoadImageFromWebOperations("http://tmcrmappsqa.inservices.tatamotors.com/cordys/Images/mobile.png"+position));
        return imageView;
    }
    protected Drawable LoadImageFromWebOperations(String url) {
        try {
            InputStream is = (InputStream) new URL(url).getContent();
            Drawable d = Drawable.createFromStream(is, "src name");
            return d;
        } catch (Exception e) {
            System.exit(0);
            return null;
        }
    }
    
    }    
    
    • dennisdrew
      dennisdrew over 11 years
      You should not be loading images individually from a URL on the UI thread in getView. You should fetch all the images through an AsyncTask and update the GridView in onPostExecute.
    • Bratchley
      Bratchley about 10 years
      The man page for capabilities is pretty invaluable when dealing with them. Look for the section called "Transformation of capabilities during execve" which explains the exact mechanics of how the new Permitted and Effective sets are populated from the Inheritable set.
    • Bratchley
      Bratchley about 10 years
      The UID of zero is special in capability calculation in that execve doesn't default to resetting the inheritable set. That's probably why the setuid is working. I would add the inheritable bit to the net binary and see if that fixes it.
    • Josiah Yoder
      Josiah Yoder almost 6 years
      @Bratchley What is the inheritable set? The man page you link to mentions it several times, but I'm just looking for a quick summary of the important things in it -- like the PID, UID bit and other permissions, std in and out file descriptors, etc.
    • Bratchley
      Bratchley almost 6 years
      @JosiahYoder They actually have an entry for it under "Thread capability sets" but basically it's the set of capabilities child processes can inherit from the parent process if the parent process has that capability. It's basically a way to prevent programs you kick off from having a capability without the parent process giving up the capability for itself.
    • Josiah Yoder
      Josiah Yoder almost 6 years
      @Bratchley Thank you, but that didn't fully answer my question. I've started a new question to ask it clearly. The section "Capabilities list" in the man page you linked to answers my question partly, but I'm also interested in properties of a process that are inherited which are not capabilities.
    • Josiah Yoder
      Josiah Yoder almost 6 years
      I'd like to echo @AdmiralNero's comments from below. After reading the man pages that Bratchley linked, I think the Ambient Set is a better choice than the Inherited Set for unprivileged processes.
  • AdmiralNemo
    AdmiralNemo about 10 years
    This is exactly what I've tried. I've edited my question to better reflect that.
  • ctrl-alt-delor
    ctrl-alt-delor about 4 years
    You are mixing inheritable and permitted way in a dangerous may: By giving the file permitted permission, you give everyone that calls it this permission. Consider also the newer ambient set.