Linux Hotplug development
 help / color / mirror / Atom feed
* Re: Creating executable device nodes in /dev?
From: Topi Miettinen @ 2020-12-09  8:58 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: Andy Lutomirski, Andy Lutomirski,
	Zbigniew Jędrzejewski-Szmek, linux-hotplug,
	systemd Mailing List, Jarkko Sakkinen, Jethro Beekman,
	Casey Schaufler, linux-sgx, Svahn, Kai, Schlobohm, Bruce,
	Stephen Smalley, Haitao Huang, Ben Hutchings
In-Reply-To: <20201209004214.GA64820@kernel.org>

On 9.12.2020 2.42, Jarkko Sakkinen wrote:
> On Wed, Dec 09, 2020 at 02:15:28AM +0200, Jarkko Sakkinen wrote:
>> On Wed, Dec 09, 2020 at 01:15:27AM +0200, Topi Miettinen wrote:
>>>>>> As  a further argument, I just did this on a Fedora system:
>>>>>> $ find /dev -perm /ugo+x -a \! -type d -a \! -type l
>>>>>> No results.  So making /dev noexec doesn't seem to have any benefit.
>>>>>
>>>>> It's no surprise that there aren't any executables in /dev since
>>>>> removing MAKEDEV ages ago. That's not the issue, which is that
>>>>> /dev is a writable directory (for UID=0 but no capabilities are
>>>>> needed) and thus a potential location for constructing unapproved
>>>>> executables if it is also mounted exec (W^X).
>>>>
>>>> UID 0 can just change mount options, though, unless SELinux or similar is used. And SELinux can protect /dev just fine without noexec.
>>>
>>> Well, mounting would need CAP_SYS_ADMIN in addition to UID 0. Also SELinux
>>> is not universal and the policies might not contain all users or services.
>>>
>>> -Topi
>>
>> What's the data that supports having noexec /dev anyway? With root
>> access I can then just use something else like /dev/shm mount.
>>
>> Has there been out in the wild real world cases that noexec mount
>> of would have prevented?
> 
> Typo: "of" = "of /dev"
> 
>> For me this sounds a lot just something that "feels more secure"
>> without any measurable benefit. Can you prove me wrong?
> 
> The debate is circled around something not well defined. Of course you
> get theoretically more safe system when you decrease priviliges anywhere
> in the system. Like you could start do grazy things with stuff that
> unprivilged user has access, in order to prevent malware to elevate to
> UID 0 in the first place.
> 
> I think where this go intellectually wrong is that we are talking about
> *default installation* of a distribution. That should have somewhat sane
> common sense access control settings. For like a normal desktop user
> noexec /dev will not do any possible favor.
> 
> Then there is the case when you want to harden installation for an
> application, let's' say some server. In that case you will anyway
> fine-tune the security settings and go grazy enough with hardening.
> When you tailor a server, it's a standard practice to enumerate and
> adjust the mount points if needed.

I think we agree that there's a need for either way to allow SGX (if 
default is hardened) or a hardening option (in the opposite case). For 
systemd I see two approaches:

1. Default noexec /dev, override with something like
- ExecPaths=/dev
- MountOptions=/dev:rw,exec,dev,nosuid
- or even MountOptions=/dev/sgx:rw,exec,dev,nosuid
- ProtectDev=no
- AllowSGX=yes

2. Default exec /dev, override with
- NoExecPaths=/dev
- MountOptions=/dev:rw,noexec,dev,nosuid
- ProtectDev=yes
- DenySGX=yes

I'd prefer 1. but of course 2. would be reasonable.

> To summarize, I neither understand the intended target audience.

We have something in common: me neither. What's the target audience for 
SGX? What's the use case? What are the users: browsers, system services? 
How would applications use SGX? Should udev rules for /dev/sgx make it 
available to any logged in users with uaccess tags?

-Topi

^ permalink raw reply

* Re: Creating executable device nodes in /dev?
From: Topi Miettinen @ 2020-12-09  8:35 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: Andy Lutomirski, Andy Lutomirski,
	Zbigniew Jędrzejewski-Szmek, linux-hotplug,
	systemd Mailing List, Jarkko Sakkinen, Jethro Beekman,
	Casey Schaufler, linux-sgx, Svahn, Kai, Schlobohm, Bruce,
	Stephen Smalley, Haitao Huang, Ben Hutchings
In-Reply-To: <20201209001521.GA64007@kernel.org>

On 9.12.2020 2.15, Jarkko Sakkinen wrote:
> On Wed, Dec 09, 2020 at 01:15:27AM +0200, Topi Miettinen wrote:
>>>>> As  a further argument, I just did this on a Fedora system:
>>>>> $ find /dev -perm /ugo+x -a \! -type d -a \! -type l
>>>>> No results.  So making /dev noexec doesn't seem to have any benefit.
>>>>
>>>> It's no surprise that there aren't any executables in /dev since
>>>> removing MAKEDEV ages ago. That's not the issue, which is that
>>>> /dev is a writable directory (for UID=0 but no capabilities are
>>>> needed) and thus a potential location for constructing unapproved
>>>> executables if it is also mounted exec (W^X).
>>>
>>> UID 0 can just change mount options, though, unless SELinux or similar is used. And SELinux can protect /dev just fine without noexec.
>>
>> Well, mounting would need CAP_SYS_ADMIN in addition to UID 0. Also SELinux
>> is not universal and the policies might not contain all users or services.
>>
>> -Topi
> 
> What's the data that supports having noexec /dev anyway? With root
> access I can then just use something else like /dev/shm mount.
> 
> Has there been out in the wild real world cases that noexec mount
> of would have prevented?
> 
> For me this sounds a lot just something that "feels more secure"
> without any measurable benefit. Can you prove me wrong?

I don't think security works that way. An attacker has various methods 
to choose from, some are more interesting than others. The case where 
rw,exec /dev would be interesting would imply that easier or more common 
avenues would be blocked, for example rw,exec /dev/shm, /tmp, /var/tmp, 
or /run/user/$UID/ for user. Also fileless malware with pure ROP/JOP 
approach with no need for any file system access is getting more common. 
It does not mean that it would not be prudent to block the relatively 
easy approaches too, including /dev.

-Topi

^ permalink raw reply

* Antw: [EXT] Re: [systemd-devel] Creating executable device nodes in /dev?
From: Ulrich Windl @ 2020-12-09  7:58 UTC (permalink / raw)
  To: jarkko; +Cc: systemd-devel@lists.freedesktop.org, linux-hotplug, linux-sgx
In-Reply-To: <20201209001521.GA64007@kernel.org>

>>> Jarkko Sakkinen <jarkko@kernel.org> schrieb am 09.12.2020 um 01:15 in Nachricht
<20201209001521.GA64007@kernel.org>:

...
> 
> What's the data that supports having noexec /dev anyway? With root
> access I can then just use something else like /dev/shm mount.
> 
> Has there been out in the wild real world cases that noexec mount
> of would have prevented?
> 
> For me this sounds a lot just something that "feels more secure"
> without any measurable benefit. Can you prove me wrong?

I think the better question is: Why not allow it? I.e.: Why do you want to forbid it?

Event though I wouldn't like it myself, I could even think of noexec /tmp.

Regards,
Ulrich


^ permalink raw reply

* Re: Creating executable device nodes in /dev?
From: Jarkko Sakkinen @ 2020-12-09  0:42 UTC (permalink / raw)
  To: Topi Miettinen
  Cc: Andy Lutomirski, Andy Lutomirski,
	Zbigniew Jędrzejewski-Szmek, linux-hotplug,
	systemd Mailing List, Jarkko Sakkinen, Jethro Beekman,
	Casey Schaufler, linux-sgx, Svahn, Kai, Schlobohm, Bruce,
	Stephen Smalley, Haitao Huang, Ben Hutchings
In-Reply-To: <20201209001521.GA64007@kernel.org>

On Wed, Dec 09, 2020 at 02:15:28AM +0200, Jarkko Sakkinen wrote:
> On Wed, Dec 09, 2020 at 01:15:27AM +0200, Topi Miettinen wrote:
> > > > > As  a further argument, I just did this on a Fedora system:
> > > > > $ find /dev -perm /ugo+x -a \! -type d -a \! -type l
> > > > > No results.  So making /dev noexec doesn't seem to have any benefit.
> > > > 
> > > > It's no surprise that there aren't any executables in /dev since
> > > > removing MAKEDEV ages ago. That's not the issue, which is that
> > > > /dev is a writable directory (for UID=0 but no capabilities are
> > > > needed) and thus a potential location for constructing unapproved
> > > > executables if it is also mounted exec (W^X).
> > > 
> > > UID 0 can just change mount options, though, unless SELinux or similar is used. And SELinux can protect /dev just fine without noexec.
> > 
> > Well, mounting would need CAP_SYS_ADMIN in addition to UID 0. Also SELinux
> > is not universal and the policies might not contain all users or services.
> > 
> > -Topi
> 
> What's the data that supports having noexec /dev anyway? With root
> access I can then just use something else like /dev/shm mount.
> 
> Has there been out in the wild real world cases that noexec mount
> of would have prevented?

Typo: "of" = "of /dev"

> For me this sounds a lot just something that "feels more secure"
> without any measurable benefit. Can you prove me wrong?

The debate is circled around something not well defined. Of course you
get theoretically more safe system when you decrease priviliges anywhere
in the system. Like you could start do grazy things with stuff that
unprivilged user has access, in order to prevent malware to elevate to
UID 0 in the first place.

I think where this go intellectually wrong is that we are talking about
*default installation* of a distribution. That should have somewhat sane
common sense access control settings. For like a normal desktop user
noexec /dev will not do any possible favor.

Then there is the case when you want to harden installation for an
application, let's' say some server. In that case you will anyway
fine-tune the security settings and go grazy enough with hardening.
When you tailor a server, it's a standard practice to enumerate and
adjust the mount points if needed.

To summarize, I neither understand the intended target audience.

/Jarkko

^ permalink raw reply

* Re: Creating executable device nodes in /dev?
From: Jarkko Sakkinen @ 2020-12-09  0:15 UTC (permalink / raw)
  To: Topi Miettinen
  Cc: Andy Lutomirski, Andy Lutomirski,
	Zbigniew Jędrzejewski-Szmek, linux-hotplug,
	systemd Mailing List, Jarkko Sakkinen, Jethro Beekman,
	Casey Schaufler, linux-sgx, Svahn, Kai, Schlobohm, Bruce,
	Stephen Smalley, Haitao Huang, Ben Hutchings
In-Reply-To: <bbdedcfd-cc24-1616-7f87-3c7f62571b22@gmail.com>

On Wed, Dec 09, 2020 at 01:15:27AM +0200, Topi Miettinen wrote:
> > > > As  a further argument, I just did this on a Fedora system:
> > > > $ find /dev -perm /ugo+x -a \! -type d -a \! -type l
> > > > No results.  So making /dev noexec doesn't seem to have any benefit.
> > > 
> > > It's no surprise that there aren't any executables in /dev since
> > > removing MAKEDEV ages ago. That's not the issue, which is that
> > > /dev is a writable directory (for UID=0 but no capabilities are
> > > needed) and thus a potential location for constructing unapproved
> > > executables if it is also mounted exec (W^X).
> > 
> > UID 0 can just change mount options, though, unless SELinux or similar is used. And SELinux can protect /dev just fine without noexec.
> 
> Well, mounting would need CAP_SYS_ADMIN in addition to UID 0. Also SELinux
> is not universal and the policies might not contain all users or services.
> 
> -Topi

What's the data that supports having noexec /dev anyway? With root
access I can then just use something else like /dev/shm mount.

Has there been out in the wild real world cases that noexec mount
of would have prevented?

For me this sounds a lot just something that "feels more secure"
without any measurable benefit. Can you prove me wrong?

/Jarkko

^ permalink raw reply

* Re: Creating executable device nodes in /dev?
From: Jarkko Sakkinen @ 2020-12-09  0:03 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Topi Miettinen, Zbigniew Jędrzejewski-Szmek, linux-hotplug,
	systemd Mailing List, Jarkko Sakkinen, Jethro Beekman,
	Casey Schaufler, linux-sgx, Svahn, Kai, Schlobohm, Bruce,
	Stephen Smalley, Haitao Huang, Ben Hutchings
In-Reply-To: <CALCETrW7JUquNf_KaA0UK9VEcswQZ+QMqFEQD_8G=c3JyH1xsQ@mail.gmail.com>

On Tue, Dec 08, 2020 at 10:07:17AM -0800, Andy Lutomirski wrote:
> On Thu, Nov 19, 2020 at 10:05 AM Topi Miettinen <toiwoton@gmail.com> wrote:
> >
> > On 19.11.2020 18.32, Zbigniew Jędrzejewski-Szmek wrote:
> > > On Thu, Nov 19, 2020 at 08:17:08AM -0800, Andy Lutomirski wrote:
> > >> Hi udev people-
> > >>
> > >> The upcoming Linux SGX driver has a device node /dev/sgx.  User code
> > >> opens it, does various setup things, mmaps it, and needs to be able to
> > >> create PROT_EXEC mappings.  This gets quite awkward if /dev is mounted
> > >> noexec.
> > >>
> > >> Can udev arrange to make a device node executable on distros that make
> > >> /dev noexec?  This could be done by bind-mounting from an exec tmpfs.
> > >> Alternatively, the kernel could probably learn to ignore noexec on
> > >> /dev/sgx, but that seems a little bit evil.
> > >
> > > I'd be inclined to simply drop noexec from /dev by default.
> > > We don't do noexec on either /tmp or /dev/shm (because that causes immediate
> > > problems with stuff like Java and cffi). And if you have those two at your
> > > disposal anyway, having noexec on /dev doesn't seem important.
> >
> > I'd propose to not enable exec globally, but if a service needs SGX, it
> > could use something like MountOptions=/dev:exec only in those cases
> > where it's needed. That way it's possible to disallow writable and
> > executable file systems for most services (which typically don't need
> > /tmp or /dev/shm either). Of course the opposite
> > (MountOptions=/dev:noexec) would be also possible, but I'd expect that
> > this would be needed to be used more often.
> >
> 
> I imagine the opposite would be more sensible.  It seems odd to me
> that we would want any SGX-using service to require both special mount
> options and regular ACL permissions.
> 
> As  a further argument, I just did this on a Fedora system:
> 
> $ find /dev -perm /ugo+x -a \! -type d -a \! -type l
> 
> No results.  So making /dev noexec doesn't seem to have any benefit.

Neither does my Ubuntu installation with '-xdev' added (because of
/dev/shm mount).

find /dev -xdev -perm /ugo+x -a \! -type d -a \! -type l

/Jarkko

^ permalink raw reply

* Re: Creating executable device nodes in /dev?
From: Topi Miettinen @ 2020-12-08 23:15 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Andy Lutomirski, Zbigniew Jędrzejewski-Szmek, linux-hotplug,
	systemd Mailing List, Jarkko Sakkinen, Jethro Beekman,
	Casey Schaufler, linux-sgx, Svahn, Kai, Schlobohm, Bruce,
	Stephen Smalley, Haitao Huang, Ben Hutchings
In-Reply-To: <9DF5C88B-5156-455A-BA3F-EB19CAA0411B@amacapital.net>

On 8.12.2020 23.30, Andy Lutomirski wrote:
> 
>> On Dec 8, 2020, at 12:45 PM, Topi Miettinen <toiwoton@gmail.com> wrote:
>>
>> On 8.12.2020 20.07, Andy Lutomirski wrote:
>>>> On Thu, Nov 19, 2020 at 10:05 AM Topi Miettinen <toiwoton@gmail.com> wrote:
>>>>
>>>> On 19.11.2020 18.32, Zbigniew Jędrzejewski-Szmek wrote:
>>>>> On Thu, Nov 19, 2020 at 08:17:08AM -0800, Andy Lutomirski wrote:
>>>>>> Hi udev people-
>>>>>>
>>>>>> The upcoming Linux SGX driver has a device node /dev/sgx.  User code
>>>>>> opens it, does various setup things, mmaps it, and needs to be able to
>>>>>> create PROT_EXEC mappings.  This gets quite awkward if /dev is mounted
>>>>>> noexec.
>>>>>>
>>>>>> Can udev arrange to make a device node executable on distros that make
>>>>>> /dev noexec?  This could be done by bind-mounting from an exec tmpfs.
>>>>>> Alternatively, the kernel could probably learn to ignore noexec on
>>>>>> /dev/sgx, but that seems a little bit evil.
>>>>>
>>>>> I'd be inclined to simply drop noexec from /dev by default.
>>>>> We don't do noexec on either /tmp or /dev/shm (because that causes immediate
>>>>> problems with stuff like Java and cffi). And if you have those two at your
>>>>> disposal anyway, having noexec on /dev doesn't seem important.
>>>>
>>>> I'd propose to not enable exec globally, but if a service needs SGX, it
>>>> could use something like MountOptions=/dev:exec only in those cases
>>>> where it's needed. That way it's possible to disallow writable and
>>>> executable file systems for most services (which typically don't need
>>>> /tmp or /dev/shm either). Of course the opposite
>>>> (MountOptions=/dev:noexec) would be also possible, but I'd expect that
>>>> this would be needed to be used more often.
>>>>
>>> I imagine the opposite would be more sensible.  It seems odd to me
>>> that we would want any SGX-using service to require both special mount
>>> options and regular ACL permissions.
>>
>> How common are thes SGX-using services? Will every service start using it without any special measures taken on it's behalf, or perhaps only a special SGX control tool needs access? What about unprivileged user applications, do they ever want to access SGX? Could something like Widevine deep in a browser need to talk to SGX in a DRM scheme?
> 
> I honestly don’t know. Widevine is probably some unholy mess of SGX and ME crud. But regular user programs may well end up using SGX for little non-evil enclaves, e.g. storing their keys securely.  It would be nice if unprivileged enclaves just work as long as the use has appropriate permissions on the device nodes.

Maybe, it would be also great if the access could be limited to those 
users or services which actually need it, by principle of least privilege.

> SGX adoption has been severely hampered by the massive series of recent vulnerabilities and by Intel’s silly licensing scheme. The latter won’t be supported upstream.
> 
>>
>>> As  a further argument, I just did this on a Fedora system:
>>> $ find /dev -perm /ugo+x -a \! -type d -a \! -type l
>>> No results.  So making /dev noexec doesn't seem to have any benefit.
>>
>> It's no surprise that there aren't any executables in /dev since removing MAKEDEV ages ago. That's not the issue, which is that /dev is a writable directory (for UID=0 but no capabilities are needed) and thus a potential location for constructing unapproved executables if it is also mounted exec (W^X).
> 
> UID 0 can just change mount options, though, unless SELinux or similar is used. And SELinux can protect /dev just fine without noexec.

Well, mounting would need CAP_SYS_ADMIN in addition to UID 0. Also 
SELinux is not universal and the policies might not contain all users or 
services.

-Topi

^ permalink raw reply

* Re: Creating executable device nodes in /dev?
From: Andy Lutomirski @ 2020-12-08 21:30 UTC (permalink / raw)
  To: Topi Miettinen
  Cc: Andy Lutomirski, Zbigniew Jędrzejewski-Szmek, linux-hotplug,
	systemd Mailing List, Jarkko Sakkinen, Jethro Beekman,
	Casey Schaufler, linux-sgx, Svahn, Kai, Schlobohm, Bruce,
	Stephen Smalley, Haitao Huang, Ben Hutchings
In-Reply-To: <0f17eade-5e99-be29-fd09-2d0a1949ac7f@gmail.com>


> On Dec 8, 2020, at 12:45 PM, Topi Miettinen <toiwoton@gmail.com> wrote:
> 
> On 8.12.2020 20.07, Andy Lutomirski wrote:
>>> On Thu, Nov 19, 2020 at 10:05 AM Topi Miettinen <toiwoton@gmail.com> wrote:
>>> 
>>> On 19.11.2020 18.32, Zbigniew Jędrzejewski-Szmek wrote:
>>>> On Thu, Nov 19, 2020 at 08:17:08AM -0800, Andy Lutomirski wrote:
>>>>> Hi udev people-
>>>>> 
>>>>> The upcoming Linux SGX driver has a device node /dev/sgx.  User code
>>>>> opens it, does various setup things, mmaps it, and needs to be able to
>>>>> create PROT_EXEC mappings.  This gets quite awkward if /dev is mounted
>>>>> noexec.
>>>>> 
>>>>> Can udev arrange to make a device node executable on distros that make
>>>>> /dev noexec?  This could be done by bind-mounting from an exec tmpfs.
>>>>> Alternatively, the kernel could probably learn to ignore noexec on
>>>>> /dev/sgx, but that seems a little bit evil.
>>>> 
>>>> I'd be inclined to simply drop noexec from /dev by default.
>>>> We don't do noexec on either /tmp or /dev/shm (because that causes immediate
>>>> problems with stuff like Java and cffi). And if you have those two at your
>>>> disposal anyway, having noexec on /dev doesn't seem important.
>>> 
>>> I'd propose to not enable exec globally, but if a service needs SGX, it
>>> could use something like MountOptions=/dev:exec only in those cases
>>> where it's needed. That way it's possible to disallow writable and
>>> executable file systems for most services (which typically don't need
>>> /tmp or /dev/shm either). Of course the opposite
>>> (MountOptions=/dev:noexec) would be also possible, but I'd expect that
>>> this would be needed to be used more often.
>>> 
>> I imagine the opposite would be more sensible.  It seems odd to me
>> that we would want any SGX-using service to require both special mount
>> options and regular ACL permissions.
> 
> How common are thes SGX-using services? Will every service start using it without any special measures taken on it's behalf, or perhaps only a special SGX control tool needs access? What about unprivileged user applications, do they ever want to access SGX? Could something like Widevine deep in a browser need to talk to SGX in a DRM scheme?

I honestly don’t know. Widevine is probably some unholy mess of SGX and ME crud. But regular user programs may well end up using SGX for little non-evil enclaves, e.g. storing their keys securely.  It would be nice if unprivileged enclaves just work as long as the use has appropriate permissions on the device nodes.

SGX adoption has been severely hampered by the massive series of recent vulnerabilities and by Intel’s silly licensing scheme. The latter won’t be supported upstream.

> 
>> As  a further argument, I just did this on a Fedora system:
>> $ find /dev -perm /ugo+x -a \! -type d -a \! -type l
>> No results.  So making /dev noexec doesn't seem to have any benefit.
> 
> It's no surprise that there aren't any executables in /dev since removing MAKEDEV ages ago. That's not the issue, which is that /dev is a writable directory (for UID=0 but no capabilities are needed) and thus a potential location for constructing unapproved executables if it is also mounted exec (W^X).

UID 0 can just change mount options, though, unless SELinux or similar is used. And SELinux can protect /dev just fine without noexec.

> 
> -Topi

^ permalink raw reply

* Re: Creating executable device nodes in /dev?
From: Topi Miettinen @ 2020-12-08 20:45 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Zbigniew Jędrzejewski-Szmek, linux-hotplug,
	systemd Mailing List, Jarkko Sakkinen, Jethro Beekman,
	Casey Schaufler, linux-sgx, Svahn, Kai, Schlobohm, Bruce,
	Stephen Smalley, Haitao Huang, Ben Hutchings
In-Reply-To: <CALCETrW7JUquNf_KaA0UK9VEcswQZ+QMqFEQD_8G=c3JyH1xsQ@mail.gmail.com>

On 8.12.2020 20.07, Andy Lutomirski wrote:
> On Thu, Nov 19, 2020 at 10:05 AM Topi Miettinen <toiwoton@gmail.com> wrote:
>>
>> On 19.11.2020 18.32, Zbigniew Jędrzejewski-Szmek wrote:
>>> On Thu, Nov 19, 2020 at 08:17:08AM -0800, Andy Lutomirski wrote:
>>>> Hi udev people-
>>>>
>>>> The upcoming Linux SGX driver has a device node /dev/sgx.  User code
>>>> opens it, does various setup things, mmaps it, and needs to be able to
>>>> create PROT_EXEC mappings.  This gets quite awkward if /dev is mounted
>>>> noexec.
>>>>
>>>> Can udev arrange to make a device node executable on distros that make
>>>> /dev noexec?  This could be done by bind-mounting from an exec tmpfs.
>>>> Alternatively, the kernel could probably learn to ignore noexec on
>>>> /dev/sgx, but that seems a little bit evil.
>>>
>>> I'd be inclined to simply drop noexec from /dev by default.
>>> We don't do noexec on either /tmp or /dev/shm (because that causes immediate
>>> problems with stuff like Java and cffi). And if you have those two at your
>>> disposal anyway, having noexec on /dev doesn't seem important.
>>
>> I'd propose to not enable exec globally, but if a service needs SGX, it
>> could use something like MountOptions=/dev:exec only in those cases
>> where it's needed. That way it's possible to disallow writable and
>> executable file systems for most services (which typically don't need
>> /tmp or /dev/shm either). Of course the opposite
>> (MountOptions=/dev:noexec) would be also possible, but I'd expect that
>> this would be needed to be used more often.
>>
> 
> I imagine the opposite would be more sensible.  It seems odd to me
> that we would want any SGX-using service to require both special mount
> options and regular ACL permissions.

How common are thes SGX-using services? Will every service start using 
it without any special measures taken on it's behalf, or perhaps only a 
special SGX control tool needs access? What about unprivileged user 
applications, do they ever want to access SGX? Could something like 
Widevine deep in a browser need to talk to SGX in a DRM scheme?

> As  a further argument, I just did this on a Fedora system:
> 
> $ find /dev -perm /ugo+x -a \! -type d -a \! -type l
> 
> No results.  So making /dev noexec doesn't seem to have any benefit.

It's no surprise that there aren't any executables in /dev since 
removing MAKEDEV ages ago. That's not the issue, which is that /dev is a 
writable directory (for UID=0 but no capabilities are needed) and thus a 
potential location for constructing unapproved executables if it is also 
mounted exec (W^X).

-Topi

^ permalink raw reply

* Re: Creating executable device nodes in /dev?
From: Andy Lutomirski @ 2020-12-08 18:07 UTC (permalink / raw)
  To: Topi Miettinen
  Cc: Zbigniew Jędrzejewski-Szmek, Andy Lutomirski, linux-hotplug,
	systemd Mailing List, Jarkko Sakkinen, Jethro Beekman,
	Casey Schaufler, linux-sgx, Svahn, Kai, Schlobohm, Bruce,
	Stephen Smalley, Haitao Huang, Ben Hutchings
In-Reply-To: <ff9aaf77-add3-dbeb-d05e-aedd93d41df0@gmail.com>

On Thu, Nov 19, 2020 at 10:05 AM Topi Miettinen <toiwoton@gmail.com> wrote:
>
> On 19.11.2020 18.32, Zbigniew Jędrzejewski-Szmek wrote:
> > On Thu, Nov 19, 2020 at 08:17:08AM -0800, Andy Lutomirski wrote:
> >> Hi udev people-
> >>
> >> The upcoming Linux SGX driver has a device node /dev/sgx.  User code
> >> opens it, does various setup things, mmaps it, and needs to be able to
> >> create PROT_EXEC mappings.  This gets quite awkward if /dev is mounted
> >> noexec.
> >>
> >> Can udev arrange to make a device node executable on distros that make
> >> /dev noexec?  This could be done by bind-mounting from an exec tmpfs.
> >> Alternatively, the kernel could probably learn to ignore noexec on
> >> /dev/sgx, but that seems a little bit evil.
> >
> > I'd be inclined to simply drop noexec from /dev by default.
> > We don't do noexec on either /tmp or /dev/shm (because that causes immediate
> > problems with stuff like Java and cffi). And if you have those two at your
> > disposal anyway, having noexec on /dev doesn't seem important.
>
> I'd propose to not enable exec globally, but if a service needs SGX, it
> could use something like MountOptions=/dev:exec only in those cases
> where it's needed. That way it's possible to disallow writable and
> executable file systems for most services (which typically don't need
> /tmp or /dev/shm either). Of course the opposite
> (MountOptions=/dev:noexec) would be also possible, but I'd expect that
> this would be needed to be used more often.
>

I imagine the opposite would be more sensible.  It seems odd to me
that we would want any SGX-using service to require both special mount
options and regular ACL permissions.

As  a further argument, I just did this on a Fedora system:

$ find /dev -perm /ugo+x -a \! -type d -a \! -type l

No results.  So making /dev noexec doesn't seem to have any benefit.

^ permalink raw reply

* Re: Creating executable device nodes in /dev?
From: Topi Miettinen @ 2020-11-19 18:05 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek, Andy Lutomirski
  Cc: linux-hotplug, systemd Mailing List, Jarkko Sakkinen,
	Jethro Beekman, Casey Schaufler, linux-sgx, Svahn, Kai,
	Schlobohm, Bruce, Stephen Smalley, Haitao Huang, Ben Hutchings
In-Reply-To: <20201119163245.GN7348@in.waw.pl>

On 19.11.2020 18.32, Zbigniew Jędrzejewski-Szmek wrote:
> On Thu, Nov 19, 2020 at 08:17:08AM -0800, Andy Lutomirski wrote:
>> Hi udev people-
>>
>> The upcoming Linux SGX driver has a device node /dev/sgx.  User code
>> opens it, does various setup things, mmaps it, and needs to be able to
>> create PROT_EXEC mappings.  This gets quite awkward if /dev is mounted
>> noexec.
>>
>> Can udev arrange to make a device node executable on distros that make
>> /dev noexec?  This could be done by bind-mounting from an exec tmpfs.
>> Alternatively, the kernel could probably learn to ignore noexec on
>> /dev/sgx, but that seems a little bit evil.
> 
> I'd be inclined to simply drop noexec from /dev by default.
> We don't do noexec on either /tmp or /dev/shm (because that causes immediate
> problems with stuff like Java and cffi). And if you have those two at your
> disposal anyway, having noexec on /dev doesn't seem important.

I'd propose to not enable exec globally, but if a service needs SGX, it 
could use something like MountOptions=/dev:exec only in those cases 
where it's needed. That way it's possible to disallow writable and 
executable file systems for most services (which typically don't need 
/tmp or /dev/shm either). Of course the opposite 
(MountOptions=/dev:noexec) would be also possible, but I'd expect that 
this would be needed to be used more often.

-Topi

^ permalink raw reply

* Re: Creating executable device nodes in /dev?
From: Zbigniew Jędrzejewski-Szmek @ 2020-11-19 16:32 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: linux-hotplug, systemd Mailing List, Jarkko Sakkinen,
	Jethro Beekman, Topi Miettinen, Casey Schaufler, linux-sgx,
	Svahn, Kai, Schlobohm, Bruce, Stephen Smalley, Haitao Huang,
	Ben Hutchings
In-Reply-To: <CALCETrWM2rGPRudtaQ=mn9MRsrbQqFfZDkOGsBbVMsk6mMw_+A@mail.gmail.com>

On Thu, Nov 19, 2020 at 08:17:08AM -0800, Andy Lutomirski wrote:
> Hi udev people-
> 
> The upcoming Linux SGX driver has a device node /dev/sgx.  User code
> opens it, does various setup things, mmaps it, and needs to be able to
> create PROT_EXEC mappings.  This gets quite awkward if /dev is mounted
> noexec.
> 
> Can udev arrange to make a device node executable on distros that make
> /dev noexec?  This could be done by bind-mounting from an exec tmpfs.
> Alternatively, the kernel could probably learn to ignore noexec on
> /dev/sgx, but that seems a little bit evil.

I'd be inclined to simply drop noexec from /dev by default.
We don't do noexec on either /tmp or /dev/shm (because that causes immediate
problems with stuff like Java and cffi). And if you have those two at your
disposal anyway, having noexec on /dev doesn't seem important.

Afaik, the kernel would refuse execve() on a character or block device
anyway. Thus noexec on /dev matters only for actual binaries copied to
/dev, which requires root privileges in the first place.

Zbyszek

^ permalink raw reply

* Creating executable device nodes in /dev?
From: Andy Lutomirski @ 2020-11-19 16:17 UTC (permalink / raw)
  To: linux-hotplug, systemd Mailing List, Jarkko Sakkinen,
	Jethro Beekman, Topi Miettinen, Casey Schaufler, linux-sgx,
	Svahn, Kai, Schlobohm, Bruce, Stephen Smalley, Haitao Huang,
	Ben Hutchings

Hi udev people-

The upcoming Linux SGX driver has a device node /dev/sgx.  User code
opens it, does various setup things, mmaps it, and needs to be able to
create PROT_EXEC mappings.  This gets quite awkward if /dev is mounted
noexec.

Can udev arrange to make a device node executable on distros that make
/dev noexec?  This could be done by bind-mounting from an exec tmpfs.
Alternatively, the kernel could probably learn to ignore noexec on
/dev/sgx, but that seems a little bit evil.

Thanks,
Andy

^ permalink raw reply

* Re: udev events for iscsi
From: Greg KH @ 2020-04-21 15:41 UTC (permalink / raw)
  To: linux-hotplug
In-Reply-To: <4a648986b130f48c9125013630473d17@assyoma.it>

On Mon, Apr 20, 2020 at 06:55:52PM +0200, Gionatan Danti wrote:
> Hi all,
> I have a question regarding udev events when using iscsi disks.
> 
> By using "udevadm monitor" I can see that events are generated when I login
> and logout from an iscsi portal/resource, creating/destroying the relative
> links under /dev/
> 
> However, I can not see anything when the remote machine simple
> dies/reboots/disconnects: while "dmesg" shows the iscsi timeout expiring, I
> don't see anything about a removed disk (and the links under /dev/ remains
> unaltered, indeed). At the same time, when the remote machine and disk
> become available again, no reconnection events happen.
> 
> Is this the expected behavior? Can be changed? Should I ping the linux-scsi
> list instead?

Try asking the linux-scsi developers, as they know what should happen
here more than anyone.

thanks,

greg k-h

^ permalink raw reply

* udev events for iscsi
From: Gionatan Danti @ 2020-04-20 16:55 UTC (permalink / raw)
  To: linux-hotplug

Hi all,
I have a question regarding udev events when using iscsi disks.

By using "udevadm monitor" I can see that events are generated when I 
login and logout from an iscsi portal/resource, creating/destroying the 
relative links under /dev/

However, I can not see anything when the remote machine simple 
dies/reboots/disconnects: while "dmesg" shows the iscsi timeout 
expiring, I don't see anything about a removed disk (and the links under 
/dev/ remains unaltered, indeed). At the same time, when the remote 
machine and disk become available again, no reconnection events happen.

Is this the expected behavior? Can be changed? Should I ping the 
linux-scsi list instead?
Thanks.

-- 
Danti Gionatan
Supporto Tecnico
Assyoma S.r.l. - www.assyoma.it [1]
email: g.danti@assyoma.it - info@assyoma.it
GPG public key ID: FF5F32A8

^ permalink raw reply

* HID_QUIRK_INPUT_PER_APP vs /dev/input/by-id
From: Jim Paris @ 2020-03-14 17:50 UTC (permalink / raw)
  To: linux-hotplug

Since Linux 4.18 where HID_QUIRK_INPUT_PER_APP was added (f07b3c1da9
"HID: generic: create one input report per application type"), my
USB keyboard shows up as 3 input devices instead of 2:

  [    1.448722] usb 1-1.1: new low-speed USB device number 3 using xhci_hcd
  [    1.588196] usb 1-1.1: New USB device found, idVendorA3c, idProduct!12, bcdDevice= 1.07
  [    1.591237] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
  [    1.594249] usb 1-1.1: Product: Dell USB Wired Multimedia Keyboard
  [    1.597222] usb 1-1.1: Manufacturer: DELL
  [    1.612274] input: DELL Dell USB Wired Multimedia Keyboard as /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/0003:413C:2112.0001/input/input0
  [    1.679217] hid-generic 0003:413C:2112.0001: input,hidraw0: USB HID v1.10 Keyboard [DELL Dell USB Wired Multimedia Keyboard] on usb-0000:01:00.0-1.1/input0
  [    1.692457] input: DELL Dell USB Wired Multimedia Keyboard System Control as /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.1/0003:413C:2112.0002/input/input1
  [    1.758905] input: DELL Dell USB Wired Multimedia Keyboard Consumer Control as /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.1/0003:413C:2112.0002/input/input2
  [    1.762641] hid-generic 0003:413C:2112.0002: input,hidraw1: USB HID v1.10 Device [DELL Dell USB Wired Multimedia Keyboard] on usb-0000:01:00.0-1.1/input1

This is fine:

  $ ls -l /dev/input/event[012]
  crw-rw---- 1 root input 13, 64 Mar 14 12:15 /dev/input/event0
  crw-rw---- 1 root input 13, 65 Mar 14 12:15 /dev/input/event1
  crw-rw---- 1 root input 13, 66 Mar 14 12:15 /dev/input/event2

But the second and third look the same as far as
/lib/udev/rules.d/60-persistent-input.rules is concerned:

  $ ls -l /dev/input/by-id/*Dell*
  lrwxrwxrwx 1 root root 9 Mar 14 12:15 usb-DELL_Dell_USB_Wired_Multimedia_Keyboard-event-if01 -> ../event2
  lrwxrwxrwx 1 root root 9 Mar 14 12:15 usb-DELL_Dell_USB_Wired_Multimedia_Keyboard-event-kbd -> ../event0

The only difference I see in the udev attributes is ATTR{name} at the
input device (attached below), so I am using this as temporary hack to
get all 3 links for this keyboard:

  SUBSYSTEMS="input", KERNEL="event*", ATTRS{name}="?*", \
     SYMLINK+="input/by-id/usb-jim-$attr{name}-event-if$env{ID_USB_INTERFACE_NUM}"

  $ ls -l /dev/input/by-id/usb-jim-*
  lrwxrwxrwx 1 root root 9 Mar 14 13:39 /dev/input/by-id/usb-jim-DELL_Dell_USB_Wired_Multimedia_Keyboard_Consumer_Control-event-if01 -> ../event2
  lrwxrwxrwx 1 root root 9 Mar 14 13:39 /dev/input/by-id/usb-jim-DELL_Dell_USB_Wired_Multimedia_Keyboard-event-if00 -> ../event0
  lrwxrwxrwx 1 root root 9 Mar 14 13:39 /dev/input/by-id/usb-jim-DELL_Dell_USB_Wired_Multimedia_Keyboard_System_Control-event-if01 -> ../event1

Should the shipped udev rules account for this?  Or should the kernel
be exposing the devices differently?

Jim



# udevadm info -q all --attribute-walk -p devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.1/0003:413C:2112.0023/input/input51/event1

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.1/0003:413C:2112.0023/input/input51/event1':
    KERNEL="event1"
    SUBSYSTEM="input"
    DRIVER=""

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.1/0003:413C:2112.0023/input/input51':
    KERNELS="input51"
    SUBSYSTEMS="input"
    DRIVERS=""
    ATTRS{phys}="usb-0000:01:00.0-1.1/input1"
    ATTRS{uniq}=""
    ATTRS{properties}="0"
    ATTRS{name}="DELL Dell USB Wired Multimedia Keyboard System Control"

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.1/0003:413C:2112.0023':
    KERNELS="0003:413C:2112.0023"
    SUBSYSTEMS="hid"
    DRIVERS="hid-generic"
    ATTRS{country}="00"

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.1':
    KERNELS="1-1.1:1.1"
    SUBSYSTEMS="usb"
    DRIVERS="usbhid"
    ATTRS{bInterfaceNumber}="01"
    ATTRS{bInterfaceProtocol}="00"
    ATTRS{supports_autosuspend}="1"
    ATTRS{bInterfaceClass}="03"
    ATTRS{bInterfaceSubClass}="00"
    ATTRS{authorized}="1"
    ATTRS{bNumEndpoints}="01"
    ATTRS{bAlternateSetting}=" 0"

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1':
    KERNELS="1-1.1"
    SUBSYSTEMS="usb"
    DRIVERS="usb"
    ATTRS{quirks}="0x0"
    ATTRS{bMaxPower}="100mA"
    ATTRS{avoid_reset_quirk}="0"
    ATTRS{removable}="unknown"
    ATTRS{bConfigurationValue}="1"
    ATTRS{busnum}="1"
    ATTRS{bNumInterfaces}=" 2"
    ATTRS{idVendor}="413c"
    ATTRS{ltm_capable}="no"
    ATTRS{rx_lanes}="1"
    ATTRS{bcdDevice}="0107"
    ATTRS{bDeviceClass}="00"
    ATTRS{devpath}="1.1"
    ATTRS{devspec}="  (null)"
    ATTRS{tx_lanes}="1"
    ATTRS{version}=" 1.10"
    ATTRS{authorized}="1"
    ATTRS{urbnum}="15"
    ATTRS{product}="Dell USB Wired Multimedia Keyboard"
    ATTRS{bNumConfigurations}="1"
    ATTRS{configuration}=""
    ATTRS{bMaxPacketSize0}="8"
    ATTRS{idProduct}="2112"
    ATTRS{speed}="1.5"
    ATTRS{bDeviceProtocol}="00"
    ATTRS{bmAttributes}="a0"
    ATTRS{manufacturer}="DELL"
    ATTRS{bDeviceSubClass}="00"
    ATTRS{devnum}="20"
    ATTRS{maxchild}="0"

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1':
    KERNELS="1-1"
    SUBSYSTEMS="usb"
    DRIVERS="usb"
    ATTRS{speed}="480"
    ATTRS{bDeviceProtocol}="01"
    ATTRS{bNumConfigurations}="1"
    ATTRS{devspec}="  (null)"
    ATTRS{bDeviceClass}="09"
    ATTRS{configuration}=""
    ATTRS{tx_lanes}="1"
    ATTRS{bMaxPower}="100mA"
    ATTRS{authorized}="1"
    ATTRS{bcdDevice}="0421"
    ATTRS{bDeviceSubClass}="00"
    ATTRS{ltm_capable}="no"
    ATTRS{avoid_reset_quirk}="0"
    ATTRS{urbnum}="409"
    ATTRS{devnum}="2"
    ATTRS{rx_lanes}="1"
    ATTRS{maxchild}="4"
    ATTRS{version}=" 2.10"
    ATTRS{product}="USB2.0 Hub"
    ATTRS{idProduct}="3431"
    ATTRS{bNumInterfaces}=" 1"
    ATTRS{bConfigurationValue}="1"
    ATTRS{bMaxPacketSize0}="64"
    ATTRS{removable}="unknown"
    ATTRS{idVendor}="2109"
    ATTRS{bmAttributes}="e0"
    ATTRS{devpath}="1"
    ATTRS{quirks}="0x0"
    ATTRS{busnum}="1"

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1':
    KERNELS="usb1"
    SUBSYSTEMS="usb"
    DRIVERS="usb"
    ATTRS{speed}="480"
    ATTRS{busnum}="1"
    ATTRS{rx_lanes}="1"
    ATTRS{bMaxPower}="0mA"
    ATTRS{devpath}="0"
    ATTRS{bDeviceClass}="09"
    ATTRS{serial}="0000:01:00.0"
    ATTRS{bDeviceSubClass}="00"
    ATTRS{avoid_reset_quirk}="0"
    ATTRS{product}="xHCI Host Controller"
    ATTRS{authorized_default}="1"
    ATTRS{bDeviceProtocol}="01"
    ATTRS{configuration}=""
    ATTRS{bMaxPacketSize0}="64"
    ATTRS{ltm_capable}="no"
    ATTRS{devspec}="  (null)"
    ATTRS{idProduct}="0002"
    ATTRS{quirks}="0x0"
    ATTRS{tx_lanes}="1"
    ATTRS{interface_authorized_default}="1"
    ATTRS{bNumConfigurations}="1"
    ATTRS{bNumInterfaces}=" 1"
    ATTRS{maxchild}="1"
    ATTRS{bmAttributes}="e0"
    ATTRS{devnum}="1"
    ATTRS{idVendor}="1d6b"
    ATTRS{version}=" 2.00"
    ATTRS{urbnum}="22"
    ATTRS{bConfigurationValue}="1"
    ATTRS{removable}="unknown"
    ATTRS{authorized}="1"
    ATTRS{bcdDevice}="0419"
    ATTRS{manufacturer}="Linux 4.19.97-v7l+ xhci-hcd"

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0':
    KERNELS="0000:01:00.0"
    SUBSYSTEMS="pci"
    DRIVERS="xhci_hcd"
    ATTRS{devspec}=""
    ATTRS{local_cpus}="f"
    ATTRS{max_link_width}="1"
    ATTRS{class}="0x0c0330"
    ATTRS{subsystem_vendor}="0x1106"
    ATTRS{max_link_speed}="5 GT/s"
    ATTRS{current_link_width}="1"
    ATTRS{revision}="0x01"
    ATTRS{subsystem_device}="0x3483"
    ATTRS{ari_enabled}="0"
    ATTRS{device}="0x3483"
    ATTRS{broken_parity_status}="0"
    ATTRS{enable}="1"
    ATTRS{irq}="54"
    ATTRS{consistent_dma_mask_bits}="64"
    ATTRS{driver_override}="(null)"
    ATTRS{local_cpulist}="0-3"
    ATTRS{msi_bus}="1"
    ATTRS{vendor}="0x1106"
    ATTRS{current_link_speed}="5 GT/s"
    ATTRS{dma_mask_bits}="64"

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0':
    KERNELS="0000:00:00.0"
    SUBSYSTEMS="pci"
    DRIVERS="pcieport"
    ATTRS{current_link_width}="1"
    ATTRS{irq}="53"
    ATTRS{aer_rootport_total_err_cor}="0"
    ATTRS{aer_rootport_total_err_nonfatal}="0"
    ATTRS{revision}="0x10"
    ATTRS{secondary_bus_number}="1"
    ATTRS{consistent_dma_mask_bits}="32"
    ATTRS{max_link_speed}="5 GT/s"
    ATTRS{local_cpulist}="0-3"
    ATTRS{ari_enabled}="0"
    ATTRS{driver_override}="(null)"
    ATTRS{subsystem_device}="0x0000"
    ATTRS{devspec}=""
    ATTRS{subsystem_vendor}="0x0000"
    ATTRS{vendor}="0x14e4"
    ATTRS{msi_bus}="1"
    ATTRS{broken_parity_status}="0"
    ATTRS{enable}="1"
    ATTRS{local_cpus}="f"
    ATTRS{dma_mask_bits}="32"
    ATTRS{aer_rootport_total_err_fatal}="0"
    ATTRS{max_link_width}="1"
    ATTRS{current_link_speed}="5 GT/s"
    ATTRS{device}="0x2711"
    ATTRS{subordinate_bus_number}="1"
    ATTRS{class}="0x060400"

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00':
    KERNELS="pci0000:00"
    SUBSYSTEMS=""
    DRIVERS=""

  looking at parent device '/devices/platform/scb/fd500000.pcie':
    KERNELS="fd500000.pcie"
    SUBSYSTEMS="platform"
    DRIVERS="brcm-pcie"
    ATTRS{driver_override}="(null)"
    ATTRS{dmabounce_stats}="m:0/0 s:0/0 f:0 s:0 b:0/0 a:0/0"

  looking at parent device '/devices/platform/scb':
    KERNELS="scb"
    SUBSYSTEMS="platform"
    DRIVERS=""
    ATTRS{driver_override}="(null)"

  looking at parent device '/devices/platform':
    KERNELS="platform"
    SUBSYSTEMS=""
    DRIVERS=""

# udevadm info -q all --attribute-walk -p devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.1/0003:413C:2112.0023/input/input52/event2

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.1/0003:413C:2112.0023/input/input52/event2':
    KERNEL="event2"
    SUBSYSTEM="input"
    DRIVER=""

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.1/0003:413C:2112.0023/input/input52':
    KERNELS="input52"
    SUBSYSTEMS="input"
    DRIVERS=""
    ATTRS{name}="DELL Dell USB Wired Multimedia Keyboard Consumer Control"
    ATTRS{properties}="0"
    ATTRS{uniq}=""
    ATTRS{phys}="usb-0000:01:00.0-1.1/input1"

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.1/0003:413C:2112.0023':
    KERNELS="0003:413C:2112.0023"
    SUBSYSTEMS="hid"
    DRIVERS="hid-generic"
    ATTRS{country}="00"

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.1':
    KERNELS="1-1.1:1.1"
    SUBSYSTEMS="usb"
    DRIVERS="usbhid"
    ATTRS{bAlternateSetting}=" 0"
    ATTRS{authorized}="1"
    ATTRS{bInterfaceClass}="03"
    ATTRS{bInterfaceProtocol}="00"
    ATTRS{bInterfaceSubClass}="00"
    ATTRS{supports_autosuspend}="1"
    ATTRS{bInterfaceNumber}="01"
    ATTRS{bNumEndpoints}="01"

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1':
    KERNELS="1-1.1"
    SUBSYSTEMS="usb"
    DRIVERS="usb"
    ATTRS{devnum}="20"
    ATTRS{bNumInterfaces}=" 2"
    ATTRS{ltm_capable}="no"
    ATTRS{bcdDevice}="0107"
    ATTRS{bMaxPacketSize0}="8"
    ATTRS{quirks}="0x0"
    ATTRS{configuration}=""
    ATTRS{rx_lanes}="1"
    ATTRS{bMaxPower}="100mA"
    ATTRS{authorized}="1"
    ATTRS{version}=" 1.10"
    ATTRS{bmAttributes}="a0"
    ATTRS{devpath}="1.1"
    ATTRS{maxchild}="0"
    ATTRS{bNumConfigurations}="1"
    ATTRS{avoid_reset_quirk}="0"
    ATTRS{removable}="unknown"
    ATTRS{bConfigurationValue}="1"
    ATTRS{speed}="1.5"
    ATTRS{idVendor}="413c"
    ATTRS{idProduct}="2112"
    ATTRS{bDeviceClass}="00"
    ATTRS{bDeviceProtocol}="00"
    ATTRS{product}="Dell USB Wired Multimedia Keyboard"
    ATTRS{busnum}="1"
    ATTRS{tx_lanes}="1"
    ATTRS{manufacturer}="DELL"
    ATTRS{devspec}="  (null)"
    ATTRS{urbnum}="15"
    ATTRS{bDeviceSubClass}="00"

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1':
    KERNELS="1-1"
    SUBSYSTEMS="usb"
    DRIVERS="usb"
    ATTRS{bDeviceClass}="09"
    ATTRS{bConfigurationValue}="1"
    ATTRS{maxchild}="4"
    ATTRS{product}="USB2.0 Hub"
    ATTRS{speed}="480"
    ATTRS{removable}="unknown"
    ATTRS{configuration}=""
    ATTRS{bNumConfigurations}="1"
    ATTRS{idVendor}="2109"
    ATTRS{avoid_reset_quirk}="0"
    ATTRS{quirks}="0x0"
    ATTRS{idProduct}="3431"
    ATTRS{rx_lanes}="1"
    ATTRS{bmAttributes}="e0"
    ATTRS{bDeviceSubClass}="00"
    ATTRS{devnum}="2"
    ATTRS{bcdDevice}="0421"
    ATTRS{version}=" 2.10"
    ATTRS{busnum}="1"
    ATTRS{ltm_capable}="no"
    ATTRS{devspec}="  (null)"
    ATTRS{devpath}="1"
    ATTRS{bDeviceProtocol}="01"
    ATTRS{tx_lanes}="1"
    ATTRS{bNumInterfaces}=" 1"
    ATTRS{urbnum}="409"
    ATTRS{bMaxPower}="100mA"
    ATTRS{bMaxPacketSize0}="64"
    ATTRS{authorized}="1"

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1':
    KERNELS="usb1"
    SUBSYSTEMS="usb"
    DRIVERS="usb"
    ATTRS{devnum}="1"
    ATTRS{bMaxPacketSize0}="64"
    ATTRS{devpath}="0"
    ATTRS{bConfigurationValue}="1"
    ATTRS{ltm_capable}="no"
    ATTRS{rx_lanes}="1"
    ATTRS{serial}="0000:01:00.0"
    ATTRS{bDeviceClass}="09"
    ATTRS{bDeviceSubClass}="00"
    ATTRS{bNumConfigurations}="1"
    ATTRS{idVendor}="1d6b"
    ATTRS{tx_lanes}="1"
    ATTRS{configuration}=""
    ATTRS{version}=" 2.00"
    ATTRS{bNumInterfaces}=" 1"
    ATTRS{removable}="unknown"
    ATTRS{maxchild}="1"
    ATTRS{bDeviceProtocol}="01"
    ATTRS{authorized}="1"
    ATTRS{speed}="480"
    ATTRS{bMaxPower}="0mA"
    ATTRS{avoid_reset_quirk}="0"
    ATTRS{authorized_default}="1"
    ATTRS{busnum}="1"
    ATTRS{urbnum}="22"
    ATTRS{devspec}="  (null)"
    ATTRS{bmAttributes}="e0"
    ATTRS{idProduct}="0002"
    ATTRS{manufacturer}="Linux 4.19.97-v7l+ xhci-hcd"
    ATTRS{interface_authorized_default}="1"
    ATTRS{product}="xHCI Host Controller"
    ATTRS{bcdDevice}="0419"
    ATTRS{quirks}="0x0"

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0':
    KERNELS="0000:01:00.0"
    SUBSYSTEMS="pci"
    DRIVERS="xhci_hcd"
    ATTRS{subsystem_vendor}="0x1106"
    ATTRS{enable}="1"
    ATTRS{local_cpus}="f"
    ATTRS{ari_enabled}="0"
    ATTRS{broken_parity_status}="0"
    ATTRS{consistent_dma_mask_bits}="64"
    ATTRS{current_link_width}="1"
    ATTRS{current_link_speed}="5 GT/s"
    ATTRS{irq}="54"
    ATTRS{vendor}="0x1106"
    ATTRS{driver_override}="(null)"
    ATTRS{msi_bus}="1"
    ATTRS{device}="0x3483"
    ATTRS{max_link_width}="1"
    ATTRS{dma_mask_bits}="64"
    ATTRS{devspec}=""
    ATTRS{local_cpulist}="0-3"
    ATTRS{class}="0x0c0330"
    ATTRS{subsystem_device}="0x3483"
    ATTRS{max_link_speed}="5 GT/s"
    ATTRS{revision}="0x01"

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0':
    KERNELS="0000:00:00.0"
    SUBSYSTEMS="pci"
    DRIVERS="pcieport"
    ATTRS{ari_enabled}="0"
    ATTRS{current_link_width}="1"
    ATTRS{local_cpulist}="0-3"
    ATTRS{dma_mask_bits}="32"
    ATTRS{max_link_width}="1"
    ATTRS{consistent_dma_mask_bits}="32"
    ATTRS{devspec}=""
    ATTRS{local_cpus}="f"
    ATTRS{aer_rootport_total_err_fatal}="0"
    ATTRS{subsystem_vendor}="0x0000"
    ATTRS{broken_parity_status}="0"
    ATTRS{irq}="53"
    ATTRS{revision}="0x10"
    ATTRS{enable}="1"
    ATTRS{device}="0x2711"
    ATTRS{subordinate_bus_number}="1"
    ATTRS{aer_rootport_total_err_cor}="0"
    ATTRS{vendor}="0x14e4"
    ATTRS{max_link_speed}="5 GT/s"
    ATTRS{aer_rootport_total_err_nonfatal}="0"
    ATTRS{secondary_bus_number}="1"
    ATTRS{current_link_speed}="5 GT/s"
    ATTRS{driver_override}="(null)"
    ATTRS{msi_bus}="1"
    ATTRS{subsystem_device}="0x0000"
    ATTRS{class}="0x060400"

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00':
    KERNELS="pci0000:00"
    SUBSYSTEMS=""
    DRIVERS=""

  looking at parent device '/devices/platform/scb/fd500000.pcie':
    KERNELS="fd500000.pcie"
    SUBSYSTEMS="platform"
    DRIVERS="brcm-pcie"
    ATTRS{dmabounce_stats}="m:0/0 s:0/0 f:0 s:0 b:0/0 a:0/0"
    ATTRS{driver_override}="(null)"

  looking at parent device '/devices/platform/scb':
    KERNELS="scb"
    SUBSYSTEMS="platform"
    DRIVERS=""
    ATTRS{driver_override}="(null)"

  looking at parent device '/devices/platform':
    KERNELS="platform"
    SUBSYSTEMS=""
    DRIVERS=""

^ permalink raw reply

* Re: Consolidating the interface for camera components
From: Greg KH @ 2019-12-06 17:57 UTC (permalink / raw)
  To: linux-hotplug
In-Reply-To: <MNGy0F8hmcJu26jxhZS9eQjsTAmh1Uh_zqVhTzSeFndBaPi2lEXsbCO99Wdja9-5yaBOihwddIZbD8NTDTwerYtAUQ89wckBymIFeG5-eD0=@philipmolloy.com>

On Fri, Dec 06, 2019 at 04:50:09PM +0000, Philip Molloy wrote:
> Hello,
> 
> I'm trying to consolidate the interface for several camera components into one place to represent a single camera.
> 
> Each of the camera modules includes a LED driver (0x63) and camera (0x3c) that sit behind a couple muxes. For example:
> 
> /sys/devices/platform/amba/ff030000.i2c/i2c-1/i2c-3/i2c-5/5-003c/
> /sys/devices/platform/amba/ff030000.i2c/i2c-1/i2c-3/i2c-7/7-0063/
> 
> The LEDs are also available under /sys/class/leds/ based on their labels as defined in the devicetree.
> 
> The image data captured by the camera passes through two soft IP blocks. The driver for the second block maps the image into memory and exposes it as a block device in /dev.
> 
> In #kernel-newbies on OFC it was suggested that I could use udev to symlink the above into one place in /dev, but I'm having trouble creating a symlink between /sys and /dev (e.g. /sys/.../5-003c -> /dev/camera-name/camera). Perhaps that isn't possible or intended? I've only seen symlinks between /dev and /dev in /usr/lib/udev/rules.d/*.rules on my development system.
> 
> If it is I can explain what I've tried in more detail, but basically I'd like to do something like the following:
> 
> DRIVER="aptina-ar0330", SYMLINK+="camera/$attr{../../of_node/name}/$env{OF_NAME}"
> 
> If it is not possible any other recommendations would be greatly appreciated.

Try asking on the linux-media mailing list as this is the API those
drivers expose.

thanks,

greg k-h

^ permalink raw reply

* Consolidating the interface for camera components
From: Philip Molloy @ 2019-12-06 16:50 UTC (permalink / raw)
  To: linux-hotplug

Hello,

I'm trying to consolidate the interface for several camera components into one place to represent a single camera.

Each of the camera modules includes a LED driver (0x63) and camera (0x3c) that sit behind a couple muxes. For example:

/sys/devices/platform/amba/ff030000.i2c/i2c-1/i2c-3/i2c-5/5-003c/
/sys/devices/platform/amba/ff030000.i2c/i2c-1/i2c-3/i2c-7/7-0063/

The LEDs are also available under /sys/class/leds/ based on their labels as defined in the devicetree.

The image data captured by the camera passes through two soft IP blocks. The driver for the second block maps the image into memory and exposes it as a block device in /dev.

In #kernel-newbies on OFC it was suggested that I could use udev to symlink the above into one place in /dev, but I'm having trouble creating a symlink between /sys and /dev (e.g. /sys/.../5-003c -> /dev/camera-name/camera). Perhaps that isn't possible or intended? I've only seen symlinks between /dev and /dev in /usr/lib/udev/rules.d/*.rules on my development system.

If it is I can explain what I've tried in more detail, but basically I'd like to do something like the following:

DRIVER=="aptina-ar0330", SYMLINK+="camera/$attr{../../of_node/name}/$env{OF_NAME}"

If it is not possible any other recommendations would be greatly appreciated.

Best,
Philip

^ permalink raw reply

* Re: driver core: Do uevents have a semantic problem ?
From: Greg KH @ 2019-12-06 16:18 UTC (permalink / raw)
  To: linux-hotplug
In-Reply-To: <20191202152850.23a0f621@ingpc3.intern.lauterbach.com>

On Mon, Dec 02, 2019 at 07:43:49PM +0100, Ingo Rohloff wrote:
> Hello,
> 
> I guess this is still me not understanding the Linux Device Model.
> 
> > > I guess udev needs both types of events:
> > > 
> > > 1) physical device was detected
> > > 2) device driver was bound  
> > 
> > 
> > It needs more than just that:
> > 	3) when a "struct device" is created within the kernel
> > 
> > Actually, udev doesn't need any of this as it doesn't do a ton of stuff
> > anymore now that devtmpfs is the primary handler for all device nodes.
> > not to say that udev doesn't still do a lot, but don't think of udev as
> > the thing that manages the creation of /dev nodes, as it hasn't done
> > that for a very long time now.
> 
> I didn't know the right terminology, after reading up on it,
> ("Linux Device Drivers, 3rd edition")
> here is hopefully a better try.
> 
> 
> I guess udev needs both types of events:
> 
> 1) "struct device" was allocated
> 2) "struct device_driver" was bound to "struct device"
>    (I think "matched" and then bound in kernel terminology ?)

This last event is "new" with the commit you referenced before.  For the
previous 15+ years, we did not have that event.

> Let me be concrete:
> As far as I can tell udev handles file permissions and group ownership
> for a lot of "/dev/*" nodes (and it creates appropriate symlinks).

Yes, for most.

> My question is:
> Should "udev" set file permissions and group ownership on
> 1) or 2) or both ?
> (It also seems 2) very often is not communicated via a uevent,
> so a "bind" event is not emitted.)

I think you are missing the connection between /dev/ nodes and other
parts of the kernel.  /dev/ nodes are not always associated with most
"struct device" structures in the kernel.  They are only a much smaller
number that actually are relevant.

Also note that a /dev/ node only shows up _after_ a driver binds to a
device, and when that happens, a "class device" is created that
represents how userspace can talk to a specific class of hardware.

So in your list above, 1) is when udev handles /dev/ node stuff, but
that's only a much more infrequent event overall (look at everything in
/sys/devices/ for proof of that.)

> My thinking was it should only do that on 2).

Nope.

> Rationale:
> My understanding is, that all the file operations for a /dev/* node
> are implemented in code which implements a "struct device_driver".
> Am I just wrong here and the file operations are actually done 
> per "struct device" and not per "struct device_driver" or per both ?

Only on a small number of "struct device"s that are created.

> So before I have bound a "struct device_driver" to a "struct device" 
> it doesn't even make sense to try to do anything with a /dev/* node; 
> or is this a mis-understanding ?

You can't even get to a /dev/ node then.

> I guess you might set file permission, group ownership and create a 
> symlink  once the /dev/* node exists 
> (I don't know if this happens at 1) or 2)).
> 
> But my assumption is you might only run actions 
> (like opening the /dev/* node and doing some ioctl) once a 
> "struct device_driver" is bound to "struct device".
> 
> Probably I simply don't get it:
> Maybe both "struct device" and "struct device_driver" might expose 
> /dev/* node entries, with accompanying "struct file_operations" ?

I would recommend stepping through the basic driver examples in the LDD3
book for an understanding of what is going on here.  THere's a lot more
steps happening :)

hope this helps,

greg k-h

^ permalink raw reply

* Re: driver core: Do uevents have a semantic problem ?
From: Ingo Rohloff @ 2019-12-02 18:43 UTC (permalink / raw)
  To: linux-hotplug
In-Reply-To: <20191202152850.23a0f621@ingpc3.intern.lauterbach.com>

Hello,

I guess this is still me not understanding the Linux Device Model.

> > I guess udev needs both types of events:
> > 
> > 1) physical device was detected
> > 2) device driver was bound  
> 
> 
> It needs more than just that:
> 	3) when a "struct device" is created within the kernel
> 
> Actually, udev doesn't need any of this as it doesn't do a ton of stuff
> anymore now that devtmpfs is the primary handler for all device nodes.
> not to say that udev doesn't still do a lot, but don't think of udev as
> the thing that manages the creation of /dev nodes, as it hasn't done
> that for a very long time now.

I didn't know the right terminology, after reading up on it,
("Linux Device Drivers, 3rd edition")
here is hopefully a better try.


I guess udev needs both types of events:

1) "struct device" was allocated
2) "struct device_driver" was bound to "struct device"
   (I think "matched" and then bound in kernel terminology ?)

Let me be concrete:
As far as I can tell udev handles file permissions and group ownership
for a lot of "/dev/*" nodes (and it creates appropriate symlinks).

My question is:
Should "udev" set file permissions and group ownership on
1) or 2) or both ?
(It also seems 2) very often is not communicated via a uevent,
so a "bind" event is not emitted.)

My thinking was it should only do that on 2).
Rationale:
My understanding is, that all the file operations for a /dev/* node
are implemented in code which implements a "struct device_driver".
Am I just wrong here and the file operations are actually done 
per "struct device" and not per "struct device_driver" or per both ?

So before I have bound a "struct device_driver" to a "struct device" 
it doesn't even make sense to try to do anything with a /dev/* node; 
or is this a mis-understanding ?

I guess you might set file permission, group ownership and create a 
symlink  once the /dev/* node exists 
(I don't know if this happens at 1) or 2)).

But my assumption is you might only run actions 
(like opening the /dev/* node and doing some ioctl) once a 
"struct device_driver" is bound to "struct device".

Probably I simply don't get it:
Maybe both "struct device" and "struct device_driver" might expose 
/dev/* node entries, with accompanying "struct file_operations" ?

with best regards
  Ingo

^ permalink raw reply

* Re: driver core: Do uevents have a semantic problem ?
From: Greg KH @ 2019-12-02 15:02 UTC (permalink / raw)
  To: linux-hotplug
In-Reply-To: <20191202152850.23a0f621@ingpc3.intern.lauterbach.com>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="windows-1252", Size: 7016 bytes --]

On Mon, Dec 02, 2019 at 03:28:57PM +0100, Ingo Rohloff wrote:
> Hello,
> 
> I recently had some problems with "bind"/"unbind" uevents, created
> when a user space program grabs an USB interface via
> 
>    ioctl(usb_fd, USBDEVFS_CLAIMINTERFACE, &usb_intf_nr);
> 
> TL;DR
> I wonder if there isn't a semantic issue what the
> "bind"/"unbind" and "add"/"remove" uevents mean.
> 
> 
> I mainly refer to commit 1455cf8dbfd0 ("driver core: emit
> uevents when device is bound to a driver")
> 
> I certainly do not know enough about the kernel; so at least I want
> to put my questions here, in the hope that somebody who has a better 
> understanding of the Linux kernel reads it.
> 
> Maybe this is just me misunderstanding how uevents work.
> 
> I read the log message of commit 1455cf8dbfd0 ("driver core: emit
> uevents when device is bound to a driver")
> 
> In particular this sentence:
>     These udev actions can not use ADD events, as those 
>     happen too early, so we are introducing BIND and UNBIND 
>     events that are emitted at the right moment.
> 
> So as far as I understand the issue is that ADD events happen too
> soon.
> 
> I am wondering if the core of the problem is the meaning of the
> word "device" under Unix in general. As far as I can tell, the
> word "device" under Unix is very often used synonymous with 
> "device driver".
> 
> Example: "Block and Character devices" it seems you are talking
> about the device drivers here, not about the physical devices.
> 
> For the rest I will try to be specific using the terms 
> "device driver" and "physical device" to differentiate.
> 
> I think for "add"/"remove" uevents it is not clear what exactly
> these events refer to (do they refer to the availability of a
> device driver or to the detection of a physical device).
> 
> 
> Example: I plug a USB pendrive into my PC and monitor the kernel
> uevents via "udevadm montior -k -p".
> 
> The first uevent I get is:
>    KERNEL[30080.233898] add      /devices/pci.../usb4/4-2 (usb)
>    ACTION­d
>    BUSNUM\04
>    DEVNAME=/dev/bus/usb/004/003
>    DEVNUM\03
>    DEVPATH=/devices/pci.../usb4/4-2
>    DEVTYPE=usb_device
>    MAJOR\x189
>    MINOR86
>    PRODUCTc/1000/1100
>    SEQNUMh96
>    SUBSYSTEM=usb
>    TYPE=0/0/0
> 
> I think this particular event refers to a physical device ?
> 
> I have not traced back the source of this event, but maybe
> it's some USB HUB, which detects that a new physical device was 
> plugged (or maybe not; I really have no clue).
> 
> Interestingly there already is a "MAJOR/MINOR" number and a path
> into /dev/...
> I am wondering: If at that moment (directly after the ADD uevent)
> I would try to open /dev/bus/usb/004/003 would that work ?
> The origin of the question: 
> Would there be a device driver to which user space might talk ?
> 
> Later I get this uevent:
>    KERNEL[30080.242045] bind     /devices/pci.../usb4/4-2 (usb)
>    ACTION=bind
>    BUSNUM\04
>    DEVNAME=/dev/bus/usb/004/003
>    DEVNUM\03
>    DEVPATH=/devices/pci.../usb4/4-2
>    DEVTYPE=usb_device
>    DRIVER=usb
>    MAJOR\x189
>    MINOR86
>    PRODUCTc/1000/1100
>    SEQNUMi01
>    SUBSYSTEM=usb
>    TYPE=0/0/0
> 
> I think this means if I would NOW open
> /dev/bus/usb/004/003 I would talk to the device driver "usb" ?
> 
> 
> The reason why I am wondering about semantics: Later I get
>    KERNEL[30081.480770] add   /devices/pci.../block/sda/sda1 (block)
>    ACTION­d
>    DEVNAME=/dev/sda1
>    DEVPATH=/devices/pci.../block/sda/sda1
>    DEVTYPE=partition
>    MAJOR=8
>    MINOR=1
>    PARTN=1
>    SEQNUMi11
>    SUBSYSTEM=block
> 
> Now this uevent seems to refer to a device driver and not to a
> physical device ?
> This uevent is not followed up by a "bind" event, so I guess this
> has already happened (so a device driver is already bound to the
> partition).
> 
> I guess udev needs both types of events:
> 
> 1) physical device was detected
> 2) device driver was bound


It needs more than just that:
	3) when a "struct device" is created within the kernel

Actually, udev doesn't need any of this as it doesn't do a ton of stuff
anymore now that devtmpfs is the primary handler for all device nodes.
not to say that udev doesn't still do a lot, but don't think of udev as
the thing that manages the creation of /dev nodes, as it hasn't done
that for a very long time now.

> I guess 1) is needed to load modules on demand (if possible),

Yes.

> loading a module will kick 2) I guess.

Yes.

> I guess 2) is needed to create device nodes under /dev/* and to run
> arbitrary actions (like mounting, loading firmware etc) once a
> device driver is bound to a physical device. I guess it does not
> make sense to create device nodes or run actions before a device
> driver is bound ?

It's physically impossible to create a /dev node before a driver binds
to a device.

> I read
>  http://www.linuxfromscratch.org/lfs/view/development/chapter07/udev.html
> but it seems that these two types of events are not distinguished ?

Yes, they are very different, look at all of the information in the
different uevent, they should not be the same at all.

> It seems to me that the origin of commit 1455cf8dbfd0 
> ("driver core: emit uevents when device is bound to a driver")
> is that there is no clear distinction between these two 
> types of event.

No, that commit was added because userspace did not know when a driver
was bound to a device and so it did not know when it was "ok" to look at
all of the attributes of the device (as doing the binding usually
creates a bunch of new attributes.)  Now that this new uevent happens,
userspace "knows" it is safe to scan the attributes, otherwise it never
really knew the device had a change of "state" from bound to unbound and
knew to look for new attributes, or attributes that might have gone
away.

> Sometimes you get an "ADD" uevent when a driver binds,

No, you get an ADD event when a new "struct device" is registered with
the driver core.

> sometimes you get an "ADD" uevent when a physical device is
> detected and later you get a "BIND" event when a driver is bound.

"struct device" does not always correlate with physical devices, there
are loads of "fake" devices in the system that you interact with all the
time (/dev/null is one fun example.)

> Further more it seems udev code and rules assume that "ADD" events in
> principle mean a device driver is now available ?

No, drivers are totally separate here.  They do not cause uevents to
happen, except by virtue of code in them that happens to allow a driver
to be bound to a device that is already created.

Did that help?

You might want to read the driver model chapter in the book, "Linux
Device Drivers, 3rd edition" for more details.  It's free online, and a
bit old but the basic concepts should be the same.

thanks,

greg k-h

^ permalink raw reply

* driver core: Do uevents have a semantic problem ?
From: Ingo Rohloff @ 2019-12-02 14:28 UTC (permalink / raw)
  To: linux-hotplug

Hello,

I recently had some problems with "bind"/"unbind" uevents, created
when a user space program grabs an USB interface via

   ioctl(usb_fd, USBDEVFS_CLAIMINTERFACE, &usb_intf_nr);

TL;DR
I wonder if there isn't a semantic issue what the
"bind"/"unbind" and "add"/"remove" uevents mean.


I mainly refer to commit 1455cf8dbfd0 ("driver core: emit
uevents when device is bound to a driver")

I certainly do not know enough about the kernel; so at least I want
to put my questions here, in the hope that somebody who has a better 
understanding of the Linux kernel reads it.

Maybe this is just me misunderstanding how uevents work.

I read the log message of commit 1455cf8dbfd0 ("driver core: emit
uevents when device is bound to a driver")

In particular this sentence:
    These udev actions can not use ADD events, as those 
    happen too early, so we are introducing BIND and UNBIND 
    events that are emitted at the right moment.

So as far as I understand the issue is that ADD events happen too
soon.

I am wondering if the core of the problem is the meaning of the
word "device" under Unix in general. As far as I can tell, the
word "device" under Unix is very often used synonymous with 
"device driver".

Example: "Block and Character devices" it seems you are talking
about the device drivers here, not about the physical devices.

For the rest I will try to be specific using the terms 
"device driver" and "physical device" to differentiate.

I think for "add"/"remove" uevents it is not clear what exactly
these events refer to (do they refer to the availability of a
device driver or to the detection of a physical device).


Example: I plug a USB pendrive into my PC and monitor the kernel
uevents via "udevadm montior -k -p".

The first uevent I get is:
   KERNEL[30080.233898] add      /devices/pci.../usb4/4-2 (usb)
   ACTION≠d
   BUSNUM\04
   DEVNAME=/dev/bus/usb/004/003
   DEVNUM\03
   DEVPATH=/devices/pci.../usb4/4-2
   DEVTYPE=usb_device
   MAJOR\x189
   MINOR86
   PRODUCTêc/1000/1100
   SEQNUMh96
   SUBSYSTEM=usb
   TYPE=0/0/0

I think this particular event refers to a physical device ?

I have not traced back the source of this event, but maybe
it's some USB HUB, which detects that a new physical device was 
plugged (or maybe not; I really have no clue).

Interestingly there already is a "MAJOR/MINOR" number and a path
into /dev/...
I am wondering: If at that moment (directly after the ADD uevent)
I would try to open /dev/bus/usb/004/003 would that work ?
The origin of the question: 
Would there be a device driver to which user space might talk ?

Later I get this uevent:
   KERNEL[30080.242045] bind     /devices/pci.../usb4/4-2 (usb)
   ACTION=bind
   BUSNUM\04
   DEVNAME=/dev/bus/usb/004/003
   DEVNUM\03
   DEVPATH=/devices/pci.../usb4/4-2
   DEVTYPE=usb_device
   DRIVER=usb
   MAJOR\x189
   MINOR86
   PRODUCTêc/1000/1100
   SEQNUMi01
   SUBSYSTEM=usb
   TYPE=0/0/0

I think this means if I would NOW open
/dev/bus/usb/004/003 I would talk to the device driver "usb" ?


The reason why I am wondering about semantics: Later I get
   KERNEL[30081.480770] add   /devices/pci.../block/sda/sda1 (block)
   ACTION≠d
   DEVNAME=/dev/sda1
   DEVPATH=/devices/pci.../block/sda/sda1
   DEVTYPE=partition
   MAJOR=8
   MINOR=1
   PARTN=1
   SEQNUMi11
   SUBSYSTEM=block

Now this uevent seems to refer to a device driver and not to a
physical device ?
This uevent is not followed up by a "bind" event, so I guess this
has already happened (so a device driver is already bound to the
partition).

I guess udev needs both types of events:

1) physical device was detected
2) device driver was bound

I guess 1) is needed to load modules on demand (if possible),
loading a module will kick 2) I guess.

I guess 2) is needed to create device nodes under /dev/* and to run
arbitrary actions (like mounting, loading firmware etc) once a
device driver is bound to a physical device. I guess it does not
make sense to create device nodes or run actions before a device
driver is bound ?

I read
 http://www.linuxfromscratch.org/lfs/view/development/chapter07/udev.html
but it seems that these two types of events are not distinguished ?

It seems to me that the origin of commit 1455cf8dbfd0 
("driver core: emit uevents when device is bound to a driver")
is that there is no clear distinction between these two 
types of event.
Sometimes you get an "ADD" uevent when a driver binds,
sometimes you get an "ADD" uevent when a physical device is
detected and later you get a "BIND" event when a driver is bound.

Further more it seems udev code and rules assume that "ADD" events in
principle mean a device driver is now available ?
Even if this is not really the case ?

so long
  Ingo

^ permalink raw reply

* Re: [PATCH v2] usb: usbfs: Suppress problematic bind and unbind uevents.
From: Greg KH @ 2019-10-15 18:23 UTC (permalink / raw)
  To: Ingo Rohloff; +Cc: linux-usb, linux-hotplug
In-Reply-To: <20191011115518.2801-1-ingo.rohloff@lauterbach.com>

On Fri, Oct 11, 2019 at 01:55:18PM +0200, Ingo Rohloff wrote:
> commit 1455cf8dbfd0 ("driver core: emit uevents when device is bound
> to a driver") added bind and unbind uevents when a driver is bound or
> unbound to a physical device.
> 
> For USB devices which are handled via the generic usbfs layer (via
> libusb for example), this is problematic:
> Each time a user space program calls
>    ioctl(usb_fd, USBDEVFS_CLAIMINTERFACE, &usb_intf_nr);
> and then later
>    ioctl(usb_fd, USBDEVFS_RELEASEINTERFACE, &usb_intf_nr);
> The kernel will now produce a bind or unbind event, which does not
> really contain any useful information.
> 
> This allows a user space program to run a DoS attack against programs
> which listen to uevents (in particular systemd/eudev/upowerd):
> A malicious user space program just has to call in a tight loop
> 
>    ioctl(usb_fd, USBDEVFS_CLAIMINTERFACE, &usb_intf_nr);
>    ioctl(usb_fd, USBDEVFS_RELEASEINTERFACE, &usb_intf_nr);
> 
> With this loop the malicious user space program floods the kernel and
> all programs listening to uevents with tons of bind and unbind
> events.
> 
> This patch suppresses uevents for ioctls USBDEVFS_CLAIMINTERFACE and
> USBDEVFS_RELEASEINTERFACE.
> 
> Signed-off-by: Ingo Rohloff <ingo.rohloff@lauterbach.com>
> ---
> 
> Notes:
>     v2:
>     Patch only single file (devio.c), try to only suppress uevents while
>     usb_driver_claim_interface/usb_driver_release_interface are called.
>     Try to restore old state of dev->kobj.uevent_suppress.

Thanks for cleaning this up.  It looks much nicer now.  I've queued it
up in my tree, let's see how testing goes :)

thanks,

greg k-h

^ permalink raw reply

* [PATCH v2] usb: usbfs: Suppress problematic bind and unbind uevents.
From: Ingo Rohloff @ 2019-10-11 11:55 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, linux-hotplug, Ingo Rohloff

commit 1455cf8dbfd0 ("driver core: emit uevents when device is bound
to a driver") added bind and unbind uevents when a driver is bound or
unbound to a physical device.

For USB devices which are handled via the generic usbfs layer (via
libusb for example), this is problematic:
Each time a user space program calls
   ioctl(usb_fd, USBDEVFS_CLAIMINTERFACE, &usb_intf_nr);
and then later
   ioctl(usb_fd, USBDEVFS_RELEASEINTERFACE, &usb_intf_nr);
The kernel will now produce a bind or unbind event, which does not
really contain any useful information.

This allows a user space program to run a DoS attack against programs
which listen to uevents (in particular systemd/eudev/upowerd):
A malicious user space program just has to call in a tight loop

   ioctl(usb_fd, USBDEVFS_CLAIMINTERFACE, &usb_intf_nr);
   ioctl(usb_fd, USBDEVFS_RELEASEINTERFACE, &usb_intf_nr);

With this loop the malicious user space program floods the kernel and
all programs listening to uevents with tons of bind and unbind
events.

This patch suppresses uevents for ioctls USBDEVFS_CLAIMINTERFACE and
USBDEVFS_RELEASEINTERFACE.

Signed-off-by: Ingo Rohloff <ingo.rohloff@lauterbach.com>
---

Notes:
    v2:
    Patch only single file (devio.c), try to only suppress uevents while
    usb_driver_claim_interface/usb_driver_release_interface are called.
    Try to restore old state of dev->kobj.uevent_suppress.

 drivers/usb/core/devio.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 3f899552f6e3..6ca40d135430 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -764,8 +764,15 @@ static int claimintf(struct usb_dev_state *ps, unsigned int ifnum)
 	intf = usb_ifnum_to_if(dev, ifnum);
 	if (!intf)
 		err = -ENOENT;
-	else
+	else {
+		unsigned int old_suppress;
+
+		/* suppress uevents while claiming interface */
+		old_suppress = dev_get_uevent_suppress(&intf->dev);
+		dev_set_uevent_suppress(&intf->dev, 1);
 		err = usb_driver_claim_interface(&usbfs_driver, intf, ps);
+		dev_set_uevent_suppress(&intf->dev, old_suppress);
+	}
 	if (err = 0)
 		set_bit(ifnum, &ps->ifclaimed);
 	return err;
@@ -785,7 +792,13 @@ static int releaseintf(struct usb_dev_state *ps, unsigned int ifnum)
 	if (!intf)
 		err = -ENOENT;
 	else if (test_and_clear_bit(ifnum, &ps->ifclaimed)) {
+		unsigned int old_suppress;
+
+		/* suppress uevents while releasing interface */
+		old_suppress = dev_get_uevent_suppress(&intf->dev);
+		dev_set_uevent_suppress(&intf->dev, 1);
 		usb_driver_release_interface(&usbfs_driver, intf);
+		dev_set_uevent_suppress(&intf->dev, old_suppress);
 		err = 0;
 	}
 	return err;
-- 
2.17.1

^ permalink raw reply related

* Re: [PATCH] usb: usbfs: Suppress problematic bind and unbind uevents.
From: Greg KH @ 2019-10-11  4:41 UTC (permalink / raw)
  To: Ingo Rohloff; +Cc: linux-usb, linux-hotplug
In-Reply-To: <20191010164800.2444-1-ingo.rohloff@lauterbach.com>

On Thu, Oct 10, 2019 at 06:48:00PM +0200, Ingo Rohloff wrote:
> commit 1455cf8dbfd0 ("driver core: emit uevents when device is bound
> to a driver") added bind and unbind uevents when a driver is bound or
> unbound to a physical device.
> 
> For USB devices which are handled via the generic usbfs layer (via
> libusb for example), this is problematic:
> Each time a user space program calls
>    ioctl(usb_fd, USBDEVFS_CLAIMINTERFACE, &usb_intf_nr);
> and then later
>    ioctl(usb_fd, USBDEVFS_RELEASEINTERFACE, &usb_intf_nr);
> The kernel will now produce a bind or unbind event, which does not
> really contain any useful information.
> 
> This allows a user space program to run a DoS attack against programs
> which listen to uevents (in particular systemd/eudev/upowerd):
> A malicious user space program just has to call in a tight loop
> 
>    ioctl(usb_fd, USBDEVFS_CLAIMINTERFACE, &usb_intf_nr);
>    ioctl(usb_fd, USBDEVFS_RELEASEINTERFACE, &usb_intf_nr);
> 
> With this loop the malicious user space program floods the kernel and
> all programs listening to uevents with tons of bind and unbind
> events.
> 
> This patch suppresses uevents for ioctls USBDEVFS_CLAIMINTERFACE and
> USBDEVFS_RELEASEINTERFACE.
> 
> Signed-off-by: Ingo Rohloff <ingo.rohloff@lauterbach.com>
> ---
>  drivers/usb/core/devio.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)

I am guessing this is a new version of a previously-submitted patch?  If
so, you need to include a "version" number on it, and put what you
changed below the --- line.  The kernel documentation should explain how
to do this, if not, please let us know.

Please fix this up and resend.

thanks,

greg k-h

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox