Odi's astoundingly incomplete notes
New entriesCode
back | nextfix Stack Clash on Gentoo
The Stack Clash class of bugs can be easily prevented on Gentoo.
1. Add -fstack-check to your CFLAGS. It instructs the compiler to touch every page when extending the stack by more than one page. So the kernel will trap in the guard page. This even makes the larger stack gap in recent kernels unnecessary (if you don't run other binaries)
3. Recompile important libraries (like openssl) and programs (setuid root binaries in shadow and util-linux) or simply everything: emerge -ae world
As always, keep your system uptodate regularly: emerge -uavD world
1. Add -fstack-check to your CFLAGS. It instructs the compiler to touch every page when extending the stack by more than one page. So the kernel will trap in the guard page. This even makes the larger stack gap in recent kernels unnecessary (if you don't run other binaries)
/etc/portage/make.conf: CFLAGS="-march=native -O2 -pipe -fstack-check"2. Some packages don't like this flag. Especially sys-libs/glibc itself. So for those define a separate environment:
/etc/portage/env/simple: CFLAGS="-march=native -O2 -pipe" CXXFLAGS="${CFLAGS}"
/etc/portage/package.env: sys-libs/glibc simple
3. Recompile important libraries (like openssl) and programs (setuid root binaries in shadow and util-linux) or simply everything: emerge -ae world
As always, keep your system uptodate regularly: emerge -uavD world
Add comment
Oracle and HugePages
I have an Oracle 12 instance with 32GB SGA on a modern Gentoo Linux system with 48GB of RAM. The kernel has transparent hugepages set to always but no HugePages configured.
From
After reserving 32 GB of real 2 MB HugePages (vm.nr_hugepages = 16384) the situation has become:
From
/proc/meminfo
:
PageTables: 2577752 kB
AnonHugePages: 75776 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
You can clearly see that page tables take up 2.5 GB of RAM. This makes TLB flushes really bad of course. You can also see that Oracle doesn't make much use of transparent huge pages. Only 75 MB are used.After reserving 32 GB of real 2 MB HugePages (vm.nr_hugepages = 16384) the situation has become:
PageTables: 118456 kB
AnonHugePages: 0 kB
HugePages_Total: 16384
HugePages_Free: 63
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
So Oracle has put the SGA completely into HugePages which greatly reduces the space required for page tables and thus memory management becomes a lot more efficient.iptables conntrack helper assignment
Long story short for a client:
[0:0] -A OUTPUT -p tcp --dport 21 -j CT --helper ftp [0:0] -A OUTPUT -p udp --dport 137:138 -j CT --helper netbios-nsThis will make work:
- active (non-passive) FTP
- browsing Windows network (SMB shares and domains)
Convert a Linux installation to Gentoo
From WS-* to REST/JSON
To set the frame, please note that during the last 10 years I have done a great many Webservices. In Java. Client and server side. Synchronous and asynchronous. Directly connected and decoupled via ESBs like TIBCO and queuing infrastructure like IBM MQ. And if I say a lot then I mean that a quick find in the git tree reveals about 1400 WSDL files. I have worked on most of them. Most of them use CXF. Some ancient ones use Axis.
Lately WS seems to be a dying technology. New interfaces between systems are now usually requested to use REST and JSON. This comes with much joy but unfortunately also much frustration.
This may seem like a joke. If plain text has one special power, then that you can insert comments. Except when the format doesn't allow it. Like JSON. This was a really brain-dead decision.
There is no standard for specifying an interface.
Well there are several competing technologies: Swagger, RAML, WADL to name a few. And then you can often chose to write them in YAML or JSON. If we wanted to support all those technologies, we would have use and maintain a zoo of tools. It would have really helped REST if it had standardized a single very good interface description language. For WS-* there is WSDL. And everybody was using it. And even though there was an option to use Relax-Ng as the modelling language, everybody just used XML Schema. Consequently the number of available tools is endless. You always find good tools that are a joy to use. Not so in the REST world. It's a chaos and a desert at the same time.
Some developers even think it is sufficient to provide some examples of requests and responses in a PDF. Of course simple typos lead to much cursing later and make testing a lengthy and painful experience.
Of course interface documentation is often also done by annotating an example message with comments. But wait... JSON doesn't have a syntax for comments, rendering such examples into invalid JSON. This is unnecessarily ugly.
Multiple competing conventions
Apparently people have noticed that REST is not enough of a spec to be actually useful. So multiple conventions have popped up that tell you how to build REST services: HAL, OData to name a few. Naturally each one claims to be the best one. Again if you need to integrate many different REST services you will have to support a zoo of 'standards'.
REST/JSON is unfriendly to strongly typed languages (like Java).
WS-* with XML Schema was equally horrible for dynamically typed languages (like JS). But there was no need to repeat that same mistake. Parsing is already harder than necessary. A JSON object has no name! It starts with a brace followed by a list of name/value pairs. So in a stream I have no idea what type of object I am going to look at and which properties I should expect. I have to know from some other source what I am going to parse.
Nothing prevents a system from throwing an array containing various types of objects at you. Without knowing exactly what type of object to expect at which array index there is simply no way of mapping that into an object model. You have to resort to a generic representation with maps which will cause you more pain later.
The number of defined datatypes in JSON is low, which I consider a good thing. But it lacks two things. There is no fixed-point decimal type. JSON's numbers are by default interpreted as double floating point numbers, which is inadequate for things like quantities or prices. Also it doesn't define any type for date and time. Most of the time though people use string and interprete it using the XML schema date format (ISO 8601). Given the difficulties involved with dates and timezones there is a need to have a good data type for date and time.
REST is not friendly to HTTP
REST is always advertised as being a natural fit for HTTP and how it embraces it's concepts. And then you find an HTTP method called PATCH that had to be standardized. Guess how many libraries still don't support PATCH 10 years later.
Have you come across a REST API that had a GET call that includes a REST object in its HTTP entity (body)? Guess how many middleboxes don't support that at all.
REST/JSON is not not good for RPC
A remote procedure call is a call that has an ordered fixed number of arguments whose types are constant and a single return value of constant type, with the assumption that arguments and return value are serializable. This definition matches function call definitions in all but exotic languages. That made it a hugely successful concept. WS-* extended it a little with Faults (exceptions) to ease integration with modern languages like C# or Java. Somehow the REST world decided that it should go a different route. Arguments in REST can be scattered throughout various places: HTTP methods (GET, POST, ...), HTTP headers (including Cookies), URI components, URL parameters and the HTTP entity (body message). Return values / objects usually depend on the HTTP status code. This could in theory be mapped to the simple RPC model, but I have yet to see any good infrastructure that does that well. JAX-RS is not nice here: all return values are simply a generic object, from which you extract the HTTP status code and then ask the object to interprete the return value as a specific type. Non-200 responses should have been mapped to exceptions in my opinion and the 200-response should have been chosen as the return type. But now we have this messy "generic" RPC style which is totally not type safe, which means that avoidable mistakes only show up at runtime instead at compile time.
Swagger doesn't even force the developer to define (named) types at all. You could simply list arguments and return types inline even if they are large complex objects. Code generators for typed languages have no other possibility than generate silly classnames (or let the poor developer specify them via configuration) in that case. Producing a horrible maze of classes that are hard to use. It's not what you want when the logic is already complex. Good names help.
REST/JSON is not good for messaging
By messaging I mean a classic ESB or message queue. So put the arguments to the RPC call into a file, possibly modify it, and send that file asynchronously over some transport queueing mechanism to the destination endpoint. For that to work you need the file to contain everything you need to know to execute the RPC call (except anything which is configuration like the actual endpoint URL of the destination). With WS-* that was part of idea behind it. It made very sure that the message contains the operation name (style: document literal wrapped) for example. Metadata (headers) is also part of the message.
All sorts of ESB middle ware cropped up. But also locally for an application it is essential to be able to queue messages to a remote system and send them one-by-one in a defined order or highly parallelize them, when the remote system is available and ready.
REST makes it harder. Because the REST/JSON message may not contain all information: again JSON objects have no name, more than one HTTP method could apply to the same arguments, some of the arguments could be part of the HTTP headers, URI or need to be passed in the URL parameter and may not be available from the message. If that is the case you need to wrap the message into an additional object that contains the missing information. As a design rule for ESB capable JSON objects, all information should be contained in the JSON object even if it is later partly duplicated elsewhere in the HTTP request.
Lately WS seems to be a dying technology. New interfaces between systems are now usually requested to use REST and JSON. This comes with much joy but unfortunately also much frustration.
Joys first
- Less traffic. Yey! JSON is much more compact than XML. It can make a huge difference.
- No more XML namespaces. It was the hardest thing for developers to understand and get right.
- No more XML at all. All these people assembling or parsing XML with string operations and all the associated headaches like missing escaping or broken namespace handling.
- No more XML parsers which are a trivial target for all sorts of attacks
- No more worrying about SOAP binding styles (document literal, RPC).
- No more worrying about SOAP versions or myriards of WS-* extensions.
Now for the frustrations
JSON does not support commentsThis may seem like a joke. If plain text has one special power, then that you can insert comments. Except when the format doesn't allow it. Like JSON. This was a really brain-dead decision.
There is no standard for specifying an interface.
Well there are several competing technologies: Swagger, RAML, WADL to name a few. And then you can often chose to write them in YAML or JSON. If we wanted to support all those technologies, we would have use and maintain a zoo of tools. It would have really helped REST if it had standardized a single very good interface description language. For WS-* there is WSDL. And everybody was using it. And even though there was an option to use Relax-Ng as the modelling language, everybody just used XML Schema. Consequently the number of available tools is endless. You always find good tools that are a joy to use. Not so in the REST world. It's a chaos and a desert at the same time.
Some developers even think it is sufficient to provide some examples of requests and responses in a PDF. Of course simple typos lead to much cursing later and make testing a lengthy and painful experience.
Of course interface documentation is often also done by annotating an example message with comments. But wait... JSON doesn't have a syntax for comments, rendering such examples into invalid JSON. This is unnecessarily ugly.
Multiple competing conventions
Apparently people have noticed that REST is not enough of a spec to be actually useful. So multiple conventions have popped up that tell you how to build REST services: HAL, OData to name a few. Naturally each one claims to be the best one. Again if you need to integrate many different REST services you will have to support a zoo of 'standards'.
REST/JSON is unfriendly to strongly typed languages (like Java).
WS-* with XML Schema was equally horrible for dynamically typed languages (like JS). But there was no need to repeat that same mistake. Parsing is already harder than necessary. A JSON object has no name! It starts with a brace followed by a list of name/value pairs. So in a stream I have no idea what type of object I am going to look at and which properties I should expect. I have to know from some other source what I am going to parse.
Nothing prevents a system from throwing an array containing various types of objects at you. Without knowing exactly what type of object to expect at which array index there is simply no way of mapping that into an object model. You have to resort to a generic representation with maps which will cause you more pain later.
The number of defined datatypes in JSON is low, which I consider a good thing. But it lacks two things. There is no fixed-point decimal type. JSON's numbers are by default interpreted as double floating point numbers, which is inadequate for things like quantities or prices. Also it doesn't define any type for date and time. Most of the time though people use string and interprete it using the XML schema date format (ISO 8601). Given the difficulties involved with dates and timezones there is a need to have a good data type for date and time.
REST is not friendly to HTTP
REST is always advertised as being a natural fit for HTTP and how it embraces it's concepts. And then you find an HTTP method called PATCH that had to be standardized. Guess how many libraries still don't support PATCH 10 years later.
Have you come across a REST API that had a GET call that includes a REST object in its HTTP entity (body)? Guess how many middleboxes don't support that at all.
REST/JSON is not not good for RPC
A remote procedure call is a call that has an ordered fixed number of arguments whose types are constant and a single return value of constant type, with the assumption that arguments and return value are serializable. This definition matches function call definitions in all but exotic languages. That made it a hugely successful concept. WS-* extended it a little with Faults (exceptions) to ease integration with modern languages like C# or Java. Somehow the REST world decided that it should go a different route. Arguments in REST can be scattered throughout various places: HTTP methods (GET, POST, ...), HTTP headers (including Cookies), URI components, URL parameters and the HTTP entity (body message). Return values / objects usually depend on the HTTP status code. This could in theory be mapped to the simple RPC model, but I have yet to see any good infrastructure that does that well. JAX-RS is not nice here: all return values are simply a generic object, from which you extract the HTTP status code and then ask the object to interprete the return value as a specific type. Non-200 responses should have been mapped to exceptions in my opinion and the 200-response should have been chosen as the return type. But now we have this messy "generic" RPC style which is totally not type safe, which means that avoidable mistakes only show up at runtime instead at compile time.
Swagger doesn't even force the developer to define (named) types at all. You could simply list arguments and return types inline even if they are large complex objects. Code generators for typed languages have no other possibility than generate silly classnames (or let the poor developer specify them via configuration) in that case. Producing a horrible maze of classes that are hard to use. It's not what you want when the logic is already complex. Good names help.
REST/JSON is not good for messaging
By messaging I mean a classic ESB or message queue. So put the arguments to the RPC call into a file, possibly modify it, and send that file asynchronously over some transport queueing mechanism to the destination endpoint. For that to work you need the file to contain everything you need to know to execute the RPC call (except anything which is configuration like the actual endpoint URL of the destination). With WS-* that was part of idea behind it. It made very sure that the message contains the operation name (style: document literal wrapped) for example. Metadata (headers) is also part of the message.
All sorts of ESB middle ware cropped up. But also locally for an application it is essential to be able to queue messages to a remote system and send them one-by-one in a defined order or highly parallelize them, when the remote system is available and ready.
REST makes it harder. Because the REST/JSON message may not contain all information: again JSON objects have no name, more than one HTTP method could apply to the same arguments, some of the arguments could be part of the HTTP headers, URI or need to be passed in the URL parameter and may not be available from the message. If that is the case you need to wrap the message into an additional object that contains the missing information. As a design rule for ESB capable JSON objects, all information should be contained in the JSON object even if it is later partly duplicated elsewhere in the HTTP request.
What the TLS private key is for really
People think that the private key of the server certificate protects the content of TLS messages. And so if someone obtains the private key they can decrypt a TLS connection. Well, not quite.
These days the private key is primarily used for authentication. So the server can prove that it is what its certificate claims it is. If a server presents a certificate for odi.ch then it needs the matching private key to prove that claim to clients. So losing the server key always enables identity theft and thus man-in-the-middle attacks.
The content of a TLS connection is encrypted using a session key (using a symmetrical algorithm like AES).
If that session key is exchanged using an insecure key exchange protocol then it is true: we can recover it. The original key exchange protocols did that. The client creates a pre-master secret and encrypts it with the server's public key, so it can be obtained with the server's private key. That pre-master secret is the basis for the session key.
If the session key is exchanged using a secure key agreement protocol (Diffie-Hellman) then we can not recover it. A secure key agreement protocol is able to produce a shared secret in plain sight without any encryption of the agreement protocol itself. It does not in any way depend on private key of either party.
These days the private key is primarily used for authentication. So the server can prove that it is what its certificate claims it is. If a server presents a certificate for odi.ch then it needs the matching private key to prove that claim to clients. So losing the server key always enables identity theft and thus man-in-the-middle attacks.
The content of a TLS connection is encrypted using a session key (using a symmetrical algorithm like AES).
If that session key is exchanged using an insecure key exchange protocol then it is true: we can recover it. The original key exchange protocols did that. The client creates a pre-master secret and encrypts it with the server's public key, so it can be obtained with the server's private key. That pre-master secret is the basis for the session key.
If the session key is exchanged using a secure key agreement protocol (Diffie-Hellman) then we can not recover it. A secure key agreement protocol is able to produce a shared secret in plain sight without any encryption of the agreement protocol itself. It does not in any way depend on private key of either party.
Making ntp-client (ntpdate) work in Gentoo
tl;dr:
Tell dhcpcd to background only after we haven an IPv4 address, which is like the whole point of DHCP these days. I don't consider the network "up" with IPv6 only.
It's particularly a problem when you get IPv6 router advertisements. Like in qemu VMs with user networking.
Look at the following log, where you see it backgrounding 3 seconds before the lease:
/etc/dhcpcd.conf
:
waitip 4dhcpcd will background already after configuring an IPv6 address on the interface. Which may be seconds before you get an IPv4 lease and DNS information from the DHCP server. The ntp-client init script may therefore run before we have a valid
/etc/resolv.conf
and will fail due to name resolution not working.Tell dhcpcd to background only after we haven an IPv4 address, which is like the whole point of DHCP these days. I don't consider the network "up" with IPv6 only.
It's particularly a problem when you get IPv6 router advertisements. Like in qemu VMs with user networking.
Look at the following log, where you see it backgrounding 3 seconds before the lease:
Oct 4 14:35:25 localhost dhcpcd[3356]: eth0: adding address fe80::59c1:f175:aeb3:433 Oct 4 14:35:25 localhost dhcpcd[3356]: DUID 00:01:00:01:1a:7a:85:31:52:54:00:12:34:56 Oct 4 14:35:25 localhost dhcpcd[3356]: eth0: IAID 00:12:34:56 Oct 4 14:35:25 localhost dhcpcd[3356]: eth0: rebinding lease of 10.0.2.15 Oct 4 14:35:25 localhost dhcpcd[3356]: eth0: probing address 10.0.2.15/24 Oct 4 14:35:26 localhost dhcpcd[3356]: eth0: soliciting an IPv6 router Oct 4 14:35:26 localhost dhcpcd[3356]: eth0: Router Advertisement from fe80::2 Oct 4 14:35:26 localhost dhcpcd[3356]: eth0: adding address fec0::4f23:8633:1bba:42f5/64 Oct 4 14:35:26 localhost dhcpcd[3356]: eth0: adding route to fec0::/64 Oct 4 14:35:26 localhost dhcpcd[3356]: eth0: adding default route via fe80::2 Oct 4 14:35:28 localhost dhcpcd[3356]: forked to background, child pid 3384 Oct 4 14:35:31 localhost dhcpcd[3384]: eth0: leased 10.0.2.15 for 86400 seconds Oct 4 14:35:31 localhost dhcpcd[3384]: eth0: adding route to 10.0.2.0/24 Oct 4 14:35:31 localhost dhcpcd[3384]: eth0: adding default route via 10.0.2.2
another broken sudo
$ sudo -l [sudo] password for xxx: Matching Defaults entries for xxx on this host: requiretty, !visiblepw, always_set_home, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin, logfile=/var/log/sudolog User xxx may run the following commands on this host: (ALL) ALL, (ALL) /usr/bin/passwd [a-zA-Z0-9_-]*, !/usr/bin/passwd root, (ALL) !/sbin/su*, !/bin/su, !/bin/bash root, !/bin/sh root, (ALL) !/usr/sbin/visudo, (ALL) !sudoedit /etc/sudoers, (ALL) !/usr/bin/* /etc/sudoers, !/bin/* /etc/sudoers, /opt/* /etc/sudoers, (ALL) !/usr/bin/* /etc/shadow, !/bin/* /etc/shadow, !/opt/* /etc/shadow $ sudo bash # whoami rootLook how they wanted to restrict executing bash. And look how they wanted to restrict access to sudoers. All that AFTER giving me ALL(ALL). Again, sudo is a complete failure.
It's always a really stupid idea to first hand out permission to everything and then trying to backpedal and go all like: uh oh... but not that... and this... and not that either... and... ah clever me... You are not going to find all possibilities. Ever.
Oracle hangs on login of one user
I just troubleshooted the strangest Oracle issue. Logon with a certain user simply hangs and eventually returns with
DBA and Oracle consultants were unable to find the problem.
Until I noticed that the password in my datasource was simply wrong. The application tried to open many connections at the same time (to populate its pool). Probably it's a deadlock in Oracle's Auditing for failed logons.
ORA-03135
. In v$session
you can see many sessions waiting on library cache lock
. Their current sql statement is a select from sysauth$
.DBA and Oracle consultants were unable to find the problem.
Until I noticed that the password in my datasource was simply wrong. The application tried to open many connections at the same time (to populate its pool). Probably it's a deadlock in Oracle's Auditing for failed logons.
findutils atime, mtime, ctime have "interesting" semantics
How not to design a user interface:
-atime n
File was last accessed n*24 hours ago. When find figures out how many 24-hour periods ago the file was last accessed, any fractional part is ignored, so to match -atime +1, a file has to have been accessed at least two days ago.
Even tough you say -atime +1, it actually behaves like "atime + 2 days >= now". It's not intuitive. It encourages people of shooting themselves in the foot.
back
|
next
-atime n
File was last accessed n*24 hours ago. When find figures out how many 24-hour periods ago the file was last accessed, any fractional part is ignored, so to match -atime +1, a file has to have been accessed at least two days ago.
Even tough you say -atime +1, it actually behaves like "atime + 2 days >= now". It's not intuitive. It encourages people of shooting themselves in the foot.